帶你開發(fā)一款給Apk中自動注入代碼工具icodetools(開鑿篇)

一、前言
從這篇開始咋們開始一個全新的靜態(tài)方式逆向工具icodetools的實現(xiàn)過程惠奸,這個也是我自己第一次寫的個人覺得比較有用的小工具,特別是在靜態(tài)方式逆向apk找關(guān)鍵點的時候宇整,后續(xù)會分為三篇來詳細介紹這個工具實現(xiàn):
第一篇:開鑿篇晌坤,簡單介紹實現(xiàn)原理以及簡單的初次方案實現(xiàn)簡單的apk注入代碼功能
第二篇:填坑篇,這一篇是在前一篇的基礎上對工具的優(yōu)化丈牢,可以應對市面上大部分的apk代碼注入功能實現(xiàn)
第三篇:生產(chǎn)篇祭钉,這一篇是在前兩篇的基礎上利用這個工具來實際操刀如何進行快速定位應用的關(guān)鍵方法功能
還記得那一年咋們 靜態(tài)方式破解應用,為了更好的追蹤代碼位置己沛,手動反編譯成smali文件慌核,然后添加smali日志代碼,在回編譯申尼,查看日志信息來定位關(guān)鍵點垮卓。那種操作現(xiàn)在回想是苦不堪言,操作非常復雜师幕。那么就嘗試想想如果有一個工具可以在自動為每個方法注入日志代碼粟按,這樣就可以很快速的定位到我們想要的方法,所以本文就來介紹一下這個工具的實現(xiàn)原理霹粥,我將其命名為icodetools灭将。

二、實現(xiàn)方案
首先咋們來看一下具體實現(xiàn)原理吧后控,這個工具最終的形態(tài)應該是這樣的庙曙,就是輸入一個apk,然后在為apk中每個類的每個方法添加一段打印此方法的堆棧信息日志浩淘,然后在重新簽名打包成新的apk捌朴。所以這個過程中我們最關(guān)鍵的地方就是如何把日志代碼插入到已經(jīng)編譯好的apk中吴攒。我們可能想到的有兩個方案:
第一個方案:首先利用apktool進行反編譯成smali文件,然后解析smali文件找到每個方法的位置男旗,添加指定smali日志代碼舶斧。那么這里有一個很大的問題,就是如何分析smali文件察皇,如何定位到每個方法茴厉?這個過程工作量就比較大了,所以這個方案就廢棄了什荣。
第二個方案:利用dex2jar獲取到apk中的dex轉(zhuǎn)化之后的jar文件矾缓,然后在解析jar文件獲取到每個class文件,解析class文件進行方法的信息獲取稻爬。這里會發(fā)現(xiàn)這個方案很靠譜嗜闻,因為我們解析class文件比解析smali文件方便多了。而且在這個過程中會發(fā)現(xiàn)有一個更大的驚喜桅锄,就是dex2jar這個工具是開源的琉雳,其實內(nèi)部實現(xiàn)原理就是解析dex文件格式,然后借助asm工具將其變成class文件的友瘤,這里又出現(xiàn)了一個非常重要的工具asm翠肘,這個工具下面會詳細介紹。
說明:
1》這里非常感謝dex2jar的作者Claud大神的開源精神辫秧,這個工具的地址:https://github.com/pxb1988/dex2jar束倍,是純java代碼,所以大家一定要先解讀這個工具源碼盟戏,內(nèi)部實現(xiàn)原理自己研讀绪妹,本文不會詳細介紹的。
2》這里有的同學會想到柿究,能不能直接解析dex文件格式邮旷,然后在找到每個類的每個方法添加日志信息,雖然我們在前面有詳細介紹dex文件格式:Dex文件格式詳解蝇摸,但是如果想在每個類每個方法中添加日志代碼這個工作量感覺比操作smali還要復雜廊移,所以直接將其轉(zhuǎn)化成class文件進行操作就非常方便了,因為我們有asm工具探入。
三狡孔、方案實現(xiàn)
上面已經(jīng)探討了方案了,在上面提到了很多次一個非常重要的工具就是asm蜂嗽,那么這個工具到底是干嘛的呢苗膝?這個工具非常有用,他的表現(xiàn)之處在JavaWeb開發(fā)中的Spring框架就有用到植旧,可以動態(tài)的解析class文件辱揭,然后可以操作這個類离唐,比如添加類成員,方法等等操作问窃。所以下面不多解釋了亥鬓,直接用一個簡單的案例來看看他的強大之處,我們實現(xiàn)給一個類添加一個成員字段域庇,方法嵌戈,給每個方法調(diào)用前添加一行代碼。
第一听皿、asm庫基本使用


