对于Native层的函数Hook,我们使用如下模板
可以发现,程序从EditText控件中获取到了用户的输入,然后调用了native层中的cmpstr函数进行比较。
程序在cmpstr中使用了strcmp函数,那么我们只需要拿到strcmp函数的传入参数就可以知道程序的正确输入了
首先我们使用Module.enumerateImports("libfrida0x8.so")查看导入表
可以发现strcmp来自于libc.so,那么我们就可以使用Module.findExportByName("libc.so","strcmp");来获取strcmp的地址了
获取了strcmp的地址就可以使用之前给的模板进行Hook了
但是我们需要注意的是strcmp可能不止调用一次,因此我们需要判断strcmp的第一个参数是否为0我们才进行操作,不然hook可能会一直循环输出
因此我们可以使用Memory.readUtf8String(args[0]);来获取我们的输入字符串,平且使用 if (input.includes("111"))来判断
首先还是给出hook的模板如下:
可以看到在onLeave中有一个参数retval,这个retval,就是我们hook上的程序的返回值,我们可以使用retval.replace(val)来修改返回值。
可以发现程序根据native层的check_flag 方法的返回值
只是简简单单的返回了一个1
首先使用Module.enumerateExports("liba0x9.so"),查看导出表,看看check_flag方法的偏移地址
然后就可以使用模板一把梭了
让我提供一个模板。
让我逐行解释。
要在 Frida 中调用一个本地函数,我们需要一个 NativePointer
对象。我们应该将要调用的本地函数的地址传递给 NativePointer
构造函数。接下来,我们将创建 NativeFunction
对象,它表示我们想要调用的实际本地函数。它在本地函数周围创建一个 JavaScript 包装器,允许我们从 Frida 调用该本地函数。
第一个参数应该是 NativePointer
对象,第二个参数是本地函数的返回类型,第三个参数是要传递给本地函数的参数的数据类型列表。现在我们可以像在 Java 空间中那样调用该方法了。
好的,我们明白了。让我们来看看例题。
发现就是在主函数中加载了stringFromJNI
没有关于flag的信息,但是有未被调用的flag函数,我们直接使用hook调用它输出log
首先我们先看来自x86指令集的frida使用模板
X86Writer
的实例化:
**插入指令 **
刷新更改:
清理:
解除段只读权限
Memory.protect
。我们可以使用这个函数来修改内存区域的保护属性。Memory.protect
函数的语法如下:
那么如何使用进行覆写呢
对于x86系统而言我们首先需要查看官方文档中的使用方法
https://frida.re/docs/javascript-api/#x86writer
对与arm64系统而言,我们使用如下api
https://frida.re/docs/javascript-api/#arm64writer
接下来让我用一个用例程序来讲一下这个指令的用法,我们示范的内容为arm64架构
首先我们看到MainActivity函数内容
发现MainActivity就是在用户点击按钮后调用了getflag方法,但是正常点击getflag方法并不会返回flag值。
惊讶的发现MainActivity中什么都没有,显然这是不存在的。接下来我们到控制流窗口中查看。
查看控制流发现程序出现了永假条件跳转。导致导致ida识别不到输出flag的功能。那么我们可以把这个B.NE给Nop掉即可
首先我们需要计算B.NE的偏移地址
可以发现就是基地址增加15248,然后我们覆写为Nop就可以了
Interceptor.attach(targetAddress, {
onEnter:
function
(args) {
console.log(
'Entering '
+ functionName);
},
onLeave:
function
(retval) {
console.log(
'Leaving '
+ functionName);
}
});
Interceptor.attach(targetAddress, {
onEnter:
function
(args) {
console.log(
'Entering '
+ functionName);
},
onLeave:
function
(retval) {
console.log(
'Leaving '
+ functionName);
}
});
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){
},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);
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);
Interceptor.attach(functionaddr, {
onEnter:
function
(args) {
},
onLeave:
function
(retval) {
}
});
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);
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);
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)