android免root權(quán)限通過hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯-尼古拉斯_第1頁
android免root權(quán)限通過hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯-尼古拉斯_第2頁
android免root權(quán)限通過hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯-尼古拉斯_第3頁
android免root權(quán)限通過hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯-尼古拉斯_第4頁
android免root權(quán)限通過hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯-尼古拉斯_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、2020/3/8尼古拉斯.Android免Root權(quán)限通過Hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯 Android技術(shù)篇 尼古拉斯 . 2年前 (2018-03-12) 9076一、知識(shí)回顧在之前一篇文章中,已經(jīng)介紹了Android中如何修改內(nèi)存指令改變方法執(zhí)行邏輯,當(dāng)時(shí)那篇文章的大致流程很簡(jiǎn)單,在程序運(yùn)行起來,dex文件被加載到內(nèi)存中之后,通過maps文件,獲取dex文件的內(nèi)存其實(shí)地址,然后通過文件頭信息找到指定dex在內(nèi)存中的數(shù)據(jù)結(jié)構(gòu),這里還需要詳細(xì)了解Dex文件的格式,不了解的同學(xué)可以看這篇文章:Android中Dex文件格式,然后使用系統(tǒng)函數(shù)修改內(nèi)存讀寫屬性,在通過指定方法名找到該方

2、法在內(nèi)存的指令地址,然后替換即可??梢院?jiǎn)單看一下dex文件被到內(nèi)存之后的地址:二、免root進(jìn)行native層hook上面的這種方案有一點(diǎn)不好就是,需要熟悉dex文件格式,然后通過方法名通過地址轉(zhuǎn)化獲取其內(nèi)存對(duì)應(yīng)的指令,操作有點(diǎn)繁瑣,而本文將介紹一種簡(jiǎn)便的方式,修改起來非常簡(jiǎn)單。就是通過hook系統(tǒng)函數(shù)來做到這一點(diǎn)。而這種hook功能是免root的,所以只能hook應(yīng)用邏輯。對(duì)其他應(yīng)用程序沒有1/262020/3/8任何效果,不過這個(gè)就已經(jīng)滿足本文操作的需求了,關(guān)于hook系統(tǒng)函數(shù)網(wǎng)上已經(jīng)有現(xiàn)成的框架:/ele7enxxh/Android-Inline-Hook,這個(gè)框架用法也非常簡(jiǎn)單。自己之

3、后導(dǎo)入工程即可。下面來看看它的具體用法:新建一個(gè)NDK工程,這個(gè)不多多說了,然后把這幾個(gè)框架中的文件拷貝到j(luò)ni目錄下,hook代碼主要在InlineHook.cpp中:2/262020/3/8這里看到會(huì)用到兩個(gè)函數(shù)進(jìn)行hook:第一個(gè)是函數(shù):registerInlineHook參數(shù):1、原始函數(shù)地址,2、hook的新函數(shù)地址,3、原始函數(shù)的二級(jí)指針第二個(gè)是hook函數(shù):inlineHook參數(shù):1、原始函數(shù)地址3/262020/3/8這里為了演示效果,先Hook系統(tǒng)函數(shù)puts,需要在hook之前定義新函數(shù)以及舊函數(shù)的函數(shù)指針類型,這里一定要注意,新函數(shù)定義類型要和原始函數(shù)保持一致。不然ho

4、ok失敗的:接下來,需要出發(fā)這個(gè)hook操作,可以在java層定義一個(gè)native方法,然后加載出發(fā)即可:這里定義一個(gè)native方法了,然后用javah命令生成指定的頭文件即可:4/262020/3/8在native方法中開始進(jìn)行hook操作,運(yùn)行程序看日志信息即可:看到了,成功的hook了系統(tǒng)函數(shù)puts。接下來開始進(jìn)入本文的正題了,如何hook系統(tǒng)函數(shù)來修改程序運(yùn)行時(shí)態(tài)指令。三、hook系統(tǒng)加載類函數(shù)在上面的hook操作中可以看到,如果想hook一個(gè)函數(shù),需要先找到這個(gè)函數(shù)的,所以第一步需要想好hook哪個(gè)系統(tǒng)函數(shù),如何獲取這個(gè)函數(shù)的?這個(gè)不難,因?yàn)橄胄薷某绦蜻\(yùn)行時(shí)態(tài)指令,那么肯定和de

