Frida0C - Module相关API

191 阅读2分钟

亲爱的读者你们好啊,今天主要分享一下 frida 相关的学习文档,见文章最后一节。

Module

var module = Process.findModuleByAddress(Module.findBaseAddress("libc.so"))
module.enumerateSymbols()

enumerateSymbols 返回该 so 的符号表。

还有一个比较类似的函数:enumerateExports 。

enumerateSymbols 对应的是 SHT_SYMTABenumerateExports 对应的是 SHT_DYNSYM 。

两者的区别见文档:

refspecs.linuxfoundation.org/LSB_2.1.0/L…

简单理解为,SHT_DYNSYM 是 SHT_SYMTAB 的一个子集,文档里面说明,这两者一般不共存。

Frida的相关源码:

github.com/frida/frida…

ModuleMap

val mm = new ModuleMap([filter]);

创建一个对象,表示当前所有已加载的 so 的快照,可使用 update 函数刷新,filter 用于过滤想要观察的 so。

可以使用 find 函数来寻找其对应的 so:

find(address)

当你有一个地址,但是不知道它属于哪个so的时候,可以使用这个方法。

例子

如果想了解更多关于Frida的API示例和用法,可以访问Frida的JavaScript API文档(frida.re/docs/javasc…

此外,GitHub上的frida-snippets项目(github.com/iddoeldor/f…

对于想要深入了解Frida的高级用法的人来说,Learn Frida网站(learnfrida.info/advanced_us…

比如,registerNativeMethods可用作对抗逆向分析,所以我们可以hook这个函数:

var RevealNativeMethods = function({
  var pSize = Process.pointerSize;
  var env = Java.vm.getEnv();
  var RegisterNatives = 215, FindClassIndex = 6// search "215" @ https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html
  var jclassAddress2NameMap = {};
  function getNativeAddress(idx{
    return env.handle.readPointer().add(idx * pSize).readPointer();
  }
  // intercepting FindClass to populate Map<address, jclass>
  Interceptor.attach(getNativeAddress(FindClassIndex), {
    onEnter: function(args) {
      jclassAddress2NameMap[args[0]] = args[1].readCString();
    }
  });
  // RegisterNative(jClass*, .., JNINativeMethod *methods[nMethods], uint nMethods) // https://android.googlesource.com/platform/libnativehelper/+/master/include_jni/jni.h#977
  Interceptor.attach(getNativeAddress(RegisterNatives), {
    onEnter: function(args) {
      for (var i = 0, nMethods = parseInt(args[3]); i < nMethods; i++) {
        /*
          https://android.googlesource.com/platform/libnativehelper/+/master/include_jni/jni.h#129
          typedef struct {
             const char* name;
             const char* signature;
             void* fnPtr;
          } JNINativeMethod;
        */
        var structSize = pSize * 3// = sizeof(JNINativeMethod)
        var methodsPtr = ptr(args[2]);
        var signature = methodsPtr.add(i * structSize + pSize).readPointer();
        var fnPtr = methodsPtr.add(i * structSize + (pSize * 2)).readPointer(); // void* fnPtr
        var jClass = jclassAddress2NameMap[args[0]].split('/');
 var methodName = methodsPtr.add(i * structSize).readPointer().readCString();
        console.log('\x1b[3' + '6;01' + 'm', JSON.stringify({
          module: DebugSymbol.fromAddress(fnPtr)['moduleName'], // https://www.frida.re/docs/javascript-api/#debugsymbol
          package: jClass.slice(0, -1).join('.'),
          class: jClass[jClass.length - 1],
          method: methodName, // methodsPtr.readPointer().readCString(), // char* name
          signature: signature.readCString(), // char* signature TODO Java bytecode signature parser { Z'boolean', B'byte', C'char', S'short', I'int', J'long', F'float', D'double', L'fully-qualified-class;''[''array' } https://github.com/skylot/jadx/blob/master/jadx-core/src/main/java/jadx/core/dex/nodes/parser/SignatureParser.java
          address: fnPtr
        }), '\x1b[39;49;00m');
      }
    }
  });
}

Java.perform(RevealNativeMethods);

未标题-1.jpg