枚举各种

  • 通过枚举导入表,可以得到出现在导入表中的函数地址

    var imports=Module.enumerateImports("libxiaojianbang.so");
    for(let i=0;i<imports.length;i++){
    console.log(JSON.stringify(imports[i]));
    }
  • 通过枚举导出表,可以得到出现在导出表中的函数地址

    var exports=Module.enumerateExports("libxiaojianbang.so");
    for(let i=0;i<exports.length;i++){
    console.log(JSON.stringify(exports[i]));
    }
  • 通过枚举符号表,可以得出出现在符号表中的函数地址

    var symbol=Module.enumerateSymbols("libencryptlib.so");
    for(let i=0;i<symbol.length;i++){
    console.log(JSON.stringify(symbol[i]));
    }
  • 通过枚举模块,在枚举出模块里面的导出表,可以快速找到某个导入函数出自哪个so

    var moudles=Process.enumerateModules();
    console.log(JSON.stringify(moudles[0].enumerateExports()[0]));

sohook导出函数

  • 在so导出表里的函数,可以通过frida提供的api来获取函数地址

    var funcAddr=Module.findExportByName("libxiaojianbang.so","add");
    函数名以汇编中出现的为准
  • 得到函数地址后,可以使用Interceptor.attach来对函数进行hook

    Interceptor.attach(Address,{
    onEnter:function(args){
    console.log(args[0]);//打印参数
    console.log(this.context.x1);//打印寄存器
    console.log(args[2].toInt32());//默认显示16进制,这里转成10进制
    },
    onLeave:function(retval){
    console.log("retval",retval,retval.toInt32());
    }
    });
var funcAddr=Module.findExportByName("libencryptlib.so","_ZN7MD5_CTX11MakePassMD5EPhjS0_");
console.log(funcAddr);
Interceptor.attach(funcAddr,{
onEnter:function(args){
console.log("funcAddr onEnter args[1]:",hexdump(args[1]));
console.log("funcAddr onEnter args[2]:",args[2].toInt32());
this.args3=args[3];
},onLeave:function(retval){
console.log("funcAddr onEnter args[3]:",hexdump(this.args3));
}
});

模块基址的几种方式

  • 在导入表、导出表、符号表里找不到的函数,地址需要自己计算

  • 计算方式也很简单:so基址+函数在so中的偏移[+1]

  • 因此,需要得到so基址,也就是模块基址

    Process.findMoudleByName("libart.so");
    Process.getMoudleByName("libc.so");
    Module.findBaseAddress("libart.so");
    Process.enumerateModules();
    Process.findModuleByAddress(address);
    Process.getModuleByAddress(address);
var module1=Process.findModuleByName("libencryptlib.so");
console.log("module1",module1.base);

var module2=Process.getModuleByName("libencryptlib.so");
console.log("module2",module2.base);

var soAddr=Module.findBaseAddress("libencryptlib.so");
console.log("soAddr",soAddr);

var modules=Process.enumerateModules();
for(let i=0;i<modules.length;i++){
if(modules[i].name=="libencrypt.so"){
console.log(modules[i].name+" "+modules[i].base);
}
}

var module=Process.findModuleByAddress(Module.findBaseAddress("libencrypt.so"));
console.log("module "+module.name+" "+module.base);

函数地址的计算

  • 在导入表、导出表、符号表里找不到的函数,地址需要自己计算

  • 计算方式也很简单:so基址+函数在so中的偏移[+1]

    如果是thumb指令,函数地址计算方式:so基址+函数在so中的偏移+1

    如果是arm指令,函数地址的i计算方式:so基址+函数在so中的偏移

  • 在安卓中,32位的so中的函数,基本都是thumb指令;64位的so基本都是arm指令

  • 也可以通过显示汇编指令对应的opcode bytes,来判断

    options->general->Number of opcode bytes(non-graph) 4

    arm指令为4个字节,如果函数中有些指令是两个字节,那么函数地址计算需要+1

  • 通过代码的方式

    var soAddr=Module.findBaseAddress("libencryptlib.so");
    console.log(soAddr.add(0x1FA38))

Hook任意函数

var soAddr=Module.findBaseAddress("libencryptlib.so");
var funcAddr=soAddr.add(0xFA38);
Interceptor.attach(funcAddr,{
onEnter:function(args){
console.log("funcAddr onEnter args[1]:"hexdump(args[1]));
console.log("funcAddr onEnter args[2]:",args[2].toInt32);
this.args3=args[3];
},onLeave:function(){
console.log("funcAddr onLeave args[3]:",hexdump(this.args3));
}
});

封装成函数

function print_arg(addr){
var module=Process.findRangeByAddress(addr);
if(module!=null) return hexdump(addr)+"\n";
return ptr(addr)+"\n";
}
function hook_native_addr(funcPtr,paramsNum){
var module=Process.findModuleByAddress(funcPtr);
Interceptor.attach(funcPtr,{
onEnter:function(args){
this.logs=[];
this.params=[];
this.logs.push("call "+module.name+"!"+ptr(funcPtr).sub(module.base)+"\n");
for(let i=0;i<paramsNum;i++){
this.params.push(args[i]);
}
for(let i=0;i<paramsNum;i++){
this.logs.push("this.args"+i+"onLeave: "+print_arg(this.params[i]));
}
},onLeave:function(){
this.logs.push("retval onLeave: "+print_arg(retval)+"\n");
console.log(this.logs);
}
});
}
var soAddr=Module.findBaseAddress("libencryptlib.so");
var funcAddr=soAddr.add(0x1FA38);
hook_native_addr(funcAddr,4);