function writeSomething(path, contents) { var fopen_addr = Module.findExportByName("libc.so", "fopen"); var fputs_addr = Module.findExportByName("libc.so", "fputs"); var fclose_addr = Module.findExportByName("libc.so", "fclose");
var fopen = new NativeFunction(fopen_addr, "pointer", ["pointer", "pointer"]) var fputs = new NativeFunction(fputs_addr, "int", ["pointer", "pointer"]) var fclose = new NativeFunction(fclose_addr, "int", ["pointer"])
//console.log(path,contents)
var fileName = Memory.allocUtf8String(path); var mode = Memory.allocUtf8String("a+");
var fp = fopen(fileName, mode);
var contentHello = Memory.allocUtf8String(contents); var ret = fputs(contentHello, fp)
fclose(fp); } // 枚举出所有导出函数和内部符号,找到关键函数存在的so,动态注册无效,名称和native可以完全不一样 function traceNativeExport(){
var modules = Process.enumerateModules(); for(var i = 0;i<modules.length;i++){ var module = modules[i];
if(module.name.indexOf("libssl.so")<0){ continue; } // 枚举so所有导出表 var exports = module.enumerateExports(); for(var j = 0;j<exports.length;j++){ //console.log("module name is =>",module.name," symbol name is =>",exports[j].name) //var path = "/sdcard/Download/so/"+module.name+".txt" // 通过objection -g com.roysue.httpsocket explore 中env拿到的filesDirectory地址 //var path = "/data/data/com.roysue.d0so2/cache/"+module.name+".txt" //writeSomething(path,"type: "+exports[j].type+" function name :"+exports[j].name+" address : "+exports[j].address+" offset => 0x"+(exports[j].address - module[i].address)+"\n") // 把所有包含SSL_write的函数全部hook上 if(exports[j].name.indexOf("SSL_write")>=0){ attach(exports[j].name,exports[j].address); } // if(exports[j].name.indexOf("set")>=0){ // attach(exports[j].name,exports[j].address); // } // if(exports[j].name.indexOf("send")>=0){ // attach(exports[j].name,exports[j].address); // } // if(exports[j].name.indexOf("recv")>=0){ // attach(exports[j].name,exports[j].address); // }
},onLeave:function(retval){ //console.log("retval is => ",retval) } })
}
// 枚举符号表 function traceNativeSymbol(){ var modules = Process.enumerateModules(); for(var i = 0;i<modules.length;i++){ var module = modules[i]; // console.log(JSON.stringify(modules)) if(module.name.indexOf("linker64")<0){ continue; }
var exports = module.enumerateSymbols(); console.log(JSON.stringify(exports)) for(var j = 0;j<exports.length;j++){ if(exports[j] == null){ continue; } console.log("module name is =>",module.name," symbol name is =>",exports[j].name) var path = "/data/data/com.roysue.d0so2/cache/"+module.name+"Symbol.txt" writeSomething(path,"type: "+exports[j].type+" function name :"+exports[j].name+" address : "+exports[j].address+" offset => 0x"+(exports[j].address - module[i].address)+"\n") } } }
function main(){ console.log("Entering main") traceNativeExport(); //traceNativeSymbol();
function writeSomething(path, contents) { var fopen_addr = Module.findExportByName("libc.so", "fopen"); var fputs_addr = Module.findExportByName("libc.so", "fputs"); var fclose_addr = Module.findExportByName("libc.so", "fclose");
var fopen = new NativeFunction(fopen_addr, "pointer", ["pointer", "pointer"]) var fputs = new NativeFunction(fputs_addr, "int", ["pointer", "pointer"]) var fclose = new NativeFunction(fclose_addr, "int", ["pointer"])
//console.log(path,contents)
var fileName = Memory.allocUtf8String(path); var mode = Memory.allocUtf8String("a+");
var fp = fopen(fileName, mode);
var contentHello = Memory.allocUtf8String(contents); var ret = fputs(contentHello, fp)
fclose(fp); }
function traceNativeExport(){
var modules = Process.enumerateModules(); for(var i = 0;i<modules.length;i++){ var module = modules[i];
if(module.name.indexOf("libc.so")<0){ continue; }
var exports = module.enumerateExports(); for(var j = 0;j<exports.length;j++){ //console.log("module name is =>",module.name," symbol name is =>",exports[j].name) //var path = "/sdcard/Download/so/"+module.name+".txt" // var path = "/data/data/com.roysue.d0so2/cache/"+module.name+".txt" // writeSomething(path,"type: "+exports[j].type+" function name :"+exports[j].name+" address : "+exports[j].address+" offset => 0x"+ ( exports[j].address.sub(modules[i].base) )+"\n") // if(exports[j].name.indexOf("strto")>=0)continue; // if(exports[j].name.indexOf("strco")>=0)continue; // if(exports[j].name.indexOf("_l")>=0)continue; // if(exports[j].name.indexOf("pthread")>=0)continue; // if(exports[j].name.indexOf("socket")>=0){ // fopen fputs fputc fclose // attach(exports[j].name,exports[j].address); // } // 过反调试,一般反调试都有单独创建线程 if(exports[j].name.indexOf("pthread_create")>=0){ attach(exports[j].name,exports[j].address); } // if(exports[j].name.indexOf("read")>=0){ // man read // attach(exports[j].name,exports[j].address); // } // if(exports[j].name.indexOf("write")>=0){ // attach(exports[j].name,exports[j].address); // } // if(exports[j].name.indexOf("send")>=0){ // attach(exports[j].name,exports[j].address); // } // if(exports[j].name.indexOf("recv")>=0){ // attach(exports[j].name,exports[j].address); // }
var exports = module.enumerateSymbols(); // console.log(JSON.stringify(exports)) for(var j = 0;j<exports.length;j++){ // console.log("module name is =>",module.name," symbol name is =>",exports[j].name) var path = "/data/data/com.roysue.d0so2/cache/"+module.name+"Symbol.txt" writeSomething(path,"type: "+exports[j].type+" function name :"+exports[j].name+" address : "+exports[j].address+" offset => 0x"+ ( exports[j].address.sub(modules[i].base) )+"\n")
} } }
function main(){ console.log("Entering main") traceNativeExport(); // traceNativeSymbol();
function hook_native(){ var libnative_addr = Module.findBaseAddress('libnative-lib.so'); console.log("libnative_addr is => ",libnative_addr) var stringfromJNI3 = libnative_addr.add(0xf454); console.log("stringfromJNI3 address is =>",stringfromJNI3);
var stringfromJNI3_2 = Module.findExportByName('libnative-lib.so', "_Z14stringFromJNI3P7_JNIEnvP7_jclassP8_jstring") console.log("stringfromJNI3_2 address is =>",stringfromJNI3_2);
在hook_RegisterNatives方法中添加 if(name.indexOf("method01")>=0){ //hookmethod(fnPtr_ptr); //replacehook(fnPtr_ptr); method01addr = fnPtr_ptr; }else if (name.indexOf("method02")>=0){ method02addr = fnPtr_ptr; method02 = new NativeFunction(method02addr,'pointer',['pointer','pointer','pointer']); }else{ continue; } 新增invokemethod01 function invokemethod01(contents){ console.log("ENV=>",ENV) console.log("JCLZ=>",JCLZ); console.log("method01_addr is =>",method01addr) var method01 = new NativeFunction(method01addr,'pointer',['pointer','pointer','pointer']); var NewStringUTF = new NativeFunction(addrNewStringUTF,'pointer',['pointer','pointer']) var result = null; Java.perform(function(){ console.log("Java.vm.getEnv()",Java.vm.getEnv()) var JSTRING = NewStringUTF(Java.vm.getEnv(),Memory.allocUtf8String(contents)) result = method01(Java.vm.getEnv(),JSTRING,JSTRING); console.log("result is =>",result) console.log("result is ",Java.vm.getEnv().getStringUtfChars(result, null).readCString()) result = Java.vm.getEnv().getStringUtfChars(result, null).readCString(); }) return result; } 新增invokemethod02 function invokemethod02(contents){ var result = null; Java.perform(function(){ var JSTRING = NewStringUTF(Java.vm.getEnv(),Memory.allocUtf8String(contents)) result = method02(Java.vm.getEnv(),JSTRING,JSTRING); result = Java.vm.getEnv().getStringUtfChars(result, null).readCString(); }) return result; }
Java.perform(function () { Java.choose("com.xiaojianbang.app.MainActivity", { onMatch: function (instanse) { MainActivity = instanse; console.log("found instance => ", MainActivity); }, onComplete: function () { console.log("search completed!") } }) }) function showToast(string) { Java.perform(function () { // UI thread 注入 var Toast = Java.use('android.widget.Toast'); var currentApplication = Java.use('android.app.ActivityThread').currentApplication(); var context = currentApplication.getApplicationContext(); // 在线程上运行指定的函数 Java.scheduleOnMainThread(function () { Toast.makeText(context, string, Toast.LENGTH_LONG.value).show(); }) }) } function invokeNormal() { Java.perform(function () {
var javaString = Java.use("java.lang.String") // 静态内部函数 var MoneyInnerClass = Java.use("com.xiaojianbang.app.Money$innerClass").$new(javaString.$new("J"), 666).outPrint(); console.log("result =>", MoneyInnerClass) showToast(javaString.$new(MoneyInnerClass)) }) }
frida -UF -l hookxjb.js
[Pixel::HookTestDemo]-> result => 内部类被调用J: 666
构造实例方法
1 2 3 4 5 6 7 8 9 10 11
case R.id.gouzao /*{ENCODED_INT: 2131165257}*/: if (money == null) { money = new Money("美元", 1000); } toastPrint("money: " + money.getInfo()); toastPrint(Utils.getMoney().getInfo()); toastPrint(new Money().name()); public String name() { return "my name is xiaojianbang"; }
frida -UF -l hookxjb.js
invokeInit()
1 2 3 4 5 6 7
function invokeInit() { Java.perform(function () { var javaString = Java.use("java.lang.String") var MoneyName = Java.use("com.xiaojianbang.app.Money").$new().name(); showToast(javaString.$new(MoneyName)) }) }
重载方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
case R.id.chongzai /*{ENCODED_INT: 2131165233}*/: toastPrint(Utils.test(666)); toastPrint(Utils.test()); toastPrint(Utils.test(new Money("港币", 7000))); toastPrint(new Money() { /* class com.xiaojianbang.app.MainActivity.AnonymousClass1 */
android hooking list class_methods com.xiaojianbang.app.Utils
1 2 3 4 5 6 7
function invokeOverload() { Java.perform(function () { // 静态重载方法 var result = Java.use("com.xiaojianbang.app.Utils").test(666); console.log("invoke overload result is => ", result); }) }
public static String test(Money money) { return money.getInfo(); } public String myPrint(String[] strArr) { StringBuilder sb = new StringBuilder(); for (String str : strArr) { sb.append(str); } return sb.toString(); }
frida -UF -l hookxjb.js
invokeOverload()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
function invokeObject() { Java.perform(function () { var javaString = Java.use("java.lang.String") var newMoney = Java.use("com.xiaojianbang.app.Money").$new(javaString.$new("dollar"), 200); var result = Java.use("com.xiaojianbang.app.Utils").test(newMoney); showToast(javaString.$new(result))
var StringArray = Java.array("java.lang.String", [javaString.$new("J "), javaString.$new("you are the "), javaString.$new("best ")]) var result = Java.use("com.xiaojianbang.app.Utils").$new().myPrint(StringArray); showToast(javaString.$new(result))
}) }
Native
1 2 3 4 5 6 7 8
case R.id.helloFromC /*{ENCODED_INT: 2131165260}*/: toastPrint(NativeHelper.helloFromC()); return; case R.id.add /*{ENCODED_INT: 2131165218}*/: toastPrint(NativeHelper.add(5, 6, 7) + BuildConfig.FLAVOR); return; public static native String helloFromC(); public static native int add(int i, int i2, int i3);
frida -UF -l hookxjb.js
invokeNative()
1 2 3 4 5 6 7 8 9 10 11 12
function invokeNative() { Java.perform(function () { var javaString = Java.use("java.lang.String") var result = Java.use("com.xiaojianbang.app.NativeHelper").helloFromC(); showToast(javaString.$new(result));
result = Java.use("com.xiaojianbang.app.NativeHelper").add(100, 200, 300); showToast(javaString.$new(String(result)));