目前很多 App 的加密签名算法都在so文件中,强行逆向so的话可能会耗费大量工夫和资源。

之前用 xposed 采纳 hook 的办法从程序计算签名,然而须要模拟器或者真机运行这个利用,应用效率不高。
也用过 jtype 启动JVM,而后通过 native 对so文件进行调用,因为每次都须要启动JVM,所以效率也不高。

unidbg 他不须要运行 app,也无需逆向 so 文件,通过在 app 中找到对应的 JNI 接口,而后用 unicorn 引擎间接调用 so 文件,所以效率绝对要高不少。


unidbg特点

  • 模仿JNI调用API,能够调用JNI_OnLoad
  • 反对JavaVM,JNIEnv
  • 模拟系统调用
  • 反对ARM32和ARM64
  • 内联钩子(Inline Hook)
  • Android import hook
  • iOS 的一些hook工具 fishhook and substrate and whale hook
  • 反对简略的控制台调试器,gdb存根,实验性IDA android调试器服务器,指令跟踪,内存读/写跟踪
  • 反对iOS objc和Swift

unidbg环境配置

unidbg下载链接: https://github.com/zhkl0228/unidbg

IntelliJ IDEA可用于编辑unidbg源

下载实现之后示导入到 IDEA 中,当然你须要筹备好java环境(jdk、maven)


抉择Maven

期待加载实现之后,运行src/..../encrypt 中的TTEncrypt测试用例

如果控制台打印相干调用信息,阐明曾经导入胜利。


加载libcms.so

看过这篇文章的应该曾经晓得生成xg函数的地位,所以不具体说了。《抖音xgorgon(0401)》

上面筹备调用libcms.so文件中的 leviathan 函数

首先在 src/test/resources 目录下新建文件夹dylib,放入libcms.so文件

libcms.so 下载地址: https://download.csdn.net/download/weixin_43582101/12713664

而后我在 /unidbg/unidbg-android/src/test/java/com/sun/jna/ 目录下新建了 JniDispatch128.java文件

JniDispatch128.java文件内容如下:

备注
"com/ss/sys/ces/a"须要调用函数所在的Java类残缺门路,比方 a/b/c/d 等等,留神须要用/代替.
"leviathan(II[B)[B"须要调用的函数名,名字是smali语法,可通过jadx等工具查看
“vm.loadLibrary(new File)”so文件的门路,须要自行批改,最好为绝对路径
package com.sun.jna;import com.github.unidbg.*;import com.github.unidbg.linux.android.AndroidARMEmulator;import com.github.unidbg.linux.android.AndroidResolver;import com.github.unidbg.linux.android.dvm.*;import com.github.unidbg.memory.Memory;import com.github.unidbg.memory.MemoryBlock;import com.github.unidbg.linux.android.dvm.array.ByteArray;import java.io.File;import java.io.IOException;public class JniDispatch128 extends AbstractJni {    private static LibraryResolver createLibraryResolver() {        return new AndroidResolver(23);    }    private static AndroidEmulator createARMEmulator() {        return new AndroidARMEmulator("com.sun.jna");    }    private final AndroidEmulator emulator;    private final Module module;    private final VM vm;    private final DvmClass Native;    private JniDispatch128() {        emulator = createARMEmulator();        final Memory memory = emulator.getMemory();        memory.setLibraryResolver(createLibraryResolver());        vm = emulator.createDalvikVM(null);        vm.setJni(this);        vm.setVerbose(true);        // 自行批改文件门路        DalvikModule dm = vm.loadLibrary(new File("/Users/Desktop/unidbg/unidbg-android/src/test/resources/dylib/libcms.so"), false);        dm.callJNI_OnLoad(emulator);        module = dm.getModule();        Native = vm.resolveClass("com/ss/sys/ces/a");    private void destroy() throws IOException {        emulator.close();        System.out.println("destroy");    }    public static void main(String[] args) throws Exception {        JniDispatch128 test = new JniDispatch128();        test.test();        test.destroy();    }    public static String xuzi1(byte[] bArr) {        if (bArr == null) {            return null;        }        char[] charArray = "0123456789abcdef".toCharArray();        char[] cArr = new char[(bArr.length * 2)];        for (int i = 0; i < bArr.length; i++) {            int b2 = bArr[i] & 255;            int i2 = i * 2;            cArr[i2] = charArray[b2 >>> 4];            cArr[i2 + 1] = charArray[b2 & 15];        }        return new String(cArr);    }    private void test() {        String methodSign = "leviathan(II[B)[B";        byte[] data = "临时轻易写的,这里是url通过解决后的data".getBytes();        int time = (int) (System.currentTimeMillis() / 1000);        Native.callStaticJniMethod(emulator, methodSign, -1,time,new ByteArray(vm,data));        Object ret = Native.callStaticJniMethodObject(emulator, methodSign, -1,time,new ByteArray(vm,data));        System.out.println("callObject执行后果:"+((DvmObject) ret).getValue());        byte[] tt = (byte[]) ((DvmObject) ret).getValue();        System.out.println(new String(tt));        String s = xuzi1(tt);        System.out.println(s);    }}

运行main办法即可查看生成进去的xgorgon了


more articles

更多douyin技术文章,可查看专栏:

https://blog.csdn.net/weixin_43582101/category_9529769.html