前期准备
一
Hook Native层中调用的函数并且读取传入的参数
Interceptor.attach(targetAddress, {
onEnter: function (args) {
console.log('Entering ' + functionName);
// Modify or log arguments if needed
},
onLeave: function (retval) {
console.log('Leaving ' + functionName);
// Modify or log return value if needed
}
});
Interceptor.attach
:将回调函数附加到指定的函数地址。targetAddress
应该是我们想要挂钩的本地函数的地址。onEnter
:当挂钩的函数被调用时,调用此回调。它提供对函数参数 (args
) 的访问。onLeave
:当挂钩的函数即将退出时,调用此回调。它提供对返回值 (retval
) 的访问。Module.enumerateExports()
Module.getExportByName()
Module.findExportByName()
null
。让我们看一个示例。Module.getBaseAddress()
Module.enumerateImports()
function hook(){ var targetAddress = Module.findExportByName("libc.so","strcmp");
console.log("Strcmp Address: ",targetAddress.toString(16));Interceptor.attach(targetAddress,{
onEnter:function (args){},onLeave:function(retval){
}
})
console.log("success!");
}function main(){
Java.perform(function (){
hook();
})
}
setImmediate(main);
function hook(){ var targetAddress = Module.findExportByName("libc.so","strcmp");
console.log("Strcmp Address: ",targetAddress.toString(16));Interceptor.attach(targetAddress,{
onEnter:function (args){
var input = Memory.readUtf8String(args[0]);
if (input.includes("111")){
console.log(Memory.readUtf8String(args[1]));
}},onLeave:function(retval){
}
})
console.log("success!");
}function main(){
Java.perform(function (){
hook();
})
}
setImmediate(main);
二
Hook修改native层程序返回值
Interceptor.attach(functionaddr, {
onEnter: function (args) {},
onLeave: function (retval) {}
});
function hook(){
var check_flag = Module.enumerateExports("liba0x9.so")[0]["address"];
console.log("Func address = ",check_flag);
Interceptor.attach(check_flag,{
onEnter:function (args){},onLeave:function (retval){
console.log("Origin retval : ",retval);
retval.replace(1337);
}
})
}
function main(){
Java.perform(function (){
hook();
})
}
setImmediate(hook);
三
调用native层中未被调用的方法
var native_adr = new NativePointer(<address_of_the_native_function>);
const native_function = new NativeFunction(native_adr, '<return type>', ['argument_data_type']);
native_function(<arguments>);
var native_adr = new NativePointer(<address_of_the_native_function>);
NativePointer
对象。我们应该将要调用的本地函数的地址传递给NativePointer
构造函数。接下来,我们将创建NativeFunction
对象,它表示我们想要调用的实际本地函数。它在本地函数周围创建一个 JavaScript 包装器,允许我们从 Frida 调用该本地函数。const native_function = new NativeFunction(native_adr, '<return type>', ['argument_data_type']);
NativePointer
对象,第二个参数是本地函数的返回类型,第三个参数是要传递给本地函数的参数的数据类型列表。现在我们可以像在 Java 空间中那样调用该方法了。native_function(<arguments>);
function hook(){
var a = Module.findBaseAddress("libfrida0xa.so");
var b = Module.enumerateExports("libfrida0xa.so");
var get_flagaddress = null;
var mvaddress = null;
for(var i = 0 ; b[i]!= null ; i ++ ){
// console.log(b[i]["name"])
if(b[i]["name"] == "_Z8get_flagii"){
console.log("function get_flag : ",b[i]["address"]);
console.log((b[i]["address"] - a).toString(16));
// mvaddress = b[i]["address"] - a;
get_flagaddress = b[i]["address"];
}
}
console.log(ptr.toString(16));var get_flag_ptr = new NativePointer(get_flagaddress);
const get_flag = new NativeFunction(get_flag_ptr,'char',['int','int']);
var flag = get_flag(1,2);
console.log(flag)
//console.log(b);
}function main(){
Java.perform(function (){
hook();
})
}
setImmediate(main)
四
更改Native层方法的汇编指令
var writer = new X86Writer(opcodeaddr);
Memory.protect(opcodeaddr, 0x1000, "rwx");
try {writer.flush();
} finally {
writer.dispose();
}
X86Writer
的实例化:var writer = new X86Writer(<指令的地址>);
X86Writer
类的实例,并指定我们要修改的指令的地址。这设置了写入器以操作指定的内存位置。try { /* 在此处插入指令 */ }
try
块内,我们可以插入要修改/添加的x86指令。X86Writer
实例提供了各种方法来插入各种x86指令。我们可以查阅文档以了解详情。writer.flush();
flush
方法将更改应用到内存中。这确保修改后的指令被写入内存位置。finally { /* 释放X86Writer以释放资源 */ writer.dispose(); }
finally
块用于确保X86Writer
资源得到适当清理。调用dispose
方法释放与X86Writer
实例关联的资源。
Memory.protect
。我们可以使用这个函数来修改内存区域的保护属性。Memory.protect
函数的语法如下:Memory.protect(地址, 大小, 保护属性);
地址
:要更改保护的内存区域的起始地址。大小
:内存区域的大小,以字节为单位。保护属性
:内存区域的保护属性。function hook(){
var Base = Module.getBaseAddress("libfrida0xb.so");
console.log("Base address : ",Base);
var BNE = Base.add(0x15248);
Memory.protect(Base,0x1000,"rwx");
var writer = new Arm64Writer(BNE);
try{
writer.putNop();
writer.flush();
console.log("Success!!");
}finally {
writer.dispose();
}
}function main(){
Java.perform(function (){
hook();
})
}setTimeout(main,1000);
看雪ID:Shangwendada
https://bbs.kanxue.com/user-home-979679.htm
# 往期推荐
2、BFS Ekoparty 2022 Linux Kernel Exploitation Challenge
3、银狐样本分析
球分享
球点赞
球在看
点击阅读原文查看更多