Android基於frida的脫殼


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

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

來導出OpenMemory里面的名稱

 

# 安卓七
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()

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

 

結束

來自猿人學 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM