Unidbg调用jni函数

Unidbg 是一个基于 unicorn 的逆向工具,可以黑盒调用安卓和 iOS 中的 so 文件。它可以让你在电脑上跑 arm 的可执行文件或共享库文件。Unidbg 是一个标准的Java项目。

环境准备

1
git clone https://github.com/zhkl0228/unidbg.git

使用 IDEA 打开项目,等待 maven 下载依赖并根据提示配置 JDK。

基本功能

  • so 算法的模拟执行
  • hook
  • trace 帮助还原算法

使用

项目依赖下载完成后,可以进入 unidbg-android/src/test 目录,里面为自带的几个测试项目,确保可以正常运行其中的项目。

使用我们之前创建的easymd5项目,解压 apk,将得到的 so 文件复制到 unidbg 目录中,比如此处我们的 so 文件目录为 unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libeasymd5.so。

在 unidbg-android/src/test 目录下新建 package,并创建一个 class,内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package dev.svip.easymd5;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.LibraryResolver;
import com.github.unidbg.arm.backend.DynarmicFactory;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.DvmObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject;
import com.github.unidbg.memory.Memory;

import java.io.File;


public class MainActivity {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        dev.svip.easymd5.MainActivity mainActivity = new dev.svip.easymd5.MainActivity();
        System.out.println("load offset=" + (System.currentTimeMillis() - start) + "ms");
        mainActivity.crack();
    }

    private final AndroidEmulator emulator;
    private final DvmClass dvmClass;
    private final VM vm;

    private MainActivity() {
        emulator = AndroidEmulatorBuilder
                .for32Bit()
                .addBackendFactory(new DynarmicFactory(true))
                .build();
        Memory memory = emulator.getMemory();
        LibraryResolver resolver = new AndroidResolver(23);
        memory.setLibraryResolver(resolver);

        vm = emulator.createDalvikVM();
        //打印日志
        vm.setVerbose(true);
        DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libeasymd5.so"), false);
        dm.callJNI_OnLoad(emulator);
        dvmClass = vm.resolveClass("dev/svip/easymd5/MainActivity");
    }


    private void crack() {
        //写法一
        DvmObject<?> result = dvmClass.callStaticJniMethodObject(emulator, "mdString(Ljava/lang/String;)Ljava/lang/String;", "12345blog.svip.dev");
        System.out.println("result is => " + result.getValue());

        //写法二
        DvmObject<?> obj = ProxyDvmObject.createObject(vm, this);
        DvmObject<?> result2 = obj.callJniMethodObject(emulator, "mdString(Ljava/lang/String;)Ljava/lang/String;", "12345blog.svip.dev");
        System.out.println("result2 is => " + result2.getValue());
    }
}

运行效果如下

image-20220107101252921

红框内容为我们自己打印的内容,其他信息为调试信息,可以看出 unidbg 已将调用过程准确 trace 出来。

updatedupdated2022-01-072022-01-07