Android應(yīng)用逆向分析技術(shù)綜述_第1頁
Android應(yīng)用逆向分析技術(shù)綜述_第2頁
Android應(yīng)用逆向分析技術(shù)綜述_第3頁
Android應(yīng)用逆向分析技術(shù)綜述_第4頁
Android應(yīng)用逆向分析技術(shù)綜述_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、精選優(yōu)質(zhì)文檔-傾情為你奉上精選優(yōu)質(zhì)文檔-傾情為你奉上專心-專注-專業(yè)專心-專注-專業(yè)精選優(yōu)質(zhì)文檔-傾情為你奉上專心-專注-專業(yè)Android應(yīng)用逆向分析技術(shù)綜述Dex文件結(jié)構(gòu)Dex文件結(jié)構(gòu)1. 文件頭 DEX文件頭主要包括校驗(yàn)和以及其他結(jié)構(gòu)的偏移地址和長度信息。字段名稱偏移值長度描述magic0 x08Magic值,即魔數(shù)字段,格式如”dex/n035/0”,其中的035表示結(jié)構(gòu)的版本。checksum0 x84校驗(yàn)碼。signature0 xC20SHA-1簽名。file_size0 x204Dex文件的總長度。header_size0 x244文件頭長度,009版本=0 x5C,035版本

2、=0 x70。endian_tag0 x284標(biāo)識(shí)字節(jié)順序的常量,根據(jù)這個(gè)常量可以判斷文件是否交換了字節(jié)順序,缺省情況下=0 x。link_size0 x2C4連接段的大小,如果為0就表示是靜態(tài)連接。link_off0 x304連接段的開始位置,從本文件頭開始算起。如果連接段的大小為0,這里也是0。map_off0 x344map數(shù)據(jù)基地址。string_ids_size0 x384字符串列表的字符串個(gè)數(shù)。string_ids_off0 x3C4字符串列表表基地址。type_ids_size0 x404類型列表里類型個(gè)數(shù)。type_ids_off0 x444類型列表基地址。proto_ids_

3、size0 x484原型列表里原型個(gè)數(shù)。proto_ids_off0 x4C4原型列表基地址。field_ids_size0 x504字段列表里字段個(gè)數(shù)。field_ids_off0 x544字段列表基地址。method_ids_size0 x584方法列表里方法個(gè)數(shù)。method_ids_off0 x5C4方法列表基地址。class_defs_size0 x604類定義類表中類的個(gè)數(shù)。class_defs_off0 x644類定義列表基地址。data_size0 x684數(shù)據(jù)段的大小,必須以4字節(jié)對(duì)齊。data_off0 x6C4數(shù)據(jù)段基地址2. 魔數(shù)字段魔數(shù)字段,主要就是Dex文件的標(biāo)識(shí)符

4、,它占用4個(gè)字節(jié),在目前的源碼里是 “dexn”,它的作用主要是用來標(biāo)識(shí)dex文件的,比如有一個(gè)文件也以dex為后綴名,僅此并不會(huì)被認(rèn)為是Davlik虛擬機(jī)運(yùn)行的文件,還要判斷這 四個(gè)字節(jié)。另外Davlik虛擬機(jī)也有優(yōu)化的Dex,也是通過個(gè)字段來區(qū)分的,當(dāng)它是優(yōu)化的Dex文件時(shí),它的值就變成”deyn”了。根據(jù)這四個(gè)字 節(jié),就可以識(shí)別不同類型的Dex文件了。3. 檢驗(yàn)碼字段 主要用來檢查從這個(gè)字段開始到文件結(jié)尾,這段數(shù)據(jù)是否完整,有沒有人修改過,或者傳送過程中是否有出錯(cuò)等等。通常用來檢查數(shù)據(jù)是否完整的算法,有 CRC32、有SHA128等,但這里采用并不是這兩類,而采用一個(gè)比較特別的算法,叫做

5、adler32,這是在開源zlib里常用的算法,用來檢查文件 是否完整性。該算法由MarkAdler發(fā)明,其可靠程度跟CRC32差不多,不過還是弱一點(diǎn)點(diǎn),但它有一個(gè)很好的優(yōu)點(diǎn),就是使用軟件來計(jì)算檢驗(yàn)碼時(shí)比較 CRC32要快很多??梢夾ndroid系統(tǒng),就算法上就已經(jīng)為移動(dòng)設(shè)備進(jìn)行優(yōu)化了。SHA-1簽名字段dex文件頭里,前面已經(jīng)有了面有一個(gè)4字節(jié)的檢驗(yàn)字段碼了,為什么還會(huì)有SHA-1簽名字段呢?不是重復(fù)了嗎?可是仔細(xì)考慮一下,這樣設(shè)計(jì)自有道理。因 為dex文件一般都不是很小,簡單的應(yīng)用程序都有幾十K,這么多數(shù)據(jù)使用一個(gè)4字節(jié)的檢驗(yàn)碼,重復(fù)的機(jī)率還是有的,也就是說當(dāng)文件里的數(shù)據(jù)修改了,還是很 有

6、可能檢驗(yàn)不出來的。這時(shí)檢驗(yàn)碼就失去了作用,需要使用更加強(qiáng)大的檢驗(yàn)碼,這就是SHA-1。SHA-1校驗(yàn)碼有20個(gè)字節(jié),比前面的檢驗(yàn)碼多了16個(gè)字 節(jié),幾乎不會(huì)不同的文件計(jì)算出來的檢驗(yàn)是一樣的。設(shè)計(jì)兩個(gè)檢驗(yàn)碼的目的,就是先使用第一個(gè)檢驗(yàn)碼進(jìn)行快速檢查,這樣可以先把簡單出錯(cuò)的dex文件丟掉了, 接著再使用第二個(gè)復(fù)雜的檢驗(yàn)碼進(jìn)行復(fù)雜計(jì)算,驗(yàn)證文件是否完整,這樣確保執(zhí)行的文件完整和安全。 SHA(Secure Hash Algorithm, 安全散列算法)是美國國家安全局設(shè)計(jì),美國國家標(biāo)準(zhǔn)與技術(shù)研究院發(fā)布的一系列密碼散列函數(shù)。SHA-1看起來和MD5算法很像,也許是Ron Rivest在SHA-1的設(shè)計(jì)

7、中起了一定的作用。SHA-1的內(nèi)部比MD5更強(qiáng),其摘要比MD5的16字節(jié)長4個(gè)字節(jié),這個(gè)算法成功經(jīng)受了密碼分析專家 的攻擊,也因而受到密碼學(xué)界的廣泛推崇。這個(gè)算法在目前網(wǎng)絡(luò)上的簽名,BT軟件里就有大量使用,比如在BT里要計(jì)算是否同一個(gè)種子時(shí),就是利用文件的簽名 來判斷的。同一份8G的電影從幾千BT用戶那里下載,也不會(huì)出現(xiàn)錯(cuò)誤的數(shù)據(jù),導(dǎo)致電影不播放。map_off字段這個(gè)字段主要保存map開始位置,就是從文件頭開始到map數(shù)據(jù)的長度,通過這個(gè)索引就可以找到map數(shù)據(jù)。map的數(shù)據(jù)結(jié)構(gòu)如下:名稱大小說明size4字節(jié)map里項(xiàng)的個(gè)數(shù)list變長每一項(xiàng)定義為12字節(jié),項(xiàng)的個(gè)數(shù)由上面項(xiàng)大小決定。map

8、數(shù)據(jù)排列結(jié)構(gòu)定義如下:/*Direct-mapped map_list.*/typedef struct DexMapList u4 size; /* #of entries inlist */ DexMapItem list1; /* entries */DexMapList;每一個(gè)map項(xiàng)的結(jié)構(gòu)定義如下:/*Direct-mapped map_item.*/typedef struct DexMapItem u2 type; /* type code (seekDexType* above) */ u2 unused; u4 size; /* count of items ofthe in

9、dicated type */ u4 offset; /* file offset tothe start of data */DexMapItem;DexMapItem結(jié)構(gòu)定義每一項(xiàng)的數(shù)據(jù)意義:類型、類型個(gè)數(shù)、類型開始位置。其中的類型定義如下:/*map item type codes */enum kDexTypeHeaderItem = 0 x0000, kDexTypeStringIdItem = 0 x0001, kDexTypeTypeIdItem = 0 x0002, kDexTypeProtoIdItem = 0 x0003, kDexTypeFieldIdItem = 0 x

