Android基于frida的脱壳

主要是要拿到安卓/data/lib/下的一个叫做libart.so

然后使用命令nm libart.so |grep OpenMemory

来导出OpenMemory里面的名称

Android基于frida的脱壳

 

# 安卓七
open_memory_7=‘_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_‘
#安卓九
open_memory_9=‘_ZN3art7DexFile10OpenMemoryERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEjPNS_6MemMapEPS7_‘

 将此代码放到hook frida代码中

import frida
import sys

package=‘com.iCitySuzhou.suzhou001‘

def on_message(message, data):
if message[‘type‘] == ‘send‘:
print("[*]{0}".format(message[‘payload‘]))
else:
print(message)
# a安卓七
open_memory_7=‘_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_‘
#安卓九
open_memory_9=‘_ZN3art7DexFile10OpenMemoryERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEjPNS_6MemMapEPS7_‘

#OpenMemory在libart.so中,在/data/lib/下 art是虚拟机
# Hook OpenMemory 导出方法名
# 用 nm libart.so |grep OpenMemory 查看导出导OpenMemory方法名
#OpenMemroy的第一个参数是dex文件,在内存的起始位置
#根据dex文件格式,从起始位置开始 第32个字节 是该dex文件的大小
# 知道dex起始位置和整个文件的大小,只是要把这段内存dump出来即可
# 实用与安卓 6 7 8 9
src="""
var openMemory_address=Module.findExportByName(‘libart.so‘,‘_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_‘);

Interceptor.attach(openMemory_address,{
onEnter: function(args){

//dex文件的起始位置
var dex_begin_address=args[1]
//dex文件的前八个字节是magic字段
//打印magic(会显示dex 035) 三个字符 可以验证是否未dex文件
console.log(‘magic:‘+Memory.readUtf8String(dex_begin_address))
// 把地址转换成整型 再加32
//因为dex文件的第三十二个字节处存放的dex文件的大小
var address=parseInt(dex_begin_address,16)+0x20

//把address地址指向的内存值读出来,该值就是dex的文件大小
//ptr(address)转换的原因是frida只接受NativePointer类型指针
var dex_size=Memory.readInt(ptr(address))
console.log(‘dex_size:‘+dex_size)

//frida写文件,把内存中的数据写到本地
var timestamp=new Date().getTime();

var file=new File(‘/data/data/%s/‘+timestamp+‘.dex‘,‘wb‘)

//Memory.readByteArray(begin,length)
//把内存的数据读出来,从begin开始,取length长度
file.write(Memory.readByteArray(dex_begin_address,dex_size))
file.flush()
file.close()

send(‘dex begin address:‘+parseInt(dex_begin_address,16))
send(‘dex file size:‘+dex_size)


},
onLeave: function(retval){
if (retval.toInt32()>0){}
}

});

"""%(package)

print(‘dex 导出目录为:/data/data/%s‘%(package))

deveice = frida.get_usb_device()

pid = deveice.spawn([package])

process = deveice.attach(pid)

# 创建运行脚本
script = process.create_script(src)
# 输入打印,写死
script.on(‘message‘, on_message)
print(‘[*] Running CTF‘)
# 写死
script.load()
# 重启程序
deveice.resume(pid)
# 写死
sys.stdin.read()

Android基于frida的脱壳

砸壳后的dex文件在/data/data里面

 

Android基于frida的脱壳结束

来自猿人学 

Android基于frida的脱壳

上一篇:App控件定位


下一篇:手机号码验证