Android C/C++層hook和java層hook原理以及比較

来源:https://www.cnblogs.com/cloudwise/archive/2022/04/18/16160352.html
-Advertisement-
Play Games

作者:Denny Qiao(喬喜銘),雲智慧/架構師。 雲智慧集團成立於2009年,是全棧智能業務運維解決方案服務商。經過多年自主研發,公司形成了從IT運維、電力運維到IoT運維的產業佈局,覆蓋ITOM、ITOA、ITSM、DevOps以及IoT幾大領域,為金融、政府、運營商、能源、交通、製造等上百 ...


作者:Denny Qiao(喬喜銘),雲智慧/架構師。

雲智慧集團成立於2009年,是全棧智能業務運維解決方案服務商。經過多年自主研發,公司形成了從IT運維、電力運維到IoT運維的產業佈局,覆蓋ITOM、ITOA、ITSM、DevOps以及IoT幾大領域,為金融、政府、運營商、能源、交通、製造等上百家行業的客戶,提供了數字化運維體系建設及全生命周期運維管理解決方案。雲智慧秉承Make Digital Online的使命,致力於通過先進的產品技術,為企業數字化轉型和提升IT運營效率持續賦能。

android java層hook機制

android dalvic虛擬機和JVM的區別

  1. Dalvik虛擬機並不是按照Java虛擬機的規範來實現的,與jvm並不相容
  2. Java虛擬機運行的是Java位元組碼,而Dalvik虛擬機運行的則是其專有的文件格式DEX(Dalvik Executable)
  3. Davic讀取的是dex文件,jvm讀取的.class和jar文件
  4. Dalvik基於寄存器,而JVM基於棧
  5. 每一個Android應用都運行在一個Dalvik虛擬機實例里,而每一個虛擬機實例都是一個獨立的進程空間。虛擬機的線程機制,記憶體分配和管理,Mutex等等都是依賴底層操作系統而實現的。所有Android應用的線程都對應一個Linux線程,虛擬機因而可以更多的依賴操作系統的線程調度和管理機制
  6. 有一個特殊的虛擬機進程Zygote,他是虛擬機實例的孵化器。每當系統要求執行一個Android應用程式,Zygote就會FORK出一個子進程來執行該應用程式。它在系統啟動的時候就會產生,它會完成虛擬機的初始化、庫的載入、預置類庫和初始化的操作。如果系統需要一個新的虛擬機實例,它會迅速複製自身,以最快的速度提供給系統

android的啟動流程

android的編譯結構圖

android hook 原理

Javac流程

Java 類文件是8位位元組的二進位流

Android dalvik虛擬機相比 jvm 有一個dex模塊

目的是: 優化class,減小體積,加快載入運行速度,我們hook的關鍵就是修改class文件,在原有class文件中增加,修改方法或者變數,以便加入我們的hook代碼到class中,自動埋點。在android中hook的入口點是dex模塊。

修改class的關鍵技術: asm框架

  • ASM 是一個 Java 位元組碼操控框架。它能被用來動態生成類或者增強既有類的功能。
  • ASM 可以直接產生二進位 class 文件,也可以在類被載入入 Java 虛擬機之前動態改變類行為。
  • Java class 被存儲在嚴格格式定義的.class 文件里,這些類文件擁有足夠的元數據來解析類中的所有元素:類名稱、方法、屬性以及 Java 位元組碼(指令)。
  • ASM 從類文件中讀入信息後,能夠改變類行為,分析類信息,甚至能夠根據用戶要求生成新類。

Android hook的實現方案

  1. 直接修改android SDK中的dex模塊dx.jar,用asm修改dx.jar中載入class的入口API,在函數中加入我們hook機制代碼,對每一個載入的class進行代碼註入。最後以安裝包的形式提供用戶。

優點:一勞永逸,適用於所有的android 開發工具,適合eclipse,android studio,各種腳本編譯等,開發工期短。在初期,我們採用這種方法,很快完成了產品的開發,推向市場

缺點: 安裝過程中需要替換用戶android sdk中的dx.jar文件,屬於侵入式安裝,有一些用戶不太接受。Android sdk不斷的升級,我們也需要不斷推出新的sdk,升級維護比較麻煩。

  1. 插件機制:需要實現不同的開發環境的插件:eclipse插件,gradle插件,各種自動化編譯腳本的插件等。

基本原理: 在各個編譯工具調用dx完成dex的過程中,通過編譯環境提供的介面,調用我們class註入代碼。