這里借助ClassReader來讀取一個類熟呛,使用ClassVisitor來進行類信息操作,ClassWriter將操作完之后的類寫入文件中
第二尉姨、添加類成員字段
上面看到了一個主要的類ClassVistor庵朝,他主要就是用來操作一個類:

這里看到的是繼承了ClassAdapter,然后在構(gòu)造方法中可以添加類成員信息包括字段又厉,方法等九府,這里我們添加一個字段mJW,類型是String的覆致≈堆看看如何添加的:

借助ClassVisitor的visitField方法就可以進行字段的添加了。然后我們運行程序之后篷朵,使用JD-GUI工具查看保存本地的class文件信息:

看到了吧勾怒,這里成功的定義了一個字段mJW婆排。

第三声旺、為類的所有方法前添加代碼
這里我們需要借助另外一個類了MethodVisitor了,他是用來操作方法信息的:


在ClassAdapter的visitMethod回調(diào)方法中可以獲取方法信息段只,然后進行操作:

在visitCode回調(diào)方法中利用MethodVisitor開始添加代碼:

這里看到可以利用visitFieldInsn方法方法System類的靜態(tài)變量out腮猖,然后在使用visitLdcInsn從常量池中獲取值,最后在利用visitMethodInsn方法來調(diào)用PrintStream類的成員方法println來打印信息赞枕,運行程序之后繼續(xù)借助JD-GUI來查看class文件:

看到了澈缺,類中所有的方法前面都被加了一行打印代碼。
注意:有的同學發(fā)現(xiàn)了炕婶,上面那個添加代碼怎么得到呢姐赡?難道真的要記住那么多api去添加嗎?其實不用那么復雜柠掂,Eclipse有一個插件Bytecode项滑,可以把Java代碼自動生成類似于上面的代碼,咋們之后手動拷貝一下就好了涯贞!工具后面會說枪狂。

第四危喉、為類添加成員方法
下面在來看最后一個操作吧,就是給類中添加一個成員方法州疾,有了上面的操作之后我們應該知道辜限,如果要操作類就要借助ClassVisitor類,要是操作方法就需要借助MethodVisitor類严蓖,那么這里為類添加成員方法薄嫡,借助ClassVistor類來進行操作了,但是在操作之前咋們得先搞好一個工具Bytecode谈飒,這個是Eclipse插件岂座,安裝很簡單:



安裝完成之后,可以打開視圖欄:



然后選擇Java中的bytecode視圖就可以了:

下面咋們首先在一個類中編寫好我們想要添加的方法代碼杭措,然后點擊Bytecode視圖卡片就可以看到對應的asm代碼:

看到了吧费什,這樣操作是不是如此簡單,我們可以把這段asm代碼直接拷貝到AsmUtils中:



然后在ClassVisitor的構(gòu)造方法中直接調(diào)用這個方法就可以了:

再次運行程序之后手素,使用JD-GUI查看類信息:

成功的添加了printStackTrace方法了鸳址。就是如此簡單。借助Eclipse的強大工具Bytecode就可以了泉懦,以后都不要在自己去調(diào)用asm庫的api去手動編寫了稿黍。這個工具太好了得記住它!

四崩哩、工具案例實踐
上面就介紹完了如何操作一個類和方法巡球,給類添加字段,方法邓嘹,在每個方法之前添加一行代碼酣栈。下面就得進入本文的主題了,如何給apk應用中每個類中的每個方法添加一行打印日志信息汹押。在開始的時候我們有了方法矿筝,就是借助工具dex2jar源碼,他內(nèi)部也是解析dex格式棚贾,然后利用asm將其信息變成一個class文件的窖维,那么我們只要在這個過程中得到ClassVisitor和MethodVisitor這兩個對象,就可以盡情的干很多事了妙痹。所以第一步你一定要先看懂dex2jar的源碼铸史。這里我不會對源碼進行詳細分析了,用過dex2jar工具的都知道怯伊,找入口很簡單琳轿,直接看他的一個d2j-dex2jar.bat腳本信息:


Dex2jarCmd就是工具的入口類:

然后分析代碼,會發(fā)現(xiàn)處理的核心類是Dex2jar類:

這里會看到可以拿到ClassVisitor類對象的,那么我就可以添加打印堆棧信息的方法了:

這里需要注意的是打印消息用了Android的Log.d方法利赋。然后在每個方法調(diào)用之前在調(diào)用這個打印方法:

這里過濾依然過濾了構(gòu)造方法和靜態(tài)代碼塊方法水评。

其實我們就需要這么做就可以了,下面咋們就用一個簡單的Apk來做一下實驗媚送,咋們把apk中的classes.dex文件解壓出來中燥,為了簡單直接跑這個dex2jar工具,可以在Dex2jarCmd開始處構(gòu)造一個簡單的命令:


輸入的dex文件為指定目錄的塘偎,輸出的jar文件也是指定目錄的:

然后咋們就可以運行程序了疗涉。運行結(jié)束之后我們得到了一個classes.jar文件,可以使用JD-GUI進行查看:

到這里我們就成功的吟秩,把apk中的classes.dex中的每個類每個方法添加了我們自己的打印消息的代碼了咱扣,已經(jīng)成功一大半了,下面為了驗證效果涵防,咋們還得把classes.jar轉(zhuǎn)成dex闹伪,在弄到apk中運行看效果。這個過程就簡單了壮池,利用系統(tǒng)的dx命令偏瓤,把classes.jar在變成classes.dex文件:

然后在把這個classes.dex文件塞到apk中,不過這時候得重新簽名了椰憋,可以借助jarsigner工具:
jarsigner -verbose -keystore cyy_game.keystore -storepass cyy1888 -signedjar signed.apk unsigned.apk cyy_game.keystore -digestalg SHA1 -sigalg MD5withRSA
然后咋們就可以安裝apk厅克,然后開始運行效果:

看到效果了吧,表示成功的不要不要的橙依。有點小興奮证舟,通過棧信息加上我們出發(fā)一個事件之后就可以定位這個事件的方法了。對于我們在使用hook的時候?qū)ふ襤ook點非常重要窗骑。

五女责、技術(shù)總結(jié)
到這里我們本文的知識點就算結(jié)束了,但是整個工具開發(fā)并沒有結(jié)束慧域,下面就來總結(jié)一下本文涉及到的知識點:
1鲤竹、學會了利用asm庫來操作類浪读,實現(xiàn)添加字段昔榴,方法等操作。
2碘橘、了解到了Eclipse的一個強大插件Bytecode互订,可以快速得到java代碼對應的asm代碼
3、了解了dex2jar的實現(xiàn)原理痘拆,內(nèi)部也是借助于asm來進行操作的
其實本文的這個自動注入代碼工具絕大部分是借助了dex2jar這個工具的仰禽,我們只是在適當?shù)牡胤教砑恿宋覀兿胍男畔⒋a。在操作類的時候只要有ClassVisitor對象就可以操作類,MethodVisitor對象就可以操作方法了吐葵。而在dex2jar中正好有這兩個對象规揪,所以我們實際要操作的內(nèi)容并不復雜。當我們使用通過修改之后的dex2jar得到了classes.jar之后温峭,在用dx工具將其還原成classes.dex文件猛铅,在放到apk中進行重簽名驗證。

六凤藏、遺留的問題
如果到這里有的同學覺得這個是挺簡單的奸忽,那其實就錯了,因為開始的時候我已經(jīng)說了后面還有一個填坑篇文章揖庄,在那篇文章會詳細說明在實際操作其他企業(yè)app會遇到哪些問題栗菜,我們需要繼續(xù)優(yōu)化這個工具,同時對這個工具最好能夠做到一鍵化工作蹄梢,所以我們需要解決這幾個問題:
1疙筹、上面看到我們是為每個類添加了一個打印棧信息的方法,那么就有一個很大的問題禁炒,如果一個dex文件過大腌歉,包含的類很多,那么就是增加了很多方法齐苛,對于dx進行轉(zhuǎn)化的時候會發(fā)現(xiàn)方法數(shù)超了翘盖。
2、在實際的apk操作過程中會發(fā)現(xiàn)在每個方法中插入日志之后凹蜂,當你啟動app的時候那日志幾乎會被霸屏的馍驯,而且一個龐大的app內(nèi)部調(diào)用的方法非常多,導致應用會出現(xiàn)無響應狀態(tài)玛痊,所以咋們得弄個開關(guān)以及想在哪些方法中添加汰瘫。
3、上面在看到在整個過程中擂煞,先把dex轉(zhuǎn)成jar混弥,然后再把jar轉(zhuǎn)成dex,在放到apk中对省,在簽名蝗拿,整個過程我們都是手動操作的,顯得非常的費勁蒿涎,所以我們還得優(yōu)化這個工作哀托,做到真正意義上的一鍵化,輸入一個apk劳秋,輸入就是已經(jīng)添加日志信息的apk就可以了仓手。

所以后面一個填坑篇文章會有很多工作要做的胖齐,當坑都填完了,咋們就得實際生產(chǎn)拿一些app進行實戰(zhàn)操刀了嗽冒。最后在來看一下我總結(jié)的一張原理圖吧(可以點擊查看高清大圖):

嚴重說明:
===》本文介紹的是基礎篇呀伙,可以看到我們是大致走通了整個流程,但是這個和最終的工具實現(xiàn)差的很多添坊,后續(xù)還有很多問題需要解決区匠,所以重點其實在下一篇中,那里會去解決在實際使用過程中遇到的各個問題帅腌。以及最重要的就是如何把所有的步驟連貫起來驰弄,一鍵化開發(fā)完善。一定要記得看下一篇內(nèi)容速客,那里才是主戰(zhàn)場戚篙!
===》一定要自己去github上下載dex2jar的源碼,自己先調(diào)試走通程序溺职,不然一切都是枉然岔擂,因為這個工具是純Java編寫的,代碼不是很多浪耘,所以難度不大乱灵。

七、總結(jié)
對于這個自動插入代碼的工具我個人覺得有需求采取這么干的七冲,因為以前遭受過那種手動注入代碼的痛苦痛倚,但是從本文的工具可以看到,對于一些加固app是無能無力的澜躺。而工具的理念來源是美團的一個熱修復框架Robust的蝉稳。關(guān)于源碼的話等后面都介紹完了,我把我寫的部分公開掘鄙,但是你還是得先去看看dex2jar的源碼耘戚。又開始了寫這種文章,每次寫完感覺自己身體被掏空了一樣操漠,多多點贊收津。打賞就在好不過了。

更多內(nèi)容:點擊這里

關(guān)注微信公眾號浊伙,最新技術(shù)干貨實時推送


掃一掃加小編微信添加時注明:“編碼美麗”否則不予通過撞秋!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吧黄,隨后出現(xiàn)的幾起案子部服,更是在濱河造成了極大的恐慌唆姐,老刑警劉巖拗慨,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡赵抢,警方通過查閱死者的電腦和手機剧蹂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦却,“玉大人宠叼,你說我怎么就攤上這事∑渚簦” “怎么了冒冬?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摩渺。 經(jīng)常有香客問我简烤,道長,這世上最難降的妖魔是什么摇幻? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任横侦,我火速辦了婚禮,結(jié)果婚禮上绰姻,老公的妹妹穿的比我還像新娘枉侧。我一直安慰自己,他們只是感情好狂芋,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布榨馁。 她就那樣靜靜地躺著,像睡著了一般帜矾。 火紅的嫁衣襯著肌膚如雪辆影。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天黍特,我揣著相機與錄音蛙讥,去河邊找鬼。 笑死灭衷,一個胖子當著我的面吹牛次慢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翔曲,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼迫像,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瞳遍?” 一聲冷哼從身側(cè)響起闻妓,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掠械,沒想到半個月后由缆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體注祖,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年均唉,在試婚紗的時候發(fā)現(xiàn)自己被綠了是晨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡舔箭,死狀恐怖罩缴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情层扶,我是刑警寧澤箫章,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站镜会,受9級特大地震影響炉抒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稚叹,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一焰薄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扒袖,春花似錦塞茅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至飒泻,卻和暖如春鞭光,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泞遗。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工惰许, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人史辙。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓汹买,卻偏偏與公主長得像,于是被迫代替她去往敵國和親聊倔。 傳聞我的和親對象是個殘疾皇子晦毙,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,756評論 25 707
  • 習慣了講事情盐股,早就不知道什麼叫關(guān)注人了!面對這個話題返敬,腦殼犯暈遂庄,回想起活了這麼多年寥院,依然不知道什麼叫關(guān)注...
    落子無悔ss閱讀 153評論 0 0
  • 系列文章:1-準備工作2-搭建項目框架3-功能實現(xiàn)4-加入網(wǎng)絡緩存 請先閱讀MVP架構(gòu)實現(xiàn)的Github客戶端(1...
    anly_jun閱讀 5,238評論 23 38
  • 自由書寫第九篇 有些話不及時記錄下來秸谢,會爛在肚子里凛澎,隨著時間的推移它會慢慢發(fā)酵,并不會消失和療愈估蹄,等到發(fā)酵到一定程...
    Wendy3閱讀 301評論 0 1