-
-
[讨论]com.qzone_6.8.1.288_95 的ARSC的处理
-
发表于: 2016-9-20 15:49 3361
-
鬼哥给的一个样本,"com.qzone_6.8.1.288_95"看名字也知道大概是谁家的app了.
直接反编译,ARSC报错,分析了下,用的手段还是很巧妙的,给个赞.
简单说下:
在ResTable_type节点中有一组ResTable_entry的entrys,是根据entriesStart+entryOffsets偏移来读取的.
一般情况下,都想到的是增大偏移,中间填空或脏数据,但这次qzone不这么干,他用的是减少偏移.简单来说就是,如果是按线性向下解析,会出现当前读取数据位置>entriesStart+entryOffsets[index]的偏移,这种情况下,需要回退,而不是skip跳过.针对apktool这种线性向下解析的是很大的挫败.目前还没发现apktool有回溯的流程处理.
因为apktool的命名没有按源码命名,在apktool处理位置是readTableType中的readEntry
-------------
然后猜想怎么实现,
既然是回溯偏移,那就说明前面肯定有部分数据重用了.想了想只能是ResTable_entry中数据复用.
看下修复打印:
W: readTableType entry 323 , Backward offset 64 bytes
W: readTableType entry 324 , Backward offset 64 bytes
W: readTableType entry 325 , Backward offset 64 bytes
W: readTableType entry 326 , Backward offset 64 bytes
W: readTableType entry 327 , Backward offset 64 bytes
W: readTableType entry 328 , Backward offset 64 bytes
W: readTableType entry 329 , Backward offset 64 bytes
W: readTableType entry 330 , Backward offset 64 bytes
W: readTableType entry 331 , Backward offset 64 bytes
W: readTableType entry 332 , Backward offset 64 bytes
W: readTableType entry 333 , Backward offset 64 bytes
W: readTableType entry 334 , Backward offset 64 bytes
W: readTableType entry 335 , Backward offset 64 bytes
W: readTableType entry 336 , Backward offset 64 bytes
W: readTableType entry 337 , Backward offset 64 bytes
W: readTableType entry 338 , Backward offset 64 bytes
W: readTableType entry 339 , Backward offset 64 bytes
W: readTableType entry 340 , Backward offset 64 bytes
.....
回溯从来没出现过index=0的情况.出现回溯都是连续的,那说明后一个ResTable_entry回溯到了前一个ResTable_entry的尾部
看ResTable_entry的尾部是一个不定式的结构,根据flags来判断是ResTable_map_entry还是Res_value
简单比较这两个结构,会发现Res_value不太可能,Res_value的size是8byte,而ResTable_map_entry中有一个ResTable_map类型的valueMaps数组,所有及有可能是在valueMaps中填充了可覆盖的数据
单纯这样猜测没用,还是继续打印看qzone用的那个来的实在
W: readTableType entry 323 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 324 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 325 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 326 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 327 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 328 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 329 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 330 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 331 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 332 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
看来猜的没错.....
后面就不分析了,要构造出可复用的ResTable_entry尾部,还的继续对着ResTable_entry和ResTable_map,Res_value结构来看,只能说qzone还是很用心的去构造了这个可复用的尾部,至于复用的尾部在前一个entry用没用到,这个到不重要了.....
直接反编译,ARSC报错,分析了下,用的手段还是很巧妙的,给个赞.
简单说下:
在ResTable_type节点中有一组ResTable_entry的entrys,是根据entriesStart+entryOffsets偏移来读取的.
一般情况下,都想到的是增大偏移,中间填空或脏数据,但这次qzone不这么干,他用的是减少偏移.简单来说就是,如果是按线性向下解析,会出现当前读取数据位置>entriesStart+entryOffsets[index]的偏移,这种情况下,需要回退,而不是skip跳过.针对apktool这种线性向下解析的是很大的挫败.目前还没发现apktool有回溯的流程处理.
因为apktool的命名没有按源码命名,在apktool处理位置是readTableType中的readEntry
-------------
然后猜想怎么实现,
既然是回溯偏移,那就说明前面肯定有部分数据重用了.想了想只能是ResTable_entry中数据复用.
看下修复打印:
W: readTableType entry 323 , Backward offset 64 bytes
W: readTableType entry 324 , Backward offset 64 bytes
W: readTableType entry 325 , Backward offset 64 bytes
W: readTableType entry 326 , Backward offset 64 bytes
W: readTableType entry 327 , Backward offset 64 bytes
W: readTableType entry 328 , Backward offset 64 bytes
W: readTableType entry 329 , Backward offset 64 bytes
W: readTableType entry 330 , Backward offset 64 bytes
W: readTableType entry 331 , Backward offset 64 bytes
W: readTableType entry 332 , Backward offset 64 bytes
W: readTableType entry 333 , Backward offset 64 bytes
W: readTableType entry 334 , Backward offset 64 bytes
W: readTableType entry 335 , Backward offset 64 bytes
W: readTableType entry 336 , Backward offset 64 bytes
W: readTableType entry 337 , Backward offset 64 bytes
W: readTableType entry 338 , Backward offset 64 bytes
W: readTableType entry 339 , Backward offset 64 bytes
W: readTableType entry 340 , Backward offset 64 bytes
.....
回溯从来没出现过index=0的情况.出现回溯都是连续的,那说明后一个ResTable_entry回溯到了前一个ResTable_entry的尾部
看ResTable_entry的尾部是一个不定式的结构,根据flags来判断是ResTable_map_entry还是Res_value
简单比较这两个结构,会发现Res_value不太可能,Res_value的size是8byte,而ResTable_map_entry中有一个ResTable_map类型的valueMaps数组,所有及有可能是在valueMaps中填充了可覆盖的数据
单纯这样猜测没用,还是继续打印看qzone用的那个来的实在
W: readTableType entry 323 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 324 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 325 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 326 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 327 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 328 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 329 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 330 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 331 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
W: readTableType entry 332 , Backward offset 64 bytes
W: flags is ENTRY_FLAG_COMPLEX : true
看来猜的没错.....
后面就不分析了,要构造出可复用的ResTable_entry尾部,还的继续对着ResTable_entry和ResTable_map,Res_value结构来看,只能说qzone还是很用心的去构造了这个可复用的尾部,至于复用的尾部在前一个entry用没用到,这个到不重要了.....
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: