Frida高階逆向-Hook Native(Java So)
阿新 • • 發佈:2021-06-11
Frida Hook Native
Frida Hook Java Jni
demo:
function hook_java() { Java.perform(function () { const myapp = Java.use('com.gdufs.xman.MyApp'); myapp.m.value = 1; console.log('m=', myapp.m.value); myapp.saveSN.implementation = function (s) { let result = this.saveSN(s); console.log('myapp.saveSN:', s, result); return result; } }) }
獲取模組基址,Hook匯出函式
demo:
function hook_native() { // 獲取模組基址 const my_jni = Module.findBaseAddress('libmyjni.so'); if (!my_jni) return; // 查詢 so 檔案的 匯出函式 地址 const addr_n2 = Module.findExportByName('libmyjni.so', 'n2'); console.log('my_jni: ', my_jni, 'addr_n2:', addr_n2); // 對函式地址進行Hook Interceptor.attach(addr_n2, { onEnter: function (arg) { console.log('addr_n2 onEnter :', arg[0], ptr(arg[1]).readCString(), ptr(arg[2]).readCString()) }, onLeave: function (retval) { } }) }
列舉模組的符號 Hook libart的一些函式
demo:
function hook_art() { // 查詢模組 const lib_art = Process.findModuleByName('libart.so'); // 列舉模組的符號 const symbols = lib_art.enumerateSymbols(); for (let symbol of symbols) { var name = symbol.name; if (name.indexOf("art") >= 0) { if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) { if (name.indexOf("GetStringUTFChars") >= 0) { console.log('開始 HOOK libart ', symbol.name); Interceptor.attach(symbol.address, { onEnter: function (arg) { // 列印呼叫棧 // console.log('GetStringUTFChars called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n'); }, onLeave: function (retval) { console.log('onLeave GetStringUTFChars:', ptr(retval).readCString()) } }) } else if (name.indexOf("FindClass") >= 0) { console.log('開始 HOOK libart ', symbol.name); Interceptor.attach(symbol.address, { onEnter: function (arg) { console.log('onEnter FindClass:', ptr(arg[1]).readCString()) }, onLeave: function (retval) { // console.log('onLeave FindClass:', ptr(retval).readCString()) } }) } else if (name.indexOf("GetStaticFieldID") >= 0) { console.log('開始 HOOK libart ', symbol.name); Interceptor.attach(symbol.address, { onEnter: function (arg) { console.log('onEnter GetStaticFieldID:', ptr(arg[2]).readCString(), ptr(arg[3]).readCString()) }, onLeave: function (retval) { // console.log('onLeave GetStaticFieldID:', ptr(retval).readCString()) } }) } else if (name.indexOf("SetStaticIntField") >= 0) { console.log('開始 HOOK libart ', symbol.name); Interceptor.attach(symbol.address, { onEnter: function (arg) { console.log('onEnter SetStaticIntField:', arg[3]) }, onLeave: function (retval) { // console.log('onLeave SetStaticIntField:', ptr(retval).readCString()) } }) } } } } }
列印呼叫棧
console.log('GetStringUTFChars called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
Hook libc的函式
demo:
function hook_libc() {
const strcmp = Module.findExportByName('libc.so', 'strcmp');
console.log('strcmp: ', strcmp);
Interceptor.attach(strcmp, {
onEnter: function (arg) {
let str2 = ptr(arg[1]).readCString();
if (str2 === 'EoPAoY62@ElRD') {
console.log('strcmp:', ptr(arg[0]).readCString(), str2);
}
},
onLeave: function (retval) {
}
})
}
Frida 的 File api 寫檔案
function write_data() {
const file = new File('/sdcard/reg.dat', 'w');
file.write('EoPAoY62@ElRD');
file.flush();
file.close()
}
把C函式定義為NativaFunction來寫檔案
demo:
// hook libc.so 的方式來寫檔案
function write_data_native() {
// 讀取lic的匯出函式地址
const addr_fopen = Module.findExportByName('libc.so', 'fopen');
const addr_fputs = Module.findExportByName('libc.so', 'fputs');
const addr_fclose = Module.findExportByName('libc.so', 'fclose');
console.log('fopen:', addr_fopen, 'fputs', addr_fputs, 'fclose', addr_fclose);
// 構建函式
const fopen = new NativeFunction(addr_fopen, 'pointer', ['pointer', 'pointer']);
const fputs = new NativeFunction(addr_fputs, 'int', ['pointer', 'pointer']);
const fclose = new NativeFunction(addr_fclose, 'int', ['pointer']);
// 申請記憶體空間
let file_name = Memory.allocUtf8String('/sdcard/reg.dat');
let model = Memory.allocUtf8String('w+');
let data = Memory.allocUtf8String('EoPAoY62@ElRD');
let file = fopen(file_name, model);
let ret = fputs(data, file);
console.log('fputs ret: ', ret);
fclose(file);
}