用python一步步解剖dex文件(二)

請勿轉(zhuǎn)載,謝謝S势āU!?



連續(xù)半個月重感冒和咳嗽佑吝,這個時候才倍感身體的重要坐昙。

所以身體才是革命的本錢啊。芋忿。炸客。

言歸正傳。


編碼格式uleb128

先介紹下dex中用到的一種編碼方式uleb128戈钢。

簡單來說痹仙,它是對int(4字節(jié))數(shù)據(jù)的一個可變長度編碼,使得原先固定長度(4字節(jié))的數(shù)據(jù)殉了,可以通過更少的字節(jié)表示出來开仰;而且這個可變長度不超過5。

假定有數(shù)據(jù)序列:a b c d e宣渗,我們把它們用二進制表示出來:

aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee

如果每字節(jié)的高位開頭是1抖所,那么繼續(xù)往后;如果高位開頭是0痕囱,那么終止在這里田轧;然后把所有的高位都去除,反序拼出來的二進制鞍恢,就是最后的結(jié)果傻粘。

比如這樣的:

1aaaaaaa 1bbbbbbb 1ccccccc 0ddddddd eeeeeeee

一直到第4個每窖,它是以0為高位開頭的,那么這個有效數(shù)據(jù)就是前四個字節(jié)組成弦悉,并且反序如下:

ddddddd ccccccc bbbbbbb aaaaaaa

如上窒典,第一是反序,第二是每個字節(jié)只有7位稽莉。

這個就是簡單的uleb128的示范瀑志。

解碼程序如下:

uleb128解碼

數(shù)據(jù)結(jié)構(gòu)

類信息

其中classDataOff是指向類數(shù)據(jù)信息區(qū)域的一個偏移數(shù)值。

類數(shù)據(jù)信息

從這里可以看到污秆,類數(shù)據(jù)其實包含了四種信息劈猪,靜態(tài)屬性,實例屬性良拼,直接方法和虛方法战得。

字段和方法

對于DexMethod來說,它代表一個類的方法庸推,方法中當然是包含代碼的常侦,那么代碼(字節(jié)碼)所在的位置,通過codeOff來表示贬媒。

另外加一個說明聋亡,這里的fieldIdx和methodIdx其實是一個diff,也就是說掖蛤,在field列表和method列表中杀捻,第一個Idx是真實的Idx,后面的Idx都是在這個基礎(chǔ)上做的diff蚓庭。

字節(jié)碼信息

數(shù)據(jù)追蹤

按照上面的數(shù)據(jù)結(jié)構(gòu),我們走一遍真實的dex數(shù)據(jù)仅仆。


頭部區(qū)域中的類區(qū)域信息

如上一篇所講器赞,在dex的頭部區(qū)域中,有兩個字段分別表示類信息的偏移值和類的個數(shù)墓拜;上圖中港柜,第一個四字節(jié)(07)表示類的總個數(shù),第二個四字節(jié)(2ac)就表示類信息的偏移值咳榜。

我們找到2ac處: (按照類定義夏醉,每個類信息占據(jù)4*8=32個字節(jié))

類信息數(shù)據(jù)區(qū)

我們把這7個類的信息,按著類的結(jié)構(gòu)解析并且打印出來:

打印類信息

結(jié)果是這樣的:

類信息

也就是說涌韩,我寫的這個Demo程序中畔柔,在dex里包含了7個類的信息,如上所示臣樱;其中MainActivity就是主Activity靶擦。

我們現(xiàn)在只看這個MainActivity的數(shù)據(jù):

MainActivity類信息

其中類數(shù)據(jù)的偏移數(shù)值腮考,是第7個四字節(jié),也就是5cc (cc05 0000)玄捕。

MainActivity類數(shù)據(jù)信息

這里使用到了前面鎖說的uleb128格式:00 00 01 01(四個字節(jié))

按上面的解釋方法踩蔚,每個字節(jié)都是以0開頭的,所以就是最后的結(jié)果了枚粘,那么定義出來的:

static_field_size = 0

instance_field_size = 0

direct_method_size = 1

virtual_method_size = 1

也就是說馅闽,MainActivity中沒有屬性信息,但是有一個直接方法和一個虛方法馍迄。

接下來的10個字節(jié)捞蛋,就是直接方法和虛方法的信息(屬性為空忽略),它們也是用uleb128進行編碼的柬姚。

解碼信息

這兩個方法分別是:

A: method_idx = 5, code_off = 4f0

B: method_idx = 6, code_off = 508

根據(jù)上一篇文章中介紹的拟杉,我們查找到方法信息如下:

method-idx = 5
method-idx = 6

其中第一個是構(gòu)造函數(shù)<init>,第二個就是我們很熟悉的android方法量承,onCreate搬设。

繼續(xù),我們跟蹤onCreate方法的信息撕捍,它的偏移是508(十六進制):

onCreate方法體數(shù)據(jù)

