android apk 防止反編譯技術(shù)第二篇-運行時修改Dalvik指令

上一篇我們講了apk防止反編譯技術(shù)中的加殼技術(shù),如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372。接下來我們將介紹另一種防止apk反編譯的技術(shù)-運行時修改字節(jié)碼。這種方法是在工作中在實現(xiàn)app wrapping時佑吝,看到國外的一篇關(guān)于android安全的介紹實現(xiàn)的并且獨創(chuàng)损谦。下面我們來介紹一下這種方法。

我們知道apk生成后所有的java生成的class文件都被dx命令整合成了一個classes.dex文件球及,當(dāng)apk運行時dalvik虛擬機加載classes.dex文件并且用dexopt命令進(jìn)行進(jìn)一步的優(yōu)化成odex文件。我們的方法就是在這個過程中修改dalvik指令來達(dá)到我們的目的呻疹。

一吃引、dex文件格式

dex的文件格式通常有7個主要部分和數(shù)據(jù)區(qū)組成,格式如下:

header部分記錄了主要的信息其他的部分只是索引刽锤,索引的內(nèi)容存在data區(qū)域镊尺。

Header部分結(jié)構(gòu)如下:

字段名稱

偏移值

長度

描述

magic

0x0

8

'Magic'值,即魔數(shù)字段并思,格式如”dex/n035/0”庐氮,其中的035表示結(jié)構(gòu)的版本。

checksum

0x8

4

校驗碼宋彼。

signature

0xC

20

SHA-1簽名弄砍。

file_size

0x20

4

Dex文件的總長度。

header_size

0x24

4

文件頭長度输涕,009版本=0x5C,035版本=0x70音婶。

endian_tag

0x28

4

標(biāo)識字節(jié)順序的常量,根據(jù)這個常量可以判斷文件是否交換了字節(jié)順序,缺省情況下=0x78563412。

link_size

0x2C

4

連接段的大小莱坎,如果為0就表示是靜態(tài)連接衣式。

link_off

0x30

4

連接段的開始位置,從本文件頭開始算起檐什。如果連接段的大小為0碴卧,這里也是0。

map_off

0x34

4

map數(shù)據(jù)基地址乃正。

string_ids_size

0x38

4

字符串列表的字符串個數(shù)住册。

string_ids_off

0x3C

4

字符串列表表基地址。

type_ids_size

0x40

4

類型列表里類型個數(shù)烫葬。

type_ids_off

0x44

4

類型列表基地址界弧。

proto_ids_size

0x48

4

原型列表里原型個數(shù)凡蜻。

proto_ids_off

0x4C

4

原型列表基地址。

field_ids_size

0x50

4

字段列表里字段個數(shù)垢箕。

field_ids_off

0x54

4

字段列表基地址划栓。

method_ids_size

0x58

4

方法列表里方法個數(shù)。

method_ids_off

0x5C

4

方法列表基地址条获。

class_defs_size

0x60

4

類定義類表中類的個數(shù)忠荞。

class_defs_off

0x64

4

類定義列表基地址。

data_size

0x68

4

數(shù)據(jù)段的大小帅掘,必須以4字節(jié)對齊癣朗。

data_off

0x6C

4

數(shù)據(jù)段基地址

dex與class文件相比的一個優(yōu)勢副砍,就是將所有的常量字符串集統(tǒng)一管理起來了披粟,這樣就可以減少冗余祝钢,最終的dex文件size也能變小一些。詳細(xì)的dex文件介紹就不說了吱窝,有興趣的可以查看android源碼dalvik/docs目錄下的dex-format.html文件有詳細(xì)介紹讥邻。不過我記得在android4.0版本后就沒有了這個文件。

根據(jù)上面的dex文件的格式結(jié)構(gòu)院峡,dalvik虛擬機運行dex文件執(zhí)行的字節(jié)碼就存在method_ids區(qū)域里面兴使。我們查看dalvik虛擬機源碼會有一個

struct DexCode {

u2registersSize;

u2insSize;

u2outsSize;

u2triesSize;

u4debugInfoOff;/* file offset to debug info stream */

u4insnsSize;/* size of the insns array, in u2 units */

u2insns[1];

/* followed by optional u2 padding */

/* followed by try_item[triesSize] */

/* followed by uleb128 handlersSize */

/* followed by catch_handler_item[handlersSize] */

};

這樣一個結(jié)構(gòu),這里的insns數(shù)組存放的就是dalvik的字節(jié)碼照激。我們只要定位到相關(guān)類方法的DexCode數(shù)據(jù)段发魄,即可通過修改insns數(shù)組,從而實現(xiàn)我們的目的俩垃。

二励幼、odex文件格式

apk安裝或啟動時,會通過dexopt來將dex生成優(yōu)化的odex文件吆寨。過程是將apk中的classes.dex解壓后赏淌,用dexopt處理并保存為/data/dalvik-cache/data@app@-X.apk@classes.dex文件。

odex文件結(jié)構(gòu)如下:

從上圖中我們發(fā)現(xiàn)dex文件作為優(yōu)化后的odex的一部分啄清,我們只需要從odex中找出dex的部分即可以了。

三俺孙、方法實現(xiàn)

要實現(xiàn)修改字節(jié)碼辣卒,就需要先定位到想要修改得代碼的位置,這就需要先解析dex文件睛榄。dex文件的解析在dalvik源碼的dexDump.cpp給出了我們具體的實現(xiàn)荣茫,根據(jù)它的實現(xiàn)我們可以查找我們需要的類及方法。具體實現(xiàn)步驟如下:

(1)找到我們apk生成的odex文件场靴,獲得odex文件在內(nèi)存中的映射地址和大小啡莉。實現(xiàn)代碼如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23void*base?=?NULL;

intmodule_size?=?0;

charfilename[512];

//?simple?test?code??here!

for(inti=0;?i<2;?i++){

sprintf(filename,"/data/dalvik-cache/data@app@%s-%d.apk@classes.dex","com.android.dex",?i+1);

base?=?get_module_base(-1,?filename);//獲得odex文件在內(nèi)存中的映射地址

if(base?!=?NULL){

break;

}

}

module_size?=?get_module_size(-1,?filename);//獲得odex文件大小

(2)知道dex文件在odex中的偏移港准,以便解析dex文件。代碼如下:

?

1

2

3

4

5

6

7

8

9

10

11//?search?dex?from?odex

void*dexBase?=?searchDexStart(base);

if(checkDexMagic(dexBase)?==false){

ALOGE("Error!?invalid?dex?format?at:?%p",?dexBase);

return;

}

(3)找到dex偏移以后就可以解析dex文件咧欣,從而查找我們要進(jìn)行替換的方法所在的類浅缸,然后在該類中找到該方法并返回該方法對應(yīng)的DexCode結(jié)構(gòu)體。函數(shù)實現(xiàn)如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19staticconstDexCode?*dexFindClassMethod(DexFile?*dexFile,constchar*clazz,constchar*method)

{

DexClassData*?classData?=?dexFindClassData(dexFile,?clazz);

if(classData?==?NULL)returnNULL;

constDexCode*?code?=?dexFindMethodInsns(dexFile,?classData,?method);

if(code?!=?NULL)?{

dumpDexCode(code);

}

returncode;

}

(4)找到DexCode后就可以進(jìn)行指令替換了魄咕。實現(xiàn)如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27constDexCode??*code?=

dexFindClassMethod(&gDexFile,"Lcom/android/dex/myclass;","setflagHidden");

constDexCode*code2?=

dexFindClassMethod(&gDexFile,"Lcom/android/dex/myclass;","setflag");

//?remap!!!!

if(mprotect(base,?module_size,?PROT_READ?|?PROT_WRITE?|?PROT_EXEC)?==?0){

DexCode?*pCode?=?(DexCode?*)code2;

//?Modify!

pCode->registersSize?=?code->registersSize;

for(u4?k=0;?kinsnsSize;?k++){

pCode->insns[k]?=?code->insns[k];

}

mprotect(base,?module_size,?PROT_READ?|?PROT_EXEC);

}

注意:由于是在運行時修改的dalvik指令衩椒,這是進(jìn)程的內(nèi)存映射為只讀的,所以需要調(diào)用mprotect函數(shù)將只讀改為讀寫才能進(jìn)行指令的修改

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哮兰,一起剝皮案震驚了整個濱河市毛萌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喝滞,老刑警劉巖阁将,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異右遭,居然都是意外死亡做盅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門狸演,熙熙樓的掌柜王于貴愁眉苦臉地迎上來言蛇,“玉大人,你說我怎么就攤上這事宵距±吧校” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵满哪,是天一觀的道長婿斥。 經(jīng)常有香客問我,道長哨鸭,這世上最難降的妖魔是什么民宿? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮像鸡,結(jié)果婚禮上活鹰,老公的妹妹穿的比我還像新娘。我一直安慰自己只估,他們只是感情好志群,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛔钙,像睡著了一般锌云。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吁脱,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天桑涎,我揣著相機與錄音彬向,去河邊找鬼。 笑死攻冷,一個胖子當(dāng)著我的面吹牛娃胆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讲衫,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼缕棵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涉兽?” 一聲冷哼從身側(cè)響起招驴,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枷畏,沒想到半個月后别厘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡拥诡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年触趴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渴肉。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡冗懦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仇祭,到底是詐尸還是另有隱情披蕉,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布乌奇,位于F島的核電站没讲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏礁苗。R本人自食惡果不足惜爬凑,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望试伙。 院中可真熱鬧嘁信,春花似錦、人聲如沸疏叨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽考廉。三九已至,卻和暖如春携御,著一層夾襖步出監(jiān)牢的瞬間昌粤,已是汗流浹背既绕。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涮坐,地道東北人凄贩。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像袱讹,于是被迫代替她去往敵國和親疲扎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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