5、x加載過程分不開,這個(gè)就簡(jiǎn)單了,直接去 Android源碼/dalvik/libdex/ 下找到DexFile.h頭文件,查看他的函數(shù)和一些數(shù)據(jù)結(jié)構(gòu)定義信息:5/262020/3/8發(fā)現(xiàn)了這個(gè)函數(shù),為什么呢?因?yàn)橹酪粋€(gè)方法執(zhí)行之前肯定需要類信息加載到內(nèi)存,而這個(gè)函數(shù)就是加載類必定運(yùn)行的函數(shù),在看看這個(gè)函數(shù)的:返回值是DexClassDef結(jié)構(gòu)體指針,看看DexClassDef定義結(jié)構(gòu)體:這個(gè)結(jié)構(gòu)體就是描述了一個(gè)類的詳細(xì)信息,每個(gè)字段在這里不多解釋了,不了解的同學(xué)可以去看看之前介紹dex文件格式的那篇文章。這里是類代碼數(shù)據(jù)的偏移地址,這個(gè)值在后面會(huì)用到,用它獲取類代碼結(jié)構(gòu)體信息,后面會(huì)介紹。關(guān)

6、心的就兩個(gè)參數(shù)是:第一個(gè)參數(shù):DexFile結(jié)構(gòu)體指針6/262020/3/8這個(gè)結(jié)構(gòu)體包括了整個(gè)類的全局信息。后面再獲取其他結(jié)構(gòu)體信息都會(huì)用到這個(gè)值。第二個(gè)參數(shù):是加載類的名稱這個(gè)參數(shù)在這里也非常重要,因?yàn)橄胄薷囊粋€(gè)方法的指令,肯定需要通過類去查找的,這個(gè)類名就非常重要了。分析完了這個(gè)函數(shù)之后,下面就開始操作了hook了,不過還需要做兩件事:7/262020/3/8第一件事:因?yàn)榭吹缴厦嫔婕暗胶芏郿ex的結(jié)構(gòu)體定義,所以需要手動(dòng)的把這個(gè)系統(tǒng)頭文件DexFile.h拷貝到的工程中,可以只保留一些有用的結(jié)構(gòu)體定義和函數(shù)即可。第二件事:因?yàn)閔ook的時(shí)候需要原始函數(shù)地址的,所以這里需要利用系統(tǒng)函數(shù)

7、dlopen和dlsym來獲取指定函數(shù)的地址,關(guān)于這兩個(gè)函數(shù)用法網(wǎng)上介紹的知識(shí)非常多了,這里不在詳細(xì)介紹了,他們大致的功能就是可以通過函數(shù)名獲取so文件中的函數(shù)地址。這里又要注意,為了獲取正確的函數(shù)名稱,件:需要導(dǎo)出設(shè)備中的libdvm.so文件,在設(shè)備的/system/lib/libdvm.so下,然后用IDA打開libdvm.so文搜索dexFindClass函數(shù)名,然后查看他的代碼位置,獲取導(dǎo)出的函數(shù)名。上面兩件事完成之后,下面就可以開始hook操作了,操作過程和上面hook系統(tǒng)函數(shù)puts方式完全一樣:然后使用dlopen和dlsym函數(shù)獲取正確的函數(shù)地址即可。8/262020/3/8

8、hook觸發(fā)邏輯,依然是之前定義的native方法:9/262020/3/8到這里,一個(gè)工程:還需要做一個(gè)操作,就是手動(dòng)利用DexClassLoader來加載一個(gè)自己編寫的dex文件,來看看hook是否成功了。所以還需要在構(gòu)建這個(gè)工程非常簡(jiǎn)單,有一個(gè)的工具類,類中有一個(gè)計(jì)算方法:10/262020/3/8的目的就是把這個(gè)方法的乘法改成加法操作。運(yùn)行這個(gè)工程,獲取dex文件,這里為了加載簡(jiǎn)單,直接把這個(gè)dex文件放到SD卡目錄下,然后在回到上面的hook工程,需要在Java成編寫一個(gè)加載dex文件的方法:11/262020/3/8利用DexClassLoader加載之前將CoreDex工程編譯獲

9、取的dex文件,然后加載類利用反射執(zhí)行計(jì)算方法,傳入的參數(shù)是2和3,正常結(jié)果是乘法也就是6,就要把乘法變成加法,讓結(jié)果輸出的是5。加載邏輯用一個(gè)點(diǎn)擊事件來觸發(fā):12/262020/3/8在回到native層中的hook代碼:13/262020/3/8這里主要看hook的新函數(shù)功能,過程有點(diǎn)復(fù)雜,這里一步一步來詳細(xì)分析。首先需要過濾處理的類,不能所有的類都做處理,然后通過原始函數(shù),獲取類的DexClassDef結(jié)構(gòu)信息,然后利用系統(tǒng)函數(shù)dlsym調(diào)用函數(shù)dexReadAndVerifyClassData獲取類對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)信息,這里依然需要用IDA打開libdvm.so文件查看這個(gè)函數(shù)的導(dǎo)出名稱

