Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复
1.前言
本文简单介绍一些so文件简单的内存dump和修复的一些流程,主要针对so脱壳中自解密的应对方案
2.实验
2.1 So固技术简要分析
我们在分析Android应用时,最后往往会分析到so层,而so层的防护手段有很多,一般分为有源保护和无源保护,有源保护分为自解密、混淆、源码VMP等,无源保护分为加壳、VMP保护。
自解密的有源保护
自解密保护往往是通过对函数或段进行加密,然后再加载SO文件,解密之前加密的函数和段,由于应用程序在运行后要解密相关的逻辑,所以往往只需要在SO文件运行后,进行Dump后,就可以获取解密后的逻辑,破解难度较低
2.2 实验样本分析
我们在分析so文件时,经常会遇到各种防护,最简单的一种防护就是自解密保护,一般这种通过对函数段进行加密,会对一些数据段加密处理,例如下面我们打开一个样本
我们可以很清晰的发现加密的函数datadiv_decode,在Android APP漏洞之战(13)——WebView漏洞详解介绍了很多的工具,包括一些手段,这里我们通过ctrl+s
可以进一步查看程序的各部分
我们查看数据段,可以发现函数名等明显被加密了,很明显也是调用datadiv_decode函数进行处理的
针对这种情况,我们可以直接编写so dump脚本,在程序运行后这些函数自然就解密完成,然后我们进行dump内存中的so文件就可以得到一个解密后的so文件
2.3 so_dump脚本编写
so的dump脚本如下所示:
function so_dump(so_name){
Java.perform(function(){
var module = Process.getModuleByName(so_name);
console.log("[name]:",module.name);
console.log("[base]:",module.base);
console.log("[size]:",module.size);
console.log("[path]:",module.path);
var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
var dir = currentApplication.getApplicationContext().getFilesDir().getPath();
var path = dir + "/" + module.name +"_"+module.base + "_" + module.size + ".so";
var file = new File(path,"wb");
if(file){
Memory.protect(module.base,module.size,'rwx');
var buffer = module.base.readByteArray(module.size);
file.write(buffer);
file.flush();
file.close();
console.log("[dump success:]"+path);
}
})
}
就是从内存中搜索目标的so文件,然后进行dump,此时往往加密的函数都进行解密了
然后此时我们使用frida注入该脚本,就可以dump下内存中的so文件,再次打开,发现一些段丢失,这是因为内存中的so文件需要进行修复
明显发现一些数据IDA没有识别出来,这是因为IDA是按照ELF文件的section进行识别,然后我们需要进行修复
还可以使用IDApython脚本,但需要知道起始地址和结束地址:
import idaapi
start_address = 0x0000007DB078B000
end_address = 0x0000007DB08DE000
data_length = end_address - start_address
fp = open('E:\path.so', 'wb')
cur = 0
towrite = 0x100000
while cur < data_length:
if data_length - cur < 0x100000:
towrite = data_length - cur
data = idaapi.dbg_read_memory(start_address + cur, towrite)
fp.write(data)
cur = cur + towrite
fp.close()
2.4 So文件的修复
这里可以使用网上的开源工具SoFixer:https://github.com/F8LEFT/SoFixer
sofixer -s soruce.so -o fix.so -m 0x0 -d
-s 待修复的so路徑
-o 修复后的so路徑
-m 內存dump的基地址(16位) 0xABC
-d 输出debug信息
然后打开修复后的so文件
此时一些的函数段已经修复完成,然后再次查看数据段部分
可以发现现在数据段加密部分全部已经解密完成,这里简单演示自解密so防护的dump和修复
当然感兴趣朋友自己也可以将dump和修复写成一个脚本,网上也有一些开源的脚本,如下所示:
https://github.com/lasting-yang/frida_dump
可以快速的进行dump和修复
3.总结
今天简单介绍了一下so加固中自解密加固方式的脱壳和修复技巧,后续将进一步讲解so加固的其他方式的应对方案,样本上传到知识星球,感兴趣朋友前往下载