最右so层OLLVM字符串混淆还原

1 背景

OLLVM(Obfuscator-LLVM)是瑞士西部应用科技大学安全实验室于2010年6月份发起的一个项目,该项目旨在提供一套开源的针对LLVM的代码混淆工具,通过代码混淆和防篡改来提高软件安全性。github上地址是https://github.com/obfuscator-llvm/obfuscator,只不过仅更新到4.0版本,2017年开始就没在更新。

本文使用到如下工具及软件:010 Editor、IDA Pro、4.8.10版本的最右APK

2 分析过程

2.1 静态分析so文件

2.1.1 IDA静态分析so文件

首先,解压apk文件,提取出lib目录下的libnet_crypto.so文件并用IDA打开,待其加载完成后查看一下字符串窗口的.data区,发现基本都是混淆加密的,如图1所示。

图1 发现经过加密后的字符串

在Exports中搜索JNI_OnLoad函数,查看伪代码未发现混淆处理,导入jni.h头文件后修改变量类型和名称,最终得到图2中JNI_OnLoad的代码。

图2 找到JNI_OnLoad中的RegisterNatives函数

双击RegisterNatives函数的第三个参数off_17D010,进入.data区,如图3所示。

图3 查看对应关系

常规思路是应该会出现Java层方法、签名和so层方法的对应关系,结果翻车了。
接下来调转思路,尝试还原被OLLVM加密混淆的字符串信息

2.1.2 010 Editor静态分析so文件

libnet_crypto.so文件拖进010 Editor中,主要分析数据区域。第一个是程序头,在这里无需过多关注,第二个和第三个Loadable Segment才是是关注重点,第二个是只读的,那么根据so文件需要对字符串进行加解密的过程,因此可以判断IDA编译出的混淆字符串属于第三个区域,如图4所示。

图4 找到加载段的读写区

然而,这部分的数据p_data是被混淆过的,如图5所示。

图5 发现被混淆过的数据p_data

此处灵光一闪,对于这个so的还原,就需要dump出解密后的数据,将数据复制到原加密数据位置,这样就完成对字符串解密。
结合so文件的加载过程,dump的位置可能在JNI_onloadinitinit_array,这就需要尝试了。

2.2 动态调试so文件

2.2.1 IDA动态调试so文件

动态调试,老套路了,依次按下列命令执行即可

./as -p 10001
adb forward tcp:10001 tcp:10001
adb shell am start -D -n cn.xiaochuankeji.tieba/cn.xiaochuankeji.tieba.ui.base.SplashActivity
打开IDA,填写主机号127.0.0.1,端口号10001,选择进程,双击进来,勾选三项

好巧不巧,在ctrl+s并搜索libnet_crypto.so,发现so文件已经被加载进去了😄😄😄,如图6所示。

图6 发现libnet_crypto.so文件

那就这样吧,直接搜索dump内存中解密的字符串数据。依次点击File->script command,然后输入下列命令,替换初始地址和结束地址。

1
2
3
4
5
6
7
8
static main(void) {
auto fp, dexAddress, end, size;
dexAddress = 0xC3B74000;
end = 0xC3B76000;
fp = fopen("D:\\tmp\\tmp\\libnet_crypto_dumpdata.so", "wb");
for ( ; dexAddress < end; dexAddress++ )
fputc(Byte(dexAddress), fp);
}

2.2.2 010 Editor分析dump出来的so文件

使用010 Editor打开libnet_crypto_dumpdata.so文件,发现里面的字符串都是解密的,如图7所示。

图7 发现解密后的字符串

libnet_crypto.so中的.data区中存放加密数据,可以与libnet_crypto_dumpdata.so文件对比一下。
因为libnet_crypto_dumpdata.so是从内存中dump出来的,地址应该等于libnet_crypto.so中的基地址+偏移量,所以两文件前六行基本一致。第37BF列均为固定值,第048C列内容一样

图8 libnet_crypto.so的.data区的前6行

复制libnet_crypto_dumpdata.so文件中解密后的数据,即0070h到10DFh,然后将数据粘贴到libnet_crypto.so中的.data区的对应位置处,即光标放到17C070h处,粘贴即可,如图9所示。

图9 找到修改位置

2.3 字符串还原成功

最后,打开IDA查看修复后的so文件中RegisterNatives的Java层方法、签名和so层方法的对应关系,如图10所示。

图10 成功还原字符串

3 总结

本文中的方法仅适用在内存中解密状态的情况,如果是在使用时解密,解密后再清除,需要使用动态调试。

4 参考文献

[1]https://mp.weixin.qq.com/s/TfF-xcqH--9Hv5JQ-LI3dQ


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。

×

喜欢就点赞,疼爱就打赏