10、0004, kDexTypeMethodIdItem = 0 x0005, kDexTypeClassDefItem = 0 x0006, kDexTypeMapList = 0 x1000, kDexTypeTypeList = 0 x1001, kDexTypeAnnotationSetRefList = 0 x1002, kDexTypeAnnotationSetItem = 0 x1003, kDexTypeClassDataItem = 0 x2000, kDexTypeCodeItem = 0 x2001, kDexTypeStringDataItem = 0 x2002, kDe

11、xTypeDebugInfoItem = 0 x2003, kDexTypeAnnotationItem = 0 x2004, kDexTypeEncodedArrayItem = 0 x2005, kDexTypeAnnotationsDirectoryItem = 0 x2006,;從上面的類型可知,它包括了在dex文件里可能出現(xiàn)的所有類型??梢钥闯鲞@里的類型與文件頭里定義的類型有很多是一樣的,這里的類型其實(shí)就是文件頭里定義 的類型。其實(shí)這個(gè)map的數(shù)據(jù),就是頭里類型的重復(fù),完全是為了檢驗(yàn)作用而存在的。當(dāng)Android系統(tǒng)加載dex文件時(shí),如果比較文件頭類型個(gè)數(shù)與 map里類型不一致時(shí),就

12、會(huì)停止使用這個(gè)dex文件。string_ids_size/off字段這兩個(gè)字段主要用來標(biāo)識(shí)字符串資源。源程序編譯后,程序里用到的字符串都保存在這個(gè)數(shù)據(jù)段里,以便解釋執(zhí)行這個(gè)dex文件使用。其中包括調(diào)用庫函數(shù)里的類名稱描述,用于輸出顯示的字符串等。string_ids_size標(biāo)識(shí)了有多少個(gè)字符串,string_ids_off標(biāo)識(shí)字符串?dāng)?shù)據(jù)區(qū)的開始位置。字符串的存儲(chǔ)結(jié)構(gòu)如下:/* * Direct-mapped string_id_item. */typedef struct DexStringId u4 stringDataOff; /* file offset to string_data_

13、item */ DexStringId;可以看出這個(gè)數(shù)據(jù)區(qū)保存的只是字符串表的地址索引。如果要找到字符串的實(shí)際數(shù)據(jù),還需要通過個(gè)地址索引找到文件的相應(yīng)開始位置,然后才能得到字符串?dāng)?shù)據(jù)。 每一個(gè)字符串項(xiàng)的索引占用4個(gè)字節(jié),因此這個(gè)數(shù)據(jù)區(qū)的大小就為4*string_ids_size。實(shí)際數(shù)據(jù)區(qū)中的字符串采用UTF8格式保存。例如,如果dex文件使用16進(jìn)制顯示出來內(nèi)容如下:063c 696e 6974 3e00其實(shí)際數(shù)據(jù)則是”0”另外這段數(shù)據(jù)中不僅包括字符串的字符串的內(nèi)容和結(jié)束標(biāo)志,在最開頭的位置還標(biāo)明了字符串的長度。上例中第一個(gè)字節(jié)06就是表示這個(gè)字符串有6個(gè)字符。關(guān)于字符串的長度有兩點(diǎn)需要注意

