首页
社区
课程
招聘
[原创]Frida hook Android so RegisterNatives
发表于: 2019-7-9 17:23 12347

[原创]Frida hook Android so RegisterNatives

2019-7-9 17:23
12347

为了达到在应用启动时 hook RegisterNatives 查看注册函数对应关系,特意找了一下 frida hook RegisterNatives 的方法。发现没有现成可用的。翻了一下 frida 源码,自己整理了一个方法,给同学们提供一下方便。

 

直接上 frida 脚本:

function hook_registNatives() {

    var env = Java.vm.getEnv();
    var handlePointer = env.handle.readPointer();
    console.log("handle: " + handlePointer);
    var nativePointer = handlePointer.add(215 * Process.pointerSize).readPointer();
    console.log("register: " + nativePointer);
    /**
     typedef struct {
        const char* name;
        const char* signature;
        void* fnPtr;
     } JNINativeMethod;
     jint RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
     */
    Interceptor.attach(nativePointer, {
        onEnter: function(args) {
            var env = Java.vm.getEnv();
            var methods = args[2];
            var methodcount = args[3].toInt32();
            var name = env.getClassName(args[1]);
            console.log("==== class: " + name + " ====");

            console.log("==== methods: " + methods + " nMethods: " + methodcount + " ====");
            for (var i = 0; i < methodcount; i ++ ) {
                var idx = i * 12;
                var fnPtr = methods.add(idx + 8).readPointer();
                const infoArr = getModuleInfoByPtr(fnPtr);
                const modulename = infoArr[0];
                const modulebase = infoArr[1];
                var logstr = "name: " + methods.add(idx).readPointer().readCString()
                    + ", signature: " + methods.add(idx + 4).readPointer().readCString()
                    + ", fnPtr: " + fnPtr
                    + ", modulename: " + modulename + " -> base: " + modulebase;
                if (null != modulebase) {
                    logstr += ", offset: " + fnPtr.sub(modulebase);
                }
                DMLog.i(tag, logstr);
            }

        }
    });
}

完整的代码:我把这块单独整理到了github
项目用的是 frida 作者 oleavr 推荐的开发环境,按说明初始化环境,用 pycharm 打开可以看到 frida 代码补全提示,感兴趣的同学可以用用看。

 

效果展示:

[INFO][fridaRegstNtv]: hello, i am loaded
handle: 0xefb71cbc
register: 0xef9ba4f1
==== class: com.meituan.android.cipstorage.MMKV ====
==== methods: 0xcd52d428 nMethods: 41 ====
[INFO][fridaRegstNtv]: name: initialize, signature: ()V, fnPtr: 0xcd50b6bd, modulename: libcips.so -> base: 0xcd505000, offset: 0x66bd
[INFO][fridaRegstNtv]: name: onExit, signature: ()V, fnPtr: 0xcd50b6c7, modulename: libcips.so -> base: 0xcd505000, offset: 0x66c7
[INFO][fridaRegstNtv]: name: getMMKVWithID, signature: (Ljava/lang/String;ILjava/lang/String;)J, fnPtr: 0xcd50b6d1, modulename: libcips.so -> base: 0xcd505000, offset: 0x66d1                   
[INFO][fridaRegstNtv]: name: encodeBool, signature: (JLjava/lang/String;Z)Z, fnPtr: 0xcd50b76d, modulename: libcips.so -> base: 0xcd505000, offset: 0x676d
[INFO][fridaRegstNtv]: name: decodeBool, signature: (JLjava/lang/String;Z)Z, fnPtr: 0xcd50b7bf, modulename: libcips.so -> base: 0xcd505000, offset: 0x67bf
[INFO][fridaRegstNtv]: name: encodeInt, signature: (JLjava/lang/String;I)Z, fnPtr: 0xcd50b80f, modulename: libcips.so -> base: 0xcd505000, offset: 0x680f
[INFO][fridaRegstNtv]: name: decodeInt, signature: (JLjava/lang/String;I)I, fnPtr: 0xcd50b85b, modulename: libcips.so -> base: 0xcd505000, offset: 0x685b
[INFO][fridaRegstNtv]: name: encodeLong, signature: (JLjava/lang/String;J)Z, fnPtr: 0xcd50b8a5, modulename: libcips.so -> base: 0xcd505000, offset: 0x68a5
[INFO][fridaRegstNtv]: name: decodeLong, signature: (JLjava/lang/String;J)J, fnPtr: 0xcd50b8f7, modulename: libcips.so -> base: 0xcd505000, offset: 0x68f7
[INFO][fridaRegstNtv]: name: encodeFloat, signature: (JLjava/lang/String;F)Z, fnPtr: 0xcd50b953, modulename: libcips.so -> base: 0xcd505000, offset: 0x6953
......

github 地址: https://github.com/deathmemory/fridaRegstNtv


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-5-22 17:08 被DMemory编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (14)
雪    币: 285
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
能把对应的so名字打出来就方便了 不然还得去查maps
2019-7-10 16:02
0
雪    币: 6003
活跃值: (3490)
能力值: ( LV6,RANK:96 )
在线值:
发帖
回帖
粉丝
3
pancts 能把对应的so名字打出来就方便了 不然还得去查maps

非常好,我更新一下我的git

 

https://github.com/lasting-yang/frida_hook_libart

2019-7-10 23:37
1
雪    币: 6003
活跃值: (3490)
能力值: ( LV6,RANK:96 )
在线值:
发帖
回帖
粉丝
4
GetFieldID is at 0xf229b251
GetMethodID is at 0xf2285fc1
NewStringUTF is at 0xf22b15ed
RegisterNatives is at 0xf22b34e9
GetStaticFieldID is at 0xf22ab135
GetStaticMethodID is at 0xf22a0755
GetStringUTFChars is at 0xf22b1d21
FindClass is at 0xf227f7c9
[GetStaticFieldID] name:out, sig:Ljava/io/PrintStream;
[GetStaticFieldID] name:err, sig:Ljava/io/PrintStream;
[GetStringUTFChars] result:ro.kernel.android.tracing
[NewStringUTF] bytes:
[GetStringUTFChars] result:android.app.ActivityThread
[NewStringUTF] bytes:Binder:4748_1
[NewStringUTF] bytes:Binder:4748_2
[GetStringUTFChars] result:android.graphics.Rect
[GetStringUTFChars] result:zh-Hans-CN
[GetStringUTFChars] result:debug.force_rtl
[GetStringUTFChars] result:android.view.Display$HdrCapabilities
[RegisterNatives] method_count: 0x2c
[RegisterNatives] name: nativeSetCrashLogFilesUploaded sig: ()V fnPtr: 0xd494d568 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetForeground sig: (Z)V fnPtr: 0xd494d580 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetProcessType sig: (Z)V fnPtr: 0xd494d59c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeChangeState sig: (Ljava/lang/String;Ljava/lang/String;Z)Z fnPtr: 0xd494da74 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetCrashCustoms sig: (ZZIIIIZZZIZ)V fnPtr: 0xd494d5b8 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeUpdateSignals sig: (III)V fnPtr: 0xd494d678 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetZip sig: (ZLjava/lang/String;I)V fnPtr: 0xd494dc68 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetCrashLogFileNames sig: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494dcb4 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetFolderNames sig: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494dd30 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetProcessNames sig: (Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494ddd0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetVersionInfo sig: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494de28 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetLogStrategy sig: (ZZJ)V fnPtr: 0xd494d6a0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeGetNativeBuildseq sig: ()Ljava/lang/String; fnPtr: 0xd494d8ac module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeUpdateCrashLogNames sig: ()V fnPtr: 0xd494d6dc module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeAddHeaderInfo sig: (Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494deb8 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeAddDumpFile sig: (Ljava/lang/String;Ljava/lang/String;ZZZZZ)I fnPtr: 0xd494df0c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeAddCallbackInfo sig: (Ljava/lang/String;ZZJI)I fnPtr: 0xd494dfb0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeGetCallbackInfo sig: (Ljava/lang/String;JIZ)Ljava/lang/String; fnPtr: 0xd494e020 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeCreateCachedInfo sig: (Ljava/lang/String;I)Z fnPtr: 0xd494e0ac module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeAddCachedInfo sig: (Ljava/lang/String;Ljava/lang/String;)Z fnPtr: 0xd494e0f0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetPackageInfo sig: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494e14c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSetMobileInfo sig: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd494e1c8 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeInitNative sig: ()V fnPtr: 0xd494d4a0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeInstallBreakpad sig: (II)V fnPtr: 0xd494d4b4 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeUninstallBreakpad sig: ()V fnPtr: 0xd494d4d0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeBreakpadInited sig: (Ljava/lang/String;)V fnPtr: 0xd494d9e0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativePrepareUnexpInfos sig: (Z)V fnPtr: 0xd494d4e4 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeGenerateUnexpLog sig: (JI)I fnPtr: 0xd494d500 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeReserveFileHandle sig: (II)V fnPtr: 0xd494d7a4 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeRegisterCurrentThread sig: (Ljava/lang/String;)V fnPtr: 0xd494dbd0 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeOpenFile sig: (Ljava/lang/String;)I fnPtr: 0xd494dc04 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeCloseFile sig: (I)V fnPtr: 0xd494d530 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeLockFile sig: (IZ)Z fnPtr: 0xd494d548 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeDumpThreads sig: (Ljava/lang/String;J)Ljava/lang/String; fnPtr: 0xd494f0fc module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeUpdateUnexpInfo sig: (I)V fnPtr: 0xd494d744 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSyncStatus sig: (Ljava/lang/String;Ljava/lang/String;I)Z fnPtr: 0xd494ea2c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeSyncInfo sig: (Ljava/lang/String;Ljava/lang/String;JJ)Z fnPtr: 0xd494ec54 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeGetOrSetIsolatedHostFd sig: (II)I fnPtr: 0xd494d75c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeIsolateCreateConnection sig: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)J fnPtr: 0xd494ee40 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeIsolateWriteData sig: (JLjava/lang/String;)I fnPtr: 0xd494e46c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeIsolateCloseConnection sig: (J)V fnPtr: 0xd494d6f4 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeIsCrashing sig: ()Z fnPtr: 0xd494d51c module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeLog sig: (ILjava/lang/String;Ljava/lang/String;)I fnPtr: 0xd494e244 module_name: libcrashsdk.so module_base: 0xd4948000
[RegisterNatives] name: nativeCrash sig: (II)V fnPtr: 0xd494e864 module_name: libcrashsdk.so module_base: 0xd4948000
2019-7-10 23:43
0
雪    币: 285
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
Imyang ``` GetFieldID is at 0xf229b251 GetMethodID is at 0xf2285fc1 NewStringUTF is at 0xf22b15ed Regis ...
学到了 感谢
2019-7-11 10:23
0
雪    币: 905
活跃值: (1057)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

很赞楼主,不管so里面JNI_OnLoad怎么混淆,都可以直接找到Java层对应的方法了,我之前用JNIEnv指针加偏移的方法无法hook像CallObjectMethodV这种函数,这样直接打印libart.so的导出符号函数_ZN3art3JNI17CallObjectMethodVEP7_JNIEnvP8_jobjectP10_jmethodIDSt9__va_list,找到地址就可以直接hook了,很受用的思路!

Java.perform(function() { 
    var ishook_libart = false;

    function hook_libart() {
        if (ishook_libart === true) {
            return;
        }
        var symbols = Module.enumerateSymbolsSync("libart.so");
        var JSONObject = Java.use("org.json.JSONObject")
        var addrRegisterNatives = undefined;
        var addrCallObjectMethodV= undefined;

        for (var i = 0; i < symbols.length; i++) {
            var symbol = symbols[i];

            //console.log("libart.so SymbolName: " + symbol.name);
            if (symbol.name == "_ZN3art3JNI17CallObjectMethodVEP7_JNIEnvP8_jobjectP10_jmethodIDSt9__va_list") {
              addrCallObjectMethodV = symbol.address;
              console.log("addrCallObjectMethodV is at " + addrCallObjectMethodV);
          }         
      }

      if (addrCallObjectMethodV != undefined) {
        Interceptor.attach(addrCallObjectMethodV, {
            onEnter: function(args) {
                try {
                        var JSONObj = Java.cast(args[1], JSONObject);
                        console.log("[+] args[1] JSON: " + JSONObj.toString());      
                    } catch(e) {
                        //console.log("[+] error: " + e.toString());
                    }
                },
                onLeave: function(retval) {}
            });
    }
    ishook_libart = true;
}

hook_libart();
});
2019-7-15 17:13
1
雪    币: 2155
活跃值: (4527)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
好东西 收藏一波
2019-8-11 23:24
0
雪    币: 266
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gqm
8
可以加您微信吗
2019-8-19 02:07
0
雪    币: 4440
活跃值: (3103)
能力值: ( LV10,RANK:175 )
在线值:
发帖
回帖
粉丝
9
gqm 可以加您微信吗
可以,私信我
最后于 2019-8-21 17:09 被DMemory编辑 ,原因:
2019-8-21 17:08
0
雪    币: 266
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gqm
10
私信您了
2019-8-21 23:01
0
雪    币: 0
活跃值: (353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
DMemory gqm 可以加您无微信吗 可以,私信我
最后于 2019-11-15 15:21 被Erlösung编辑 ,原因: 写错了
2019-11-13 12:34
0
雪    币: 0
活跃值: (353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
Imyang ``` GetFieldID is at 0xf229b251 GetMethodID is at 0xf2285fc1 NewStringUTF is at 0xf22b15ed Regis ...
我看你的git 有一个art 和registive 这两个区别是啥?一个是虚拟机全部加载的so?一个是当下加载的?
2019-11-13 12:36
0
雪    币: 0
活跃值: (353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
wx_La0s 很赞楼主,不管so里面JNI_OnLoad怎么混淆,都可以直接找到Java层对应的方法了,我之前用JNIEnv指针加偏移的方法无法hook像CallObjectMethodV这种函数,这样直接打印li ...
_ZN3art3JNI17CallObjectMethodVEP7_JNIEnvP8_jobjectP10_jmethodIDSt9__va_list  这个函数是偏移地址?我直接用so 的基地址+这个符号函数的地址 就可以hook 出so 层的算法?这里地址需要+1?
2019-11-13 12:52
0
雪    币: 110
活跃值: (1565)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
真的可以,非常感谢!解决了我的问题
2019-11-28 11:20
0
雪    币: 4440
活跃值: (3103)
能力值: ( LV10,RANK:175 )
在线值:
发帖
回帖
粉丝
15
Erlösung _ZN3art3JNI17CallObjectMethodVEP7_JNIEnvP8_jobjectP10_jmethodIDSt9__va_list 这个函数是偏移地址?我直接用so 的基地址+这 ...
不是 +1,准确的说,如果是 thumb 指令集需要【或运算】1
2020-3-24 16:44
0
游客
登录 | 注册 方可回帖
返回
//