作者:Denny Qiao(喬喜銘),云智慧/架構師,
云智慧集團成立于2009年,是全堆疊智能業務運維解決方案服務商,經過多年自主研發,公司形成了從IT運維、電力運維到IoT運維的產業布局,覆寫ITOM、ITOA、ITSM、DevOps以及IoT幾大領域,為金融、政府、運營商、能源、交通、制造等上百家行業的客戶,提供了數字化運維體系建設及全生命周期運維管理解決方案,云智慧秉承Make Digital Online的使命,致力于通過先進的產品技術,為企業數字化轉型和提升IT運營效率持續賦能,
android java層hook機制
android dalvic虛擬機和JVM的區別
- Dalvik虛擬機并不是按照Java虛擬機的規范來實作的,與jvm并不兼容
- Java虛擬機運行的是Java位元組碼,而Dalvik虛擬機運行的則是其專有的檔案格式DEX(Dalvik Executable)
- Davic讀取的是dex檔案,jvm讀取的.class和jar檔案
- Dalvik基于暫存器,而JVM基于堆疊
- 每一個Android應用都運行在一個Dalvik虛擬機實體里,而每一個虛擬機實體都是一個獨立的行程空間,虛擬機的執行緒機制,記憶體分配和管理,Mutex等等都是依賴底層作業系統而實作的,所有Android應用的執行緒都對應一個Linux執行緒,虛擬機因而可以更多的依賴作業系統的執行緒調度和管理機制
- 有一個特殊的虛擬機行程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的實作方案
- 直接修改android SDK中的dex模塊dx.jar,用asm修改dx.jar中加載class的入口API,在函式中加入我們hook機制代碼,對每一個加載的class進行代碼注入,最后以安裝包的形式提供用戶,
優點:一勞永逸,適用于所有的android 開發工具,適合eclipse,android studio,各種腳本編譯等,開發工期短,在初期,我們采用這種方法,很快完成了產品的開發,推向市場,
缺點: 安裝程序中需要替換用戶android sdk中的dx.jar檔案,屬于侵入式安裝,有一些用戶不太接受,Android sdk不斷的升級,我們也需要不斷推出新的sdk,升級維護比較麻煩,
- 插件機制:需要實作不同的開發環境的插件: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基本流程:
- 通過讀取 FILE *fd = fopen("/proc/self/maps","r") 記憶體映射表,找到so庫在行程記憶體中的基地址,
- 通過基地址,讀取并決議 SO 的結構,找到外部函式對應在GOT 表中的存放地址,
- 替換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/
部分大屏案例:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/458495.html
標籤:其他
下一篇:C++基礎01-類與物件