優點: 用戶使用比較方便,不用修改用戶android SDk環境,升級維護方便。比如gradle插件,版本放在jcenter倉庫,直接配置就可以了。

實現方案的特點

針對各個開發環境,實現插件,在編譯過程中對class文件進行hook。這是一種靜態hook,不影響系統運行效率,而且對android的系統相容性較好。

但是有一個缺點,不能hook android sdk,只能hook sdk之上的代碼,那麼隨著不同模塊代碼的升級和改變,我們的hook 代碼就不得不隨之改變,而且需要不斷適配新出現的第三發功能模塊。不斷地推出新的sdk版本支持這種變化。需要升級,維護。代碼體積以及記憶體,CPU等性能逐漸降低。

Android c/c++ hook

android的ndk簡介

NDK是Google為Android進行本地開發而放出的一個本地開發工具,包括Android的Na#ve API、公共庫以及編譯工具。

註意:NDK需要Android 1.5版本以上的支持,NDK與SDK是併列關係,DNK是SDK的有效補充。

一個android工程包括2部分:java部分和ndk擴展

So庫文件結構

  • ELF文件格式提供了兩種視圖,分別是鏈接視圖和執行視圖
  • 鏈接視圖是以節(secXon)為單位,執行視圖是以段(segment)為單位。鏈接視圖就是在鏈接時用到的視圖,而執行視圖則是在執行時用到的視圖。上圖左側的視角是從鏈接來看的,右側的視角是執行來看的。

我們比較關註的是執行視圖中,段中.rel.plt項:重定位的地方在.got.plt段內(註意也是.got內,具體區分而已)。 主要是針對外部函數符號,一般是函數。首次被調用時候重定位。首次調用時會重定位函數地址,把最終函數地址放到.got內,以後讀取該.got就直接得到最終函數地址。

so hook關註點

  • 導入表(GOT表 hook),SO引用外部函數的時候,在編譯時會將外部函數的地址以Stub 的形式存放在.GOT 表中,載入時linker 再進行重定位,即將真實的外部函數寫到此 stub 中。
  • HOOK 的思路就是:替換GOT表中的外部函數地址。可以理解為hook導入函數。

So hook基本流程:

  1. 通過讀取 FILE *fd = fopen("/proc/self/maps","r") 記憶體映射表,找到so庫在進程記憶體中的基地址。
  2. 通過基地址,讀取並解析 SO 的結構,找到外部函數對應在GOT 表中的存放地址。
  3. 替換GOT表中的外部函數地址

NDK hook的基本流程:

  • 主要原理:通過解析映射到記憶體中的elf的結構,解析出got,然後進行hook重定位替換。其中必須要基於執行視圖(ExecuXon View)進行符號解析;
  • ELF文件格式是基於鏈接視圖(Linking View),鏈接視圖是基於節(SecXon)對ELF進行解析的。然而動態鏈接庫在載入的過程中,linker只關註ELF中的段(Segment)信息。

NDK hook實現關鍵方法:

1、 從給定的so中獲取基址,獲取so句柄ElfHandle:ElfHandle* handle = openElfBySoname(soname);

2、從segment視圖獲取elf信息(即載入到記憶體的so):getElfInfoBySegmentView(info, handle);

3、根據符號名尋找函數地址Sym:findSymByName(info, symbol, &sym, &symidx);

4、遍歷鏈表,進行一次替換relplt表函數地址操作,其中需要使用mprotect修改訪問記憶體,然後調用系統指令 清除緩存:replaceFunc(addr, replace_func, old_func)

5、遍歷鏈表,進行一次替換reldyn表函數地址操作,其中需要使用mprotect修改訪問記憶體,然後調用系統指令 清除緩存:replaceFunc(addr, replace_func, old_func))

6、釋放資源,關閉elf句柄 :closeElfBySoname(handle);

c/c++層與java層hook的對比

目前的android hook方式具有以下缺點:

  • 實現複雜:需要支持各種開發環境,eclipse android studio,各種自動化編譯工具,每種都比較複雜,開發和維護成本都比較高。需要支持各種用戶使用到的第三方庫。
  • 集成升級和維護:用戶集成比較複雜,升級比較困難,需要不斷的適配新出現的各種第三方庫,因為我們是對用戶代碼進行hook,而不是SDK。

下一代的android agent實現構想

