欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]Ali 阿里聚安全加固的libdemolishdata.so格式分析及代码还原的一种方案

[原创]Ali 阿里聚安全加固的libdemolishdata.so格式分析及代码还原的一种方案

将apk上传到阿里云进行快速加固,下载下来可以发现最新的加固和参考资料(1)中的类似,libdemolishdata.so的位置放在了assets\ali中,不过格式不变。

但很可惜该资料中并没有给出将阿里云抽取到libdemolishdata.so二进制代码还原回dex的方法,修改代价高(伸手党做不成了),所以需要继续分析(本文在参考资料(1)的基础上分析,建议先阅读参考资料(1))。

想着动态调试太麻烦于是直接开始猜,用winhex打开libdemolishdata.so,如图:

可以发现位于0x10(表示由0x10-0x10+3构成的DWORD,下同),0x20,0x30的位置的内容恰好是fixfunc调用的内容。

那么可以推测0xC表示待修复方法个数。

用baksmali输出method(java -jar baksmali.jar list methods dex文件地址),可以发现0x18,0x28,0x38对应着三个被修改为"native"方法的methodIdx。

学习了参考资料(2)后,可以发现0x1c,0x2c,0x3c作为offset指向的内容恰好是DexCode格式,所以关键是修复codeoff。


又尝试上传了一个有multidex的apk,可以猜出libdemolishdata.so其他全部信息的含义(过程省略),如下(所有名称都是我为了方便随便命名的)

文件宏观组成如下

struct libDemolishData{

AliFixFuncInfo aliFixFuncInfos[dexNum];//每个AliFixFuncInfo对应一个dex的修复信息

AliCheckSumInfo aliCheckSumInfo[dexNum];//每个AliCheckSumInfo 对应一个dex的CheckSum

uint dexNum; //dex数量,如:有classes.dex和classes2.dex,则为2;只有classes.dex,则为1

};

AliCheckSumInfo的组成比较简单,如下(可能用于检验加固后的内容是否被修改)

struct AliCheckSumInfo{

uint multiDexId;//dex标识,0表示classes.dex,否则表示classes{$multiDexId}.dex,如2表示classes2.dex

uint checksum;//该dex的alder32,与DexHeader.checksum相同

uint hash;//该dexSha1的一部分,与DexHeader.signature的前4字节相同

};

AliFixFuncInfo则由三部分组成,如下

struct AliFixFuncInfo{

struct Header{

char magic[4];//魔数,恒为 <ali

uint multiDexId;//dex标识,0表示classes.dex,否则表示classes{$multiDexId}.dex,如2表示classes2.dex

uint dataLen;//这一AliFixFuncInfo的长度,可以借此定位下一个AliFixFuncInfo在哪

uint funcsNum;//需要修复的方法数

} header;

struct FixFunc{

uint id;//方法标志,同fixfunc调用的参数,如class调用 fixfunc(int[]{id1,id2,...}) 时,id1,id2,...就是这个id

uint multiDexId;//dex标识,0表示classes.dex,否则表示classes{$multiDexId}.dex,如2表示classes2.dex(表示似乎冗余了,为0x16对齐?)

uint methodIdx;//待修复方法的methodIdx,methodIdx含义见参考资料(2)

uint codeOffset;//指向待修复方法的真实DexCode信息,注意表示的是真实DexCode信息相对于当前AliFixFuncInfo的偏移,而并不完全相当于相对于文件头的偏移

} fixFuncs[funcsNum];

char realDexCodeInfo[dataLen-sizeof(header)-sizeof(fixFuncs)];

};


分析到这里可以说是很开心,以为只要在dex文件中找到codeOff改掉即可,然而codeOff是Uleb128类型的,这是一种变长类型,一旦改掉,需要修复很多偏移信息。

于是想到我们可以修改baksmali读取到的codeOff啊,再smali回去即可。

可以想象(伸手党放心,这部分附件有成品),先增加几个类,用于读取 libdemolishdata.so,在读取dex文件的函数中将 libdemolishdata.so 的内容复制在存储dex内容的byte[]末尾,然后修正读取到的accessFlag(去除native标记【0x100】),修正读取到的codeOff(获取到相对于当前AliFixFuncInfo的偏移后要加上AliFixFuncInfo相对于libdemolishdata.so文件头的偏移和前文中的byte[]中libdemolishdata.so信息的偏移),这样就可以了。


附件中modifiedJava.zip是修改后的java源代码(仅修改的部分,修改前的baksmali程序的java源代码可在github下载,编译采用javac -cp 编译好的.jar;. ***.java,然后将新生成的*.class用压缩软件复制到jar内对应目录即可);

bakdemolish-2.2.1.jar是修改编译后的成品(使用说明:

1.正常dex和修复后dex都用正常baksmali即可,不要用这个。

2.操作命令同正常baksmali,如java -jar bakdemolish-2.2.1.jar d classes.dex。

3.但须注意,将assets\ali(我获得的最新加固后文件)或lib\**\(参考资料(1)中加固后文件,2017.01)下的libdemolishdata.so、bakdemolish-2.2.1.jar、classes.dex文件放到相同文件夹下,并保证命令提示符当前目录也cd到这一目录时才能确保正常工作【其实就是libdemolishdata.so直接是用FileInputStream("libdemolishdata.so")取读的问题,没有测试其他情况】

4.dex文件名不能改【用来获取前文提到的multiDexId,如apk内是classes2.dex,就是classes2.dex】

5.dex可以直接解压获取,也可以用apktool d -s apk文件 获取)


有了这个工具,可以想象如下修复步骤(没有完全测试过)

1.apktool d -s apk文件

2.获得libdemolishdata.so后用bakdemolish-2.2.1.jar获得smali Code

3.适当修复,最简单的是将com\ali\fixHelper.smali中所有方法内容都删除,然后删除fixfunc方法的native属性,补上.locals 0,return-void,如下

.method public static fixfunc([IZ)V

.locals 0

return-void

.end method

也可以用一些规则匹配删除所有<clinit>中调用fixfunc的代码

注意处理后的文件仍有一些暗桩似乎和a/does/not/Exists*.smali有联系,可能需要处理

4.用smali-*.jar回编译

5.用apktool b <dir>生成新apk,签名


参考资料:

1.Caln  ali 加固(17年1月)逆向分析 http://bbs.pediy.com/thread-217235.htm

2.太尼玛菜了 Android Dex文件格式(一) http://www.cnblogs.com/dacainiao/p/6035274.html

            Android Dex文件格式(二) http://www.cnblogs.com/dacainiao/p/6036834.html

上传的附件 bakdemolish-2.2.1.jar
modifiedJava.zip

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功