應(yīng)用資源文件格式解析及阿里破解示例_第1頁
應(yīng)用資源文件格式解析及阿里破解示例_第2頁
應(yīng)用資源文件格式解析及阿里破解示例_第3頁
應(yīng)用資源文件格式解析及阿里破解示例_第4頁
應(yīng)用資源文件格式解析及阿里破解示例_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、應(yīng)用資源文件格式解析及阿里破解示例0x01 前言:目前大部份公司如阿里,騰訊,360等對apk資源保護的方法是通過自動化測試工具尋找一些異常的數(shù)據(jù)格式,安卓虛擬機及aapt對于這些異常的格式可以正常處理,而apktool工具處理分析時會出現(xiàn)異常。找到這些異常的數(shù)據(jù)格式后,利用改裝后的aapt工具,對apk打包時設(shè)置這些異常的格式,從而達到保護的作用。本文主要介紹應(yīng)用資源文件的格式,分析阿里的APK資源保護機制,給出了破解方法。0x02 arsc文件格式簡介我們知道一個APK文件結(jié)構(gòu)為:mete-INF存放簽名文件的目錄。res 存放了二進制編譯XML及圖片資源文件的目錄AndroidManif

2、est.xml 程序全局配置文件classes.dexDalvik字節(jié)碼resources.arsc編譯后的二進制資源文件Resources.arsc文件包含了二進制編譯的String, style等資源。Resources.arsc文件采用小端編碼方式(即低位在前,高位在后),Resources.arsc文件整體是由一系列的chunk構(gòu)成。Resources.arsc文件的整體可以用以下的這張圖來概述。在一個apk中,對應(yīng)chunck的數(shù)量一般有:ResTable(1個)ResStringPool(1個)ResTable_Package(1n個)RES_TABLE_TYPE_SPEC(1n個

3、)RES_TABLE_TYPE(1n個)。我們也可以通過模版來分析Resources.arsc文件,這樣更直接一點。我們用010 edit(010edit的下載地址見參考資料4)打開Resources.arsc文件在template菜單->open打開ARSCTemplate.bt模版(下載地址見參考資料5),點擊template菜單->Run即可看到Resources.arsc文件的相關(guān)結(jié)構(gòu)。具體示意如下圖下面我們以helloworld.apk做為實例,幫助大家理解一下Resources.arsc文件的結(jié)構(gòu)。helloworld.apk大家可以通過參考資料6所標注的地址下載。Re

4、sources.arsc整體是由一系列的chunk構(gòu)成。每一個chunk均包含如下結(jié)構(gòu)的ResChunk_header,用來描述這個chunk的基本信息。struct ResChunk_header        enum                 RES_NULL_TYPE        &

5、#160;      = 0x0000,          RES_STRING_POOL_TYPE        = 0x0001,          RES_TABLE_TYPE      

6、60;       = 0x0002,          RES_XML_TYPE                = 0x0003,          RES_XML_F

7、IRST_CHUNK_TYPE    = 0x0100,          RES_XML_START_NAMESPACE_TYPE= 0x0100,          RES_XML_END_NAMESPACE_TYPE  = 0x0101,        

8、  RES_XML_START_ELEMENT_TYPE  = 0x0102,          RES_XML_END_ELEMENT_TYPE    = 0x0103,          RES_XML_CDATA_TYPE       

9、0;  = 0x0104,          RES_XML_LAST_CHUNK_TYPE     = 0x017f,          RES_XML_RESOURCE_MAP_TYPE   = 0x0180,       &

10、#160;  RES_TABLE_PACKAGE_TYPE      = 0x0200,          RES_TABLE_TYPE_TYPE         = 0x0201,          RES_TABLE_TYPE

11、_SPEC_TYPE    = 0x0202            /當(dāng)前這個chunk的類型      uint16_t type;      /當(dāng)前這個chunk的頭部大小      uint16_t headerSize;     &

12、#160;/當(dāng)前這個chunk的大小      uint32_t size;  1. ResTable_header(資源索引表頭)Resources.arsc文件的第一個結(jié)構(gòu)是資源索引表頭。其結(jié)構(gòu)如下,描述了Resources.arsc文件的大小和資源包數(shù)量。struct ResTable_header          struct ResChunk_header header;   

13、0;  uint32_t packageCount;   /被編譯的資源包的個數(shù);下圖藍色加亮部分標出亮helloworld.apk的Resources.arsc文件的資源索引表頭的內(nèi)容。ResTable_header的chunk(02 00 0C 00 6895 01 00 01 000000)02 00 位置0 1,共2字節(jié),表示該chunk的類型,值為0x0002表示類型為RES_TABLE_TYPE. 0C 00 位置2 3 ,共2字節(jié),表示該chunk類型的頭長度,值為0x000C表示該類型的頭長度為12字節(jié)長度。6895 01 00

14、位置47,共4字節(jié),表示該chunk的總長度,值為0x00019568表示該chunk的總長度(這里為整個文件的大小)為103784字節(jié)長度。01 000000被編譯的資源包的個數(shù),這里只有一個。2. ResStringPool_header(全局字符串資源)緊跟著資源索引表頭部的是資源項的全局字符串資源,這個字符串資源池包含了所有的在資源包里面所定義的資源項的全局字符串,包括android工程中部分資源文件名(如res/drawable-hdpi/ic_launcher.png,res/layout/activity_main.xml等)及res/values/strings.xml中的字符

15、串值(如helloworld,hello world,Settings)全局字符串資源頭部的結(jié)構(gòu)如下。struct ResStringPool_header        struct ResChunk_header header;      uint32_t stringCount;      /字符串的數(shù)量uint32_t styleCount;    

16、 /字符串樣式的數(shù)量uint32_t flags;      /字符串的屬性,可取值包括0x000(UTF-16),0x001(字符串經(jīng)過排序)、0X100(UTF-8)和他們的組合值uint32_t stringsStart;/字符串內(nèi)容塊相對于其頭部的距離      uint32_t stylesStart;/字符串樣式塊相對于其頭部的距離       01 00 位置0 1,共2字節(jié),表示該

17、chunk的類型,值為0x0001 表示類型為RES_STRING_POOL_TYPE. 1C 00 位置2 3 ,共2字節(jié),表示該chunk類型的頭長度,值為0x001C表示該類型的頭長度為28字節(jié)長度。A491 0000位置47,共4字節(jié),表示該chunk的總長度,值為0x000091A4表示該chunk的總長度為37284字節(jié)長度。E1 03 00 00位置0x08 0x0B,共4字節(jié),表示字符串?dāng)?shù)量,值為0x000003E1表示字符串?dāng)?shù)量為993個。00000000位置 0x0C 0x0F,共4字節(jié),表示字符串樣式數(shù)量,值為0x00000000表示字符串樣式數(shù)量為0個。00 01 00

18、 00位置 0x10 0x13字符串的屬性,共4字節(jié),值為0x00000100表示字符串采用utf-8編碼。A00F 00 00 0x14 0x17共4字節(jié),值為0x00000FA0表示字符串內(nèi)容相對于RES_STRING_POOL頭部的偏移為4000。實際的文件偏移地址為0x00000FA0+0x0C=0x0FAC。000000000x18 0x1B共4字節(jié),值為0表示字符串樣式內(nèi)容相對于RES_STRING_POOL頭部的偏移為0。3. ResTable_package結(jié)構(gòu)說明struct ResTable_package struct ResChunk_he

19、ader header;/包的ID,等于Package Id,一般用戶包的值Package Id為0X7F,系統(tǒng)資源包的Package Id為0X01。uint32_t id;/包名稱char16_t name128;    /類型字符串資源池相對頭部的偏移    uint32_t typeStrings;    /最后一個導(dǎo)出的Public類型字符串在類型字符串資源池中的索引,目前這個值設(shè)置為類型字符串資

20、源池的元素個數(shù)。    uint32_t lastPublicType;    /資源項名稱字符串相對頭部的偏移    uint32_t keyStrings;     /最后一個導(dǎo)出的Public資源項名稱字符串在資源項名稱字符串資源池中的索引,目前這個值設(shè)置為資源項名稱字符串資源池的元素個數(shù)。     uint32_t lastPublicKe

21、y; typeStrings資源類型字符串存儲類型資源的類型字符串一般有animator、anim、color、drawable、layout、menu、raw、string和xml。keyStrings(資源項名稱字符串)一般儲存資源文件XML內(nèi)容的鍵名的名稱字符串,以helloworld的strings.xml為例,鍵名“app_name”,”hello_world”, “action_settings”做為資源項名稱字符串存儲在該區(qū)域。ResTable_package包頭解析00 02 1C 01 B8 03 01 00 為ResTable_package的頭ResChunk_

22、header。7F 00 0000值 0x0000007f 為包的ID63 00位置 0x91bc 0x92bb為包名com.example.helloworld1C 0100 00位置 0x9bc 0x92bf 包的typeStrings(類型字符串資源池相對頭部的偏移)0C 000000typeStrings(類型字符串資源池)的字符串個數(shù),0x00000c個C8 01 00 00keyStrings(資源項名稱字符串)相對頭部的偏移,在文件中的起始位置為 0x01C8+0x91b0=0x9378E0 01 00 00keyStrings(資源項名稱字符串資源池)的字符串元素個數(shù)。ResT

23、able_package包后是typeString和keyStrings的內(nèi)容。位置 0x92CC 0x9377為typeString的內(nèi)容typeString的格式與RES_STRING_POOL_TYPE一致。01 00 位置0 1,共2字節(jié),表示該chunk的類型,值為0x0001 表示類型為RES_STRING_POOL_TYPE. 1C 00 位置2 3 ,共2字節(jié),表示該chunk類型的頭長度,值為0x001C表示該類型的頭長度為28字節(jié)長度。Ac00 0000位置47,共4字節(jié),表示該chunk的總長度,值為0x000000ac表示該chunk的總長度為172字節(jié)長度。0c 00

24、 00 00位置0x08 0x0B,共4字節(jié),表示字符串?dāng)?shù)量,值為0x0000000c表示字符串?dāng)?shù)量為12個。00000000位置 0x0C 0x0F,共4字節(jié),表示字符串樣式數(shù)量,值為0x00000000表示字符串樣式數(shù)量為0個。00 01 00 00位置 0x10 0x13字符串的屬性,共4字節(jié),值為0x00000100表示字符串采用utf-8編碼。4c00 00 00 0x14 0x17共4字節(jié),值為0x0000004c表示字符串內(nèi)容相對于RES_STRING_POOL頭部的偏移為72。實際的文件偏移地址為0x0000004c+0x92cc=0x9318。000000000x18 0x1

25、B共4字節(jié),值為0表示字符串樣式內(nèi)容相對于RES_STRING_POOL頭部的偏移為0。typeString后是12個偏移數(shù)組,每個數(shù)組元素都記錄了typeString字符串?dāng)?shù)組的相對偏移位置(即相對于0x9318的位置)。Offset0=0x0000;Offset1=0x0007;Offset2=0x0012;Offset3=0x001B;Offset4=0x0022;Offset5=0x0027;Offset6=0x002e;Offset7=0x0036;Offset8=0x003e;Offset9=0x0048;Offset10=0x0051;Offset11=0x0059;偏移數(shù)組后面

26、是typeString的字符串的數(shù)組內(nèi)容。typeString0 =”attr”typeString1 =”drawable”typeString2 =”layout”typeString3 =”anim”typeString4 =”id”typeString5 =”bool”typeString6 =”color”typeString7 =”dimen”typeString8 =”integer”typeString9 =”string”typeString10 =”style”typeString11 =”menu”位置 0x9378 0xd617 為keyString的內(nèi)容, keySt

27、ring的格式與RES_STRING_POOL_TYPE一致。這里不再介紹。4. ResTable_typeSpec結(jié)構(gòu)說明struct ResTable_typeSpec      struct ResChunk_header header;     /標識資源的Type ID,Type ID是指資源的類型ID。資源的類型有animator、anim、color、drawable、layout、menu、raw、string和xml等

28、等若干種,每一種都會被賦予一個ID。     uint8_t id;     /保留,始終為0     uint8_t res0;     /保留,始終為0     uint16_t res1;     /等于本類型的資源項個數(shù),指名稱相同的資源項的個數(shù)。 &

29、#160;   uint32_t entryCount; 下圖藍色加亮部分為helloworld.apk的第一個ResTable_typeSpec內(nèi)容02 02 10 00 C8 01 00 00為ResTable_typeSpec的頭ResChunk_header。01 id,是指資源的類型ID,對照的typeString的字符串值,我們可以知道該ID的指是attr00 res000 00res100 0000 6EentryCount,共有0X6E個相同的名稱類型ID。ResTable_typeSpec后面緊跟著的是一個大小為entryCo

30、unt的uint32_t數(shù)組文件位置 0xd6280xd7df 為entry數(shù)組。5. ResTable_type結(jié)構(gòu)說明struct ResTable_type      struct ResChunk_header header;      enum          NO_ENTRY = 0xFFFFFFFF &

31、#160;        /標識資源的Type ID     uint8_t id;     /保留,始終為0     uint8_t res0;     /保留,始終為0     uint16_t res1; 

32、0;   /等于本類型的資源項個數(shù),指名稱相同的資源項的個數(shù)。     uint32_t entryCount;     /等于資源項數(shù)據(jù)塊相對頭部的偏移值。     uint32_t entriesStart;     /指向一個ResTable_config,用來描述配置信息,地區(qū),語言,分辨率等    

33、 ResTable_config config; 下圖藍色加亮部分為helloworld.apk的第一個ResTable_type內(nèi)容01 02 38 00 E8 0E 00 00ResTable_type的ResChunk_header01標識資源的Type ID 0x7f01000000 res000 00 res16E 00 0000 等于本類型的資源項個數(shù),指名稱相同的資源項的個數(shù)。F0 01 00 00 ResTable_entry數(shù)據(jù)的起始位置0xD7E0+0x01F0=0xD9D06. ResTable_entry結(jié)構(gòu)說明stru

34、ct ResTable_entry      /表示資源項頭部大小。     uint16_t size;      enum          /如果flags此位為1,則ResTable_entry后跟隨ResTable_map數(shù)組,為0則跟隨一個Res_value。   &

35、#160;     FLAG_COMPLEX = 0x0001,         /如果此位為1,這個一個被引用的資源項         FLAG_PUBLIC = 0x0002          /資源項標志位 

36、60;   uint16_t flags;     /資源項名稱在資源項名稱字符串資源池的索引     struct ResStringPool_ref key; structResStringPool_refuint32_t ident;下圖藍色加亮部分為的ResTable_entry10 00 長度01 00 如果flags此位為1,則ResTable_entry后跟隨ResTable_map數(shù)組00 000000 key

37、 資源項名稱在資源項名稱字符串資源池的索引“windowActionBar”7. ResTable_map_entry結(jié)構(gòu)說明struct ResTable_map_entry : public ResTable_entry      /指向父ResTable_map_entry的資源ID,如果沒有父ResTable_map_entry,則等于0。     ResTable_ref parent;   &#

38、160; /等于后面ResTable_map的數(shù)量     uint32_t count; ResTable_map的結(jié)構(gòu)如下:struct ResTable_map      /bag資源項ID     ResTable_ref name;     /bag資源項值     Res_va

39、lue value; struct Res_value      /Res_value頭部大小     uint16_t size;     /保留,始終為0     uint8_t res0;      enum     

40、60;    TYPE_NULL = 0x00,         TYPE_REFERENCE = 0x01,         TYPE_ATTRIBUTE = 0x02,         TYPE_STRING =&#

41、160;0x03,         TYPE_FLOAT = 0x04,         TYPE_DIMENSION = 0x05,         TYPE_FRACTION = 0x06,      &#

42、160;  TYPE_FIRST_INT = 0x10,         TYPE_INT_DEC = 0x10,         TYPE_INT_HEX = 0x11,         TYPE_INT_BOOLEAN = 0

43、x12,         TYPE_FIRST_COLOR_INT = 0x1c,         TYPE_INT_COLOR_ARGB8 = 0x1c,         TYPE_INT_COLOR_ARGB8 = 0x1c,   &#

44、160;     TYPE_INT_COLOR_RGB8 = 0x1d,         TYPE_INT_COLOR_ARGB4 = 0x1e,         TYPE_INT_COLOR_RGB4 = 0x1f,       

45、0; TYPE_LAST_COLOR_INT = 0x1f,         TYPE_LAST_INT = 0x1f          /數(shù)據(jù)的類型,可以從上面的枚舉類型中獲取     uint8_t dataType;      /數(shù)據(jù)

46、對應(yīng)的索引     uint32_t data; 下圖為ResTable_map_entry的舉例,本例中0xd9d80xd9ec為ResTable_map_entry的數(shù)據(jù)。00 00 00 00 如果沒有父ResTable_map_entry,則等于001 00 00 00 后面ResTable_map的數(shù)量,這里為1個。當(dāng)count不為0時,ResTable_map_entry其后跟隨則count個ResTable_map類型的數(shù)組。00 0000 01 ResTable_ref 的name;08 00 長度

47、00 res0;10 TYPE_INT_DEC08 00 0000值為8我們打開helloworld源碼工程生成的R.java可以發(fā)現(xiàn)windowActionBar確實編碼為0x7f010000,值為8,表示隱藏。為了完整地介紹ResTable_entry,我們最后列出,flags最后一位為0時的ResTable_entry的例子。80 00 ResTable_entry結(jié)構(gòu)的長度00 00flags此位為0,則ResTable_entry后跟隨Res_value84 00 0000值為0x84, key 資源項名稱在keyStrings(資源項名稱字符串資源池)的索引“abc_ic_clea

48、r”08 00 Res_value長度00 res0;03TYPE_STRING18 00 0000值為24,查找全局STRING POOL數(shù)組,可以查到“res/drawable/abc_ic_clear.xml”0x03阿里釘釘介紹:阿里釘釘是阿里旗下的面向企業(yè)的im工具。最近一年發(fā)展迅猛,是阿里移動產(chǎn)品除了支付寶,阿里旺旺以外用戶量較大的移動產(chǎn)品。目前阿里釘釘安卓版最新版本為2.7.6 我們可以到阿里釘釘官網(wǎng)利用apktool進行反編譯,我們會發(fā)現(xiàn)apktool報錯。0x04阿里資源文件分析我們打開阿里釘釘?shù)膔esources.arsc文件看一下,究竟里面是什么鬼。把下載后的dingta

49、lk.apk改名為dingtalk.zip并解壓到dingtalk目錄用ultraedit或010Edit打開dingtalk目錄下的resources.arsc文件釘釘?shù)膔esources.arsc文件內(nèi)容如下圖所示:紅線后面的010000是我們本次報錯的地方。而01001c00是我們預(yù)期想讀到的數(shù)據(jù)。第一部分為RES_TABLE_TYPE的chunk(02 00 14 00 DC CC 0F 00 01 00 0000)02 00 位置0 1,表示該chunk的類型,共2字節(jié),值為0x0001 表示類型為RES_TABLE_TYPE. 14 00 位置2 3 ,表示該chunk類型的頭長度

50、,共2字節(jié),值為0x0014表示該類型的頭長度為20字節(jié)長度。我們從上面的標注知道RES_TABLE_TYPE的chunk的長度應(yīng)固定為0x0C,阿里釘釘這里的chunk長度應(yīng)為異常。DC CC 0F 00位置47,表示該chunk的總長度,共4字節(jié),值為0x000FCCDC表示該chunk的總長度(這里為整個文件的大小)為1035484字節(jié)長度。第二部分為多出來。00 000000 01 00 0000(見紅線標注)有點像是RES_NULL_TYPE的chunk。第三部分為RES_STRING_POOL_TYPE的chunk(01 00 1C 00 EC 0D 06 00 )01 00 位置0 1,表示該chunk的類型,共2字節(jié),值為0x0001 表示類型為RES_STRING_POOL_TYPE. 1C 00 位置2 3 ,表示該chunk類型的頭長度,共2字節(jié),值為0x001C表示該類型的頭長度為28字節(jié)長度。EC 0D 06 0

溫馨提示

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

最新文檔

評論

0/150

提交評論