對照結(jié)構(gòu)如下:

onCreate方法體信息

其中從6f20開始拿穴,連續(xù)的32個字節(jié),就是該方法體的字節(jié)碼信息忧风。

接下來的任務(wù)默色,就是把這32個字節(jié),翻譯成可以識別的指令信息狮腿,就是反匯編過程了腿宰。

在這之前,我們總結(jié)下類信息的打印程序:

讀取類信息
讀取類數(shù)據(jù)(一)
讀取類數(shù)據(jù)(二)

用到的一些方法:

讀取屬性信息
讀取方法信息
讀取注解信息
讀取DexTypeList類型
讀取指令信息

反匯編

前面提到缘厢,onCreate方法中的指令字節(jié)序列吃度,就是下面的32個字節(jié)數(shù)據(jù)。

指令集數(shù)據(jù)

我們知道指令一般是指令符+指令數(shù)組成的贴硫,第一個字節(jié)一般標識一個特定的指令椿每。

在dex格式中,這個指令既表示具體的操作(字節(jié)碼格式)英遭,又對應(yīng)一個數(shù)據(jù)解析格式(說明格式)间护。

字節(jié)碼格式文檔:

https://source.android.google.cn/devices/tech/dalvik/dalvik-bytecode

說明格式文檔:

https://source.android.google.cn/devices/tech/dalvik/instruction-formats

比如第一個字節(jié)是6f,對照文檔如下:

字節(jié)碼格式

字節(jié)碼格式

6e..72是數(shù)字范圍挖诸,下面的35c就代表著數(shù)據(jù)說明格式汁尺。

說明格式

對于上面的35c來說,3表示本次指令共計3個字(2個字節(jié))税灌,5表示寄存器數(shù)目均函,而c是一個助記符標識常量:

助記符

這3個字是怎么排列呢亿虽?

字節(jié)排列

把6f開始的3個字,如上面格式依次排開:

206f 0001 0032

對照格式得出:

A = 2, G = 0, op = 6f, BBBB = 1, C = 2, D = 3, E = 0, F = 0

這里的A = 2苞也,那么對應(yīng)格式:

格式A = 2

也就是op {v2, v3}, kind@0001洛勉。

再對照字節(jié)碼格式文檔,其實就是:

invoke-super {v2, v3}, meth@0001

根據(jù)method的信息如迟,查詢出: meth@0001是

meth@0001

那么前3個字的反匯編代碼就是:

invoke-super {v2, v3}, Landroid/app/Activity; --> V onCreate(Landroid/os/Bundle;)

這個不就是調(diào)用父類Activity的onCreate方法嗎收毫?

對照源代碼:

源代碼

同樣的方式,可以把32個字節(jié)的數(shù)據(jù)殷勘,全部反匯編出來此再。

我們是為了學(xué)習(xí)Dex的結(jié)構(gòu),所以會這么大費周折玲销;更加方便的方式输拇,是直接用現(xiàn)有的反編譯工具,將dex反編譯成smali贤斜,可以更加直觀的看到信息策吠。


在面對一個未知的應(yīng)用時,我們沒有源碼瘩绒,如果去修改它的信息呢猴抹?(假定沒有加固)

最簡單的方式,還是反編譯出smali锁荔,通過修改smali再重新打包蟀给。

如果是,我們直接在dex上修改呢阳堕? 后面繼續(xù)研究和探討跋理。

【待續(xù)】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嘱丢,隨后出現(xiàn)的幾起案子薪介,更是在濱河造成了極大的恐慌,老刑警劉巖越驻,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異道偷,居然都是意外死亡缀旁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門勺鸦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來并巍,“玉大人,你說我怎么就攤上這事换途“枚桑” “怎么了刽射?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長剃执。 經(jīng)常有香客問我誓禁,道長,這世上最難降的妖魔是什么肾档? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任摹恰,我火速辦了婚禮,結(jié)果婚禮上怒见,老公的妹妹穿的比我還像新娘俗慈。我一直安慰自己,他們只是感情好遣耍,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布闺阱。 她就那樣靜靜地躺著,像睡著了一般舵变。 火紅的嫁衣襯著肌膚如雪酣溃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天棋傍,我揣著相機與錄音救拉,去河邊找鬼。 笑死瘫拣,一個胖子當著我的面吹牛亿絮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播麸拄,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼派昧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拢切?” 一聲冷哼從身側(cè)響起蒂萎,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎淮椰,沒想到半個月后五慈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡主穗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年泻拦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忽媒。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡争拐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晦雨,到底是詐尸還是另有隱情架曹,我是刑警寧澤隘冲,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站绑雄,受9級特大地震影響展辞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绳慎,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一纵竖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杏愤,春花似錦靡砌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至厕宗,卻和暖如春画舌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背已慢。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工曲聂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佑惠。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓朋腋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親膜楷。 傳聞我的和親對象是個殘疾皇子旭咽,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

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