以android naXve sdk 的思路實現,動態hook app。

  • 優點: 針對android sdk進行hook,acXvity 事件,網路,線程,崩潰,anr等直接在android sdk的基礎上進行hook,而不是針對用戶app的實現代碼進行hook,這樣就可以大大減少對第三方庫新增,升級等問題的適配。減少對系統資源的占用。
  • 集成方式: 透視寶android sdk的提供方式so庫和jar包,以普通的so和jar的方式集成,不再需要各種集成插件的支持,支持網路動態升級和維護。
  • Hook方式: 動態hook,在app啟動過程中進行hook,可以各個功能點動態控制。
  • 性能: sdk的體積會大大減少,對CPU的占用會降低
  • 相容性: 現在的相容性是對各個android系統版本之間的相容性,以後只需要對新出現的android 手機系統進行適配。
  • 缺點: 技術難度增加,需要進行大量相容性測試!

寫在最後

近年來,在AIOps領域快速發展的背景下,IT工具、平臺能力、解決方案、AI場景及可用數據集的迫切需求在各行業迸發。基於此,雲智慧在2021年8月發佈了AIOps社區, 旨在樹起一面開源旗幟,為各行業客戶、用戶、研究者和開發者們構建活躍的用戶及開發者社區,共同貢獻及解決行業難題、促進該領域技術發展。

社區先後 開源 了數據可視化編排平臺-FlyFish、運維管理平臺 OMP 、雲服務管理平臺-摩爾平臺、 Hours 演算法等產品。

可視化編排平臺-FlyFish:

項目介紹:https://www.cloudwise.ai/flyFish.html

Github地址: https://github.com/CloudWise-OpenSource/FlyFish

Gitee地址: https://gitee.com/CloudWise/fly-fish

行業案例:https://www.bilibili.com/video/BV1z44y1n77Y/

部分大屏案例:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 怎麼會有人不喜歡花呢?今天我們也來鑒定一下網路熱門植物!最近春天很多花都開了,我正好趁著清明假期到戶外踏青並拍攝 了不少花卉的照片。 由於對很多花不是特別熟悉,所以我們需要藉助軟體來識別究竟是什麼花的種類。市面上的識花軟體有很多,比如花伴侶、形 色、百度等等,我測試後發現百度的識別效果最為優秀。於是 ...
  • BlockingQueue阻塞隊列 BlockingQueue的四組API /**BlockQueue的四組API * 1.拋出異常 * 2.有返回值,不拋出異常 * 3.阻塞等待 * 4.超時等待 */public class BlockQueueTest { public static void ...
  • 前言 大家之前用python編寫過飛機大戰的部分代碼,只能夠展示英雄飛機,背景,敵機和發射子彈,今天把背景音樂,擊毀敵機,爆 炸特效,得分等等相關功能一併加入進來,代碼有點長,三百多行,你們要的代碼來了哦? 編程思路 主要使用pygame庫,類的創建,函數的調用等等來實現,話不多說,上程式。 編程實 ...
  • 反射機制雖然說增加了代碼的複雜程度但是提高代碼的靈活性,在以後的框架的學習中,配置文件的修改大部分都是利用的反射機制。和利用反射機制去做Runtime類這下麵方法exec,進行命令執行,後面去學習一下 ...
  • 官方numpy1.16.3,scipy,onnx的whl包有問題,不要直接安裝,自己編譯。 1.1安裝Python3.7 sudo apt update #檢查可更新文件 sudo apt install software-properties-common #安裝可添加源的工具 sudo add- ...
  • fastposter v2.8.0 發佈 電商海報編輯器 fastposter海報生成器,電商海報編輯器,電商海報設計器,fast快速生成海報 海報製作 海報開發。二維碼海報,圖片海報,生成分享海報 ...
  • 1、簡介 在企業級開發中、我們經常會有編寫資料庫表結構文檔的時間付出,從業以來,待過幾家企業,關於資料庫表結構文檔狀態:要麼沒有、要麼有、但都是手寫、後期運維開發,需要手動進行維護到文檔中,很是繁瑣、如果忘記一次維護、就會給以後工作造成很多困擾、無形中製造了很多坑留給自己和後人,於是萌生了要自己寫一 ...
  • 類與對象 | C++基礎 C++語言程式設計網課 C++中支持我們使用類來定義自己的數據類型。 類的基本思想:數據抽象(data abstraction) 與 封裝(encapsulation)。 數據抽象:依賴於 介面(interface) 和 實現(implementation) 分離的編程(及 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...