10、:獲取到類對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)DexClassData信息,之后就可以獲取類中的方法個(gè)數(shù)和具體信息了,這里再來看一下DexClassData數(shù)據(jù)結(jié)構(gòu)信息,這個(gè)結(jié)構(gòu)體在DexClass.h中,依然把結(jié)構(gòu)信息拷貝到的工程中即可:14/262020/3/8利用系統(tǒng)函數(shù)dexGe有了這個(gè)結(jié)構(gòu)體,下面就來獲取方法的個(gè)數(shù),這里的方法分為類方法和對(duì)象方法,在DexDtClassData獲取類的代碼數(shù)據(jù)結(jié)構(gòu):lassHeader結(jié)構(gòu)體信息中,這里15/262020/3/8接下來,繼續(xù)看如何獲取類中的方法信息:16/262020/3/817/262020/3/8因?yàn)橹滥莻€(gè)calculateMoney方法是對(duì)象方法,

11、所以這里直接獲取對(duì)象方法結(jié)構(gòu)體信息,然后依次遍歷獲取每個(gè)方法,通過系統(tǒng)函數(shù)dexGetMethodId獲取DexMethodIds結(jié)構(gòu)體信息:這里需要注意的是每個(gè)方法都是在內(nèi)存中依次挨著的,所以直接利用指針操作即可獲取每個(gè)方法的結(jié)構(gòu)體信息。然后在利用系統(tǒng)函數(shù)dexStringById獲取方法名稱,這個(gè)也是系統(tǒng)函數(shù),一樣方式拷貝到工程中來即可:有了方法名就需要進(jìn)行過濾了,只處理的那個(gè)calculateMoney方法,然后在獲取方法對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)信息DexCode了,依然如此,Code結(jié)構(gòu)體信息從系統(tǒng)中拷貝到工程中:需要把Dex18/262020/3/8然后利用系統(tǒng)函數(shù)dexGetCode通過De

12、xMethod結(jié)構(gòu)體獲取DexCode結(jié)構(gòu)體信息有了DexCode結(jié)構(gòu)體信息之后,可以打印方法的原始指令數(shù)據(jù):19/262020/3/8然后因?yàn)樾枰薷膬?nèi)存指令,所以還需要把內(nèi)存修改為可讀屬性:這里需要注意的是,修改的起始地址一定是系統(tǒng)內(nèi)存頁的整數(shù)倍,所以需要做一次轉(zhuǎn)化。修改完內(nèi)存屬性之后。四、修改指令邏輯接下來就可以構(gòu)造指令,然后替換內(nèi)存指令即可。那么如何獲取原始指令,怎么把乘法改成加法呢?這里就需要利用010Editor法的指令數(shù)據(jù):了,直接查看這個(gè)方20/262020/3/8這里看到,這個(gè)方法有三條指令,但是一條指令是兩個(gè)字節(jié),所以一共是6個(gè)字節(jié),這里看到的是十進(jìn)制的數(shù)據(jù)了,6個(gè)十六進(jìn)制

13、數(shù)據(jù):可以把這三個(gè)十進(jìn)制數(shù)據(jù)轉(zhuǎn)化成然后現(xiàn)在只需要把乘法指令碼改成加法指令碼即可,這個(gè)需要參考Bytecode of Dalvik了:這里也看到加法指令就是十六進(jìn)制的90,也就是十進(jìn)制的144,所以咋們替換指令就簡(jiǎn)單了:21/262020/3/8替換指令之后,在此打印指令數(shù)據(jù)即可,好了,到這里就完成了所有的操作了,下面就來運(yùn)行看看日志信息了:看到日志,成功的把指令146變成了144了,在往下看日志,就可以看到計(jì)算結(jié)果是加法了,也就是5:22/262020/3/8就這樣在內(nèi)存中修改了這個(gè)方法的指令邏輯,把乘法邏輯變成了加法邏輯了。神奇吧。到這里也算介紹完了本文的大致內(nèi)容了。不過有的同學(xué)可以看得沒太

