Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

admin 2024年7月4日16:53:58评论71 views字数 2294阅读7分38秒阅读模式

1.前言

本文简单介绍一些so文件简单的内存dump和修复的一些流程,主要针对so脱壳中自解密的应对方案

2.实验

2.1 So固技术简要分析

我们在分析Android应用时,最后往往会分析到so层,而so层的防护手段有很多,一般分为有源保护和无源保护,有源保护分为自解密、混淆、源码VMP等,无源保护分为加壳、VMP保护。

自解密的有源保护

自解密保护往往是通过对函数或段进行加密,然后再加载SO文件,解密之前加密的函数和段,由于应用程序在运行后要解密相关的逻辑,所以往往只需要在SO文件运行后,进行Dump后,就可以获取解密后的逻辑,破解难度较低

2.2 实验样本分析

我们在分析so文件时,经常会遇到各种防护,最简单的一种防护就是自解密保护,一般这种通过对函数段进行加密,会对一些数据段加密处理,例如下面我们打开一个样本

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

我们可以很清晰的发现加密的函数datadiv_decode,在Android APP漏洞之战(13)——WebView漏洞详解介绍了很多的工具,包括一些手段,这里我们通过ctrl+s可以进一步查看程序的各部分

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

我们查看数据段,可以发现函数名等明显被加密了,很明显也是调用datadiv_decode函数进行处理的

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

针对这种情况,我们可以直接编写so dump脚本,在程序运行后这些函数自然就解密完成,然后我们进行dump内存中的so文件就可以得到一个解密后的so文件

2.3 so_dump脚本编写

so的dump脚本如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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文件需要进行修复

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

明显发现一些数据IDA没有识别出来,这是因为IDA是按照ELF文件的section进行识别,然后我们需要进行修复

还可以使用IDApython脚本,但需要知道起始地址和结束地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

1
2
3
4
5
sofixer  -s soruce.so -o fix.so -m 0x0 -d 
-s 待修复的so路徑
-o 修复后的so路徑
-m 內存dump的基地址(16位) 0xABC
-d 输出debug信息

然后打开修复后的so文件

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

此时一些的函数段已经修复完成,然后再次查看数据段部分

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

可以发现现在数据段加密部分全部已经解密完成,这里简单演示自解密so防护的dump和修复

当然感兴趣朋友自己也可以将dump和修复写成一个脚本,网上也有一些开源的脚本,如下所示:

https://github.com/lasting-yang/frida_dump

Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复

可以快速的进行dump和修复

3.总结

今天简单介绍了一下so加固中自解密加固方式的脱壳和修复技巧,后续将进一步讲解so加固的其他方式的应对方案,样本上传到知识星球,感兴趣朋友前往下载

- source:security-kitchen.com

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月4日16:53:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Android加壳与脱壳(10)—— (so脱壳)自解密的脱壳修复https://cn-sec.com/archives/2919347.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息