如何在 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 => { .. })