14、明白,沒關(guān)系,下面在來總結(jié)一程:五、流程總結(jié)首先明確的目的就是想能修改內(nèi)存中指定方法的運(yùn)行指令邏輯,那么不用之前介紹的那個(gè)內(nèi)存中的dex數(shù)據(jù)然后靠地址來檢索到指令地址,而是采用hook系統(tǒng)函數(shù)來實(shí)現(xiàn):第一步:就需要找到hook點(diǎn),每個(gè)方法要想運(yùn)行肯定是先將方法所屬的類加載到內(nèi)存中,那么就需要調(diào)用系統(tǒng)的函數(shù):dexFindClass,而這個(gè)函數(shù)的返回值是一個(gè)DexClassDef結(jié)構(gòu)體信息。第二步:通過DexClassDef結(jié)構(gòu)體信息獲取類的數(shù)據(jù)結(jié)構(gòu)體信息DexClassData,然后獲取類的所有方法信息。第三步:遍歷方法結(jié)構(gòu)體信息DexMethod,找到想要處理的方法信息,然后在獲取其DexC

15、ode方法數(shù)據(jù)結(jié)構(gòu)體信息。第四步:有了方法數(shù)據(jù)結(jié)構(gòu)體信息之后,就可以獲取到方法的指令個(gè)數(shù)和具體指令數(shù)據(jù),在修改之前必須修改內(nèi)存屬性為可讀寫的。第五步:通過查閱虛擬機(jī)指令集,找到加法指令碼替換原來的乘法指令碼,然后覆蓋內(nèi)存中的原始指令即可。所以在這個(gè)過程中發(fā)現(xiàn),會(huì)涉及到很多數(shù)據(jù)結(jié)構(gòu)體,不過好在這些結(jié)構(gòu)體信息都定義在DexFile.h和DexClass.h這兩個(gè)頭文件中,他們存放在Android源碼/dalvik/libdex/目錄下。而這些結(jié)構(gòu)體信息也是相互包含的,下面就來整理一下:23/262020/3/8嚴(yán)重本文的所有代碼可以進(jìn)入編碼美麗小密圈自取,為了安全考慮,請(qǐng)大家不要利用本文代碼做操作

16、,秉著技術(shù)學(xué)習(xí)本文尼內(nèi)容!如果有人利用本文技術(shù)操作東西帶來的法律由操作者自己負(fù)責(zé),與本文作者沒任何關(guān)系!六、總結(jié)當(dāng)然本文介紹完了之后,有一個(gè)很大的用途就是hook虛擬機(jī)的一些函數(shù)來做一些事情,其實(shí)說到這里本文并不是本次研究的重點(diǎn),重點(diǎn)是下一篇文章,只是為了需要hook系統(tǒng)的函數(shù),本文就先做個(gè)鋪墊而已。聰明的人應(yīng)該知道我下一篇文章要介紹啥了,而下一篇文章才是重點(diǎn)。篇幅原因,不得不將其內(nèi)容拆分了??次谋疚闹螅欢ㄒ浀靡稽c(diǎn),不僅在java層可以免root進(jìn)行hook操作,在native也是可以的。這個(gè)知識(shí)點(diǎn)對(duì)未來安全防護(hù),逆向分 析,應(yīng)用開發(fā)都非常重要。24/262020/3/8Android應(yīng)

17、用安全防護(hù)和逆向分析點(diǎn)擊立即:京東天貓請(qǐng)注明:尼古拉斯. Android免Root權(quán)限通過Hook系統(tǒng)函數(shù)修改程序運(yùn)行時(shí)內(nèi)存指令邏輯25/26(0) 喜歡 (12)or2020/3/8爬取應(yīng)用英語流利說的配音數(shù)據(jù)(第一次這么粉一個(gè)人)Android中實(shí)現(xiàn)類方法指令抽取方式加固方案原理Android掛修練之行修改器插件開發(fā)詳解聊天消息Android逆向之旅開啟快手AppAndroid掛修練之行中把朋友Android逆向之旅最右App的簽名算的長拍攝權(quán)限功能圈封面設(shè)置成酷炫功能插件開發(fā)詳解法(ARM指令學(xué)習(xí)回首篇)Android掛修練之行修改器插件開發(fā)詳解聊天消息Android逆向之旅開啟快手Android掛修練之行友圈封面設(shè)置成酷炫中把朋Android逆向之旅最右App的簽名App的長拍攝權(quán)限功能功能插件開算法(ARM指令學(xué)習(xí)回首篇)Android掛修練之行Android掛修練之行

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論