-
-
[原创]基于frida框架的脱壳工具frida-unpack的使用心得
-
发表于:
2020-5-16 12:41
7245
-
[原创]基于frida框架的脱壳工具frida-unpack的使用心得
一、引言
第一次发帖,不周之处,还请原谅与指正。
众所周知,frida是一款用于hook的优秀工具,其实就是python下的一个包。由于frida本身只是一个注入方式,所以如果要对目标对象--移动设备进行注入操作,就一定要在对应的终端上安装相应的用于监听注入的服务器,也就是frida-server,当然,两方的版本也要保持一致。然后,对安卓hook来说,其对应着一款可以破壳的工具,即frida-unpack。
frida-unpack的详情-->https://github.com/dstmath/frida-unpack
利用它,能对一些app壳进行去除,达到取到源码的目的。
二、使用方法
1、搭建frida环境。由于frida-unpack是基于frida的,所以前提必须具备frida环境。电脑端:安装frida包和工具,这里使用python3.7,装frida包和工具:pip install frida---pip install frida-tools-->装好后我的是对应frida版本是12.8.20,移动设备端:安装frida-server服务器,装frida-server要找到移动设备对应的架构下载,这里使用模拟器x86-android7下好后解压push到设备的/data/local/tmp下。
2、启动frida-server服务器,到/data/local/tmp下执行./frida-server启动服务器,注意如果出现warnning可以尝试更换安卓版本(否则可能会出现time out)。
3、检查设备连接,执行adb devices可查看连接设备。
4、端口转发,执行adb forward tcp:27042 tcp:27042---adb forward tcp:27043 tcp:27043。
5、找到对应移动设备的OpenMemory的导出名称,可以通过将移动设备下/system/lib/libart.so pull到电脑,然后用IDA打开到Export那里查找,形如:_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS10OatDexFileEPS9。
6、找到app包名,可以通过反编译等方式找到。
7、执行frida-unpack脚本,如介绍所示,有js版本和python版本,这里使用python版本:
#-*- coding:utf-8 -*-
# coding=utf-8
import frida
import sys
def on_message(message, data):
base = message['payload']['base']
size = int(message['payload']['size'])
print hex(base),size
# print session
# dex_bytes = session.read_bytes(base, size)
# f = open("1.dex","wb")
# f.write(dex_bytes)
# f.close()
# 9.0 arm 需要拦截 _ZN3art13DexFileLoader10OpenCommonEPKhjS2_jRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPKNS_10OatDexFileEbbPS9_NS3_10unique_ptrINS_16DexFileContainerENS3_14default_deleteISH_EEEEPNS0_12VerifyResultE
# 7.0 arm:_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_
package = sys.argv[1]
print "dex 导出目录为: /data/data/%s"%(package)
device = frida.get_usb_device()
pid = device.spawn(package)
session = device.attach(pid)
src = """
Interceptor.attach(Module.findExportByName("libart.so", "_ZN3art13DexFileLoader10OpenCommonEPKhjS2_jRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPKNS_10OatDexFileEbbPS9_NS3_10unique_ptrINS_16DexFileContainerENS3_14default_deleteISH_EEEEPNS0_12VerifyResultE"), {
onEnter: function (args) {
var begin = args[1]
console.log("magic : " + Memory.readUtf8String(begin))
var address = parseInt(begin,16) + 0x20
var dex_size = Memory.readInt(ptr(address))
console.log("dex_size :" + dex_size)
var file = new File("/data/data/%s/" + dex_size + ".dex", "wb")
file.write(Memory.readByteArray(begin, dex_size))
file.flush()
file.close()
var send_data = {}
send_data.base = parseInt(begin,16)
send_data.size = dex_size
send(send_data)
},
onLeave: function (retval) {
if (retval.toInt32() > 0) {
}
}
});
"""%(package)
script = session.create_script(src)
script.on("message" , on_message)
script.load()
device.resume(pid)
sys.stdin.read()
把里面的package和导出名称替换执行即可
注意,这里如果是模拟器要把get_usb_device()改为get_remote_device()(否则可能会出现time out和device not found),效果:
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法