14、的地方:1、關(guān)于長度的編碼格式dex文件里采用了變長方式表示字符串長度。一個(gè)字符串的長度可能是一個(gè)字節(jié)(小于256)或者4個(gè)字節(jié)(1G大小以上)。字符串的長度大多數(shù)都是小于 256個(gè)字節(jié),因此需要使用一種編碼,既可以表示一個(gè)字節(jié)的長度,也可以表示4個(gè)字節(jié)的長度,并且1個(gè)字節(jié)的長度占絕大多數(shù)。能滿足這種表示的編碼方式有 很多,但dex文件里采用的是uleb128方式。leb128編碼是一種變長編碼,每個(gè)字節(jié)采用位來表達(dá)原來的數(shù)據(jù),最高位用來表示是否有后繼字節(jié)。它的編碼算法如下:/* * Writes a 32-bit value in unsigned ULEB128 format. * Ret

15、urns the updated pointer. */DEX_INLINE u1* writeUnsignedLeb128(u1* ptr, u4 data) while (true) u1 out = data & 0 x7f; if (out != data) *ptr+ = out | 0 x80; data = 7; else *ptr+ = out; break; return ptr;它的解碼算法如下:/* * Reads an unsigned LEB128 value, updating the given pointer to point * just past the e

16、nd of the read value. This function tolerates * non-zero high-order bits in the fifth encoded byte. */DEX_INLINE int readUnsignedLeb128(const u1* pStream) const u1* ptr = *pStream; int result = *(ptr+); if (result 0 x7f) int cur = *(ptr+); result = (result & 0 x7f) | (cur & 0 x7f) 0 x7f) cur = *(ptr

17、+); result |= (cur & 0 x7f) 0 x7f) cur = *(ptr+); result |= (cur & 0 x7f) 0 x7f) /* * Note: We dont check to see if cur is out of * range here, meaning we tolerate garbage in the * high four-order bits. */ cur = *(ptr+); result |= cur 28; *pStream = ptr; return result;根據(jù)上面的算法分析上面例子字符串,取得第一個(gè)字節(jié)是06,最高位

18、為0,因此沒有后繼字節(jié),那么取出這個(gè)字節(jié)里7位有效數(shù)據(jù),就是6,也就是說這個(gè)字符串是6個(gè)字節(jié),但不包括結(jié)束字符“0”。2、關(guān)于長度的意義由于字符串內(nèi)容采用的是UTF-8格式編碼,表示一個(gè)字符的字節(jié)數(shù)是不定的。即有時(shí)是一個(gè)字節(jié)表示一個(gè)字符,有時(shí)是兩個(gè)、三個(gè)甚至四個(gè)字節(jié)表示一個(gè)字符。 而這里的長度代表的并不是整個(gè)字符串所占用的字節(jié)數(shù),表示這個(gè)字符串包含的字符個(gè)數(shù)。所以在讀取時(shí)需要注意,尤其是在包含中文字符時(shí),往往會(huì)因?yàn)樽x取的長 度不正確導(dǎo)致字符串被截?cái)唷6?. 簡介靜態(tài)分析是探索Android程序內(nèi)幕的一種最常見的方法,它與動(dòng)態(tài)調(diào)劑雙劍合璧,幫助分析人員解決分析時(shí)遇到的各種“疑難”問題。靜態(tài)分析

19、是指在不運(yùn)行的情況下,采用詞法分析、語法分析等各種技術(shù)手段對(duì)程序文件進(jìn)行掃描從而生成程序的反匯編代碼,然后閱讀反匯編代碼來掌握程序功能的一種技術(shù),它有兩種方法:一種方法是閱讀反匯編生成的Dalvik字節(jié)碼,可以用IDA Pro分析dex文件,或者使用文本編輯器閱讀baksmali反編譯生成的smali文件;另一種方法是閱讀反匯編生成的java源碼,可以使用dex2jar生成jar文件,然后再使用jd-gui閱讀jar文件的代碼。2. 快速定位Android程序的關(guān)鍵代碼特點(diǎn):1、每個(gè)apk文件中都包含有一個(gè)AndroidManifest.xml文件,它記錄著軟件的一些基本信息。2、一個(gè)Andr

20、oid程序由一個(gè)或多個(gè)Activity以及其它組成,每個(gè)Activity都是相同級(jí)別的,不同的Activity實(shí)現(xiàn)不同的功能。六種方法定位關(guān)鍵代碼:1、信息反饋發(fā):先運(yùn)行目標(biāo)程序,然后根據(jù)程序運(yùn)行時(shí)給出的反饋信息作為突破口尋找關(guān)鍵代碼。2、特征函數(shù)法:跟信息反饋法類似。3、順序查看發(fā):從軟件的啟動(dòng)代碼開始,逐行的向下分析,掌握軟件的執(zhí)行流程。4、代碼注入法:手動(dòng)修改apk文件的反匯編代碼,加入Log輸出,配合LogCat查看程序執(zhí)行到特定點(diǎn)時(shí)的狀態(tài)數(shù)據(jù)。5、棧跟蹤法:輸出運(yùn)行時(shí)的棧跟蹤信息,然后查看棧上的函數(shù)調(diào)用序列來理解方法的執(zhí)行流程。6、方法剖析:熱點(diǎn)分析和性能優(yōu)化。3. smali文件格

21、式每個(gè)smali文件都由若干條語句組成,所有的語句都遵循著一套語法規(guī)則。在smali 文件的頭3 行描述了當(dāng)前類的一些信息,格式如下:打開MainActivity.smali 文件,頭3 行代碼如下:smali文件中字段的聲明使用“.field”指令。字段有靜態(tài)字段與實(shí)例字段兩種。靜態(tài)字段的聲明格式如下:實(shí)例字段的聲明與靜態(tài)字段類似,只是少了static關(guān)鍵字,它的格式如下:smali 文件中方法的聲明使用“.method ”指令,方法有直接方法與虛方法兩種。直接方法的聲明格式如下:虛方法的聲明與直接方法相同,只是起始處的注釋為“virtual methods”,如果一個(gè)類實(shí)現(xiàn)了接口,會(huì)在sm

22、ali 文件中使用“.implements ”指令指出,相應(yīng)的格式聲明如下:注解的作用范圍可以是類、方法或字段。如果注解的作用范圍是類,“.annotation ”指令會(huì)直接定義在smali 文件中,如果是方法或字段,“.annotation ”指令則會(huì)包含在方法或字段定義中。例如:Android 程序中的類4.1 內(nèi)部類Java 語言允許在一個(gè)類的內(nèi)部定義另一個(gè)類,這種在類中定義的類被稱為內(nèi)部類(Inner Class)。內(nèi)部類可分為成員內(nèi)部類、靜態(tài)嵌套類、方法內(nèi)部類、匿名內(nèi)部類。在反編譯dex 文件的時(shí)候,會(huì)為每個(gè)類單獨(dú)生成了一個(gè) smali 文件,內(nèi)部類作為一個(gè)獨(dú)立的類,它也擁有自己獨(dú)立

23、的smali 文件,只是內(nèi)部類的文件名形式為“外部類$內(nèi)部類.smali ”,例如:4.2 監(jiān)聽器Android程序開發(fā)中大量使用到了監(jiān)聽器,如Button的點(diǎn)擊事件響應(yīng)OnClickListener、Button的長按事件響應(yīng)OnLongClickListener、ListView列表項(xiàng)的點(diǎn)擊事件響應(yīng) OnItemSelected-Listener等。實(shí)例源碼以及反編譯設(shè)置按鈕點(diǎn)擊事件監(jiān)聽器的代碼如下:在MainActivity$1.smali 文件的開頭使用了“.implements ”指令指定該類實(shí)現(xiàn)了按鈕點(diǎn)擊事件的監(jiān)聽器接口,因此,這個(gè)類實(shí)現(xiàn)了它的OnClick()方法,這也是我們?cè)诜?/p>

24、析程序時(shí)關(guān)心的地方。另外,程序中的注解與監(jiān)聽器的構(gòu)造函數(shù)都是編譯器為我們自己生成的,實(shí)際分析過程中不必關(guān)心。4.3 注解類注解是Java 的語言特性,在 Android的開發(fā)過程中也得到了廣泛的使用。Android系統(tǒng)中涉及到注解的包共有兩個(gè):一個(gè)是dalvik.annotation;另一個(gè)是 android.annotation。例如:除了SuppressLint與TargetApi注解,android.annotation 包還提供了SdkConstant與Widget兩個(gè)注解,這兩個(gè)注解在注釋中被標(biāo)記為“hide”,即在 SDK 中是不可見的。SdkConstant注解指定了SDK中可以被導(dǎo)出的常量字段值,Widget 注解指定了哪些類是 UI類,這兩個(gè)注解在分析Android程序時(shí)基本上碰不到,此處就不去探究了。4、自動(dòng)生成的類使用 Android SDK 默認(rèn)生成的工程會(huì)自動(dòng)添加一些類。例如:由于這些資源類都是R 類的內(nèi)部類,因此它們都會(huì)獨(dú)立生成一個(gè)類文件,在反編譯出的代碼中,可以發(fā)現(xiàn)有R.smali、R$attr.smali 、R$dimen.smali、R$drawable.smali、R$id.smali、R$layout.smali、R$menu.smali 、R$string.smali 、R$style.smali 等幾個(gè)文件。三、Li

溫馨提示

  • 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)論