如何在 Android 中使用 Frida 挂钩 fopen?
How to hook fopen using Frida in Android?
我有一个 android 应用程序,我在其中加载了一个库,有时我读取了一个文件。这是应用程序中使用的代码。
FILE *fp = fopen(file_name, "r");
if (fp == NULL) {
return res;
}
现在我正在尝试使用 Frida 挂钩 fopen
以将其强制为 return null 但我似乎无法找出方法。
应用程序中包含的库称为 libnative-lib.so
,我尝试挂钩 fopen
包括 frida
的以下代码
Module.enumerateExports("libnative-lib.so", {
onMatch: function(e) {
if(e.type == 'function') {
if(e.name == "fopen") {
console.log("Function recognized by name");
Interceptor.attach(e.address, {
onEnter: function(args) {
console.log("Interceptor attached onEnter...");
},
onLeave: function(retval){
console.log("Interceptor attached onLeave...");
}
});
}
}
},
onComplete: function() {}
});
您可以尝试调用 Module.findExportByName(null, "fopen")
来获取 fopen
的地址,而不是枚举特定库的导出(空参数告诉 frida 查看所有已加载库的导出库)并像您一样使用 Interceptor
API。
这应该看起来像这样:
Interceptor.attach(Module.findExportByName(null, "fopen"), {
onEnter: function(args) {
console.log("Interceptor attached onEnter...");
},
onLeave: function(args) {
console.log("Interceptor attached onLeave...");
}
}
您没有具体说明您的代码是如何失败的,但是为了确保您所讨论的库确实已加载到应用程序中,您可以列出所有已加载的模块:
Process.enumerateModules()
.forEach(function(m) {
// You can print just the name by using m.name or the entire system path with m.path
console.log(JSON.stringify(m));
});
另一种方法是使用 Process.enumerateModules()
找到正确的模块,然后在您获得的 Module
对象上调用 enumerateExports
。
如果模块名称不完全是 libnative-lib.so
:
,这将确保您在正确的模块中搜索 fopen
Process.enumerateModules()
.filter(function(m){ return m["path"].toLowerCase().indexOf("libnative") != -1 ; })
.forEach(function(mod) {
console.log(JSON.stringify(mod));
mod.enumerateExports().forEach(function (exp) {
if (exp.name.indexOf("fopen") != -1) {
console.log("fopen found!");
}
})
});
HTH,如果这仍然不能解决您的问题post您的问题中的一些额外信息。
fopen 将调用 open
我建议使用条件来断言它会打开您的特定文件,而不是 replace/override。
Interceptor.attach(Module.findExportByName(null, "open"), {
onEnter: function(args) {
this.file_name = Memory.readCString(ptr(args[0]));
},
onLeave: function(retval) {
if ("your file name" === this.file_name) // passed from onEnter
retval.replace(0x0); // return null
}
});
顺便说一句,如果您启用标志 --enable-jit
,您可以使用 ECMAScript6
进行过滤
Module.enumerateExports(moduleName).filter(ex => ex.name.includes('fopen')).forEach(ex => { .. })
我有一个 android 应用程序,我在其中加载了一个库,有时我读取了一个文件。这是应用程序中使用的代码。
FILE *fp = fopen(file_name, "r");
if (fp == NULL) {
return res;
}
现在我正在尝试使用 Frida 挂钩 fopen
以将其强制为 return null 但我似乎无法找出方法。
应用程序中包含的库称为 libnative-lib.so
,我尝试挂钩 fopen
包括 frida
Module.enumerateExports("libnative-lib.so", {
onMatch: function(e) {
if(e.type == 'function') {
if(e.name == "fopen") {
console.log("Function recognized by name");
Interceptor.attach(e.address, {
onEnter: function(args) {
console.log("Interceptor attached onEnter...");
},
onLeave: function(retval){
console.log("Interceptor attached onLeave...");
}
});
}
}
},
onComplete: function() {}
});
您可以尝试调用 Module.findExportByName(null, "fopen")
来获取 fopen
的地址,而不是枚举特定库的导出(空参数告诉 frida 查看所有已加载库的导出库)并像您一样使用 Interceptor
API。
这应该看起来像这样:
Interceptor.attach(Module.findExportByName(null, "fopen"), {
onEnter: function(args) {
console.log("Interceptor attached onEnter...");
},
onLeave: function(args) {
console.log("Interceptor attached onLeave...");
}
}
您没有具体说明您的代码是如何失败的,但是为了确保您所讨论的库确实已加载到应用程序中,您可以列出所有已加载的模块:
Process.enumerateModules()
.forEach(function(m) {
// You can print just the name by using m.name or the entire system path with m.path
console.log(JSON.stringify(m));
});
另一种方法是使用 Process.enumerateModules()
找到正确的模块,然后在您获得的 Module
对象上调用 enumerateExports
。
如果模块名称不完全是 libnative-lib.so
:
fopen
Process.enumerateModules()
.filter(function(m){ return m["path"].toLowerCase().indexOf("libnative") != -1 ; })
.forEach(function(mod) {
console.log(JSON.stringify(mod));
mod.enumerateExports().forEach(function (exp) {
if (exp.name.indexOf("fopen") != -1) {
console.log("fopen found!");
}
})
});
HTH,如果这仍然不能解决您的问题post您的问题中的一些额外信息。
fopen 将调用 open
我建议使用条件来断言它会打开您的特定文件,而不是 replace/override。
Interceptor.attach(Module.findExportByName(null, "open"), {
onEnter: function(args) {
this.file_name = Memory.readCString(ptr(args[0]));
},
onLeave: function(retval) {
if ("your file name" === this.file_name) // passed from onEnter
retval.replace(0x0); // return null
}
});
顺便说一句,如果您启用标志 --enable-jit
,您可以使用 ECMAScript6
Module.enumerateExports(moduleName).filter(ex => ex.name.includes('fopen')).forEach(ex => { .. })