坦然 发表于 2020-12-6 16:02

unidbg初探

本帖最后由 坦然 于 2020-12-6 16:18 编辑

# 由来
前天有个吧友发了个使用unidbg模拟某app协议,觉得有点意思,于是乎今天来试试,论坛里unidbg的教程也比较少,那我就来抛砖引玉,献献丑了。还望大神勿喷。

# 优势
unidbg 是一个基于 unicorn 的逆向工具,可以黑盒调用安卓和 iOS 中的 so 文件。unidbg 是一个标准的 java 项目。
由于现在的大多数 app 把签名算法已经放到了 so 文件中,要想破解签名算法,必须能够破解 so 文件。C++ 的逆向远比 Java 的逆向要难得多了,所以好多时候是没法破解的,那么这个时候还可以采用 hook 的方法,直接读取程序中算出来的签名,但是这样的话,需要实际运行这个应用,需要模拟器或者真机,效率又不是很高(比如frida的rpc调用,就需要后台运行应用)。unidbg 就是一个很巧妙地解决方案,他不需要直接运行 app,也无需逆向 so 文件,而是通过在 app 中找到对应的 JNI 接口,然后用 unicorn 引擎直接执行这个 so 文件,所以效率也比较高。(复制百度)
# 需要工具
`安卓模拟器`(真机也可以)
`Fiddler`(用于抓包)
`jadx`(用于反编译apk)
`jeb`(用于反编译apk)
`firda`(用于分析apk)
`idea`(用于写代码)
`apk`(分析的apk)
# 前提
由于脱壳和反编译不是本文的重点,那么假设你已经脱壳并得到dex,且用jex和jadx定义到加密的地方。如下图

并且得到一组加密参数(原文两个参数)
原文 `参数一:/v1/login/mobile/code?mobile=13888888888&country_code=0086&__plat=android&__version=2.21.0&__app=inyu 参数二:1607237431 `
密文 `4e02b282da566a80b86c25cd2cb6e1ec`
# 正文开始
1、下载unidbg项目
      下载地址:https://github.com/zhkl0228/unidbg
2、导入到IDEA中
      unidbg项目用Java编写,并且上面下载的是一个标准的maven项目。我这里演示导入到IDEA中。
3、测试unidbg
      项目中的src/test/java/com/bytedance/frameworks/core/encrypt路径中有一个TTEncrypt测试用例,直接执行其中的main方法。
4、编写我们的调用类TestJni(基本上是个模板,需要改的地方,已经注释表明)
```
package com.tanran.test;

import com.github.unidbg.Module;
import com.github.unidbg.arm.ARMEmulator;
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 java.io.File;
import java.io.IOException;

public class TestJni extends AbstractJni {
    // ARM模拟器
    private final ARMEmulator emulator;
    // vm
    private final VM vm;
    // 载入的模块
    private final Module module;

    private final DvmClass TTEncryptUtils;

    /**
   *
   * @param soFilePath   需要执行的so文件路径
   * @param classPath    需要执行的函数所在的Java类路径
   * @throws IOException
   */
    public TestJni(String soFilePath, String classPath) throws IOException {
      // 创建app进程,包名可任意写
      emulator = new AndroidARMEmulator("io.liuliu.music");
      Memory memory = emulator.getMemory();
      // 作者支持19和23两个sdk
      memory.setLibraryResolver(new AndroidResolver(23));
      // 创建DalvikVM,利用apk本身,可以为null
      vm = ((AndroidARMEmulator) emulator).createDalvikVM(null);
      vm.setVerbose(true);
      vm.setJni(this);
      // (关键处1)加载so,填写so的文件路径
      DalvikModule dm = vm.loadLibrary(new File(soFilePath), false);
      // 调用jni
      dm.callJNI_OnLoad(emulator);
      module = dm.getModule();
      // (关键处2)加载so文件中的哪个类,填写完整的类路径
      TTEncryptUtils = vm.resolveClass(classPath);
    }

    /**
   * 调用so文件中的指定函数
   * @param methodSign 传入你要执行的函数信息,需要完整的smali语法格式的函数签名
   * @param args       是即将调用的函数需要的参数
   * @return 函数调用结果
   */
    private String myJni(String methodSign, Object ...args) {
       // 使用jni调用传入的函数签名对应的方法()
      Object value = TTEncryptUtils.callStaticJniMethodObject(emulator, methodSign, args).getValue();
      return value.toString();
    }

    /**
   * 关闭模拟器
   * @throws IOException
   */
    private void destroy() throws IOException {
      emulator.close();
      System.out.println("emulator destroy...");
    }

    public static void main(String[] args) throws IOException {
      // 1、需要调用的so文件所在路径
      String soFilePath = "unidbg-android/src/test/resources/myso/libinyu-lib.so";
      // 2、需要调用函数所在的Java类完整路径,比如a/b/c/d等等,注意需要用/代替.
      String classPath = "water/android/io/inyustring/InyuString";
      // 3、需要调用方法,再jadx中找到对应的方法,然后点击下面的Smail,复制方法的Smail代码。
      String methodSign = "getUrlSign(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
      TestJni testJni = new TestJni(soFilePath, classPath);
      // 输出getGameKey方法调用结果
      System.err.println(testJni.myJni(methodSign,"/v1/login/mobile/code?mobile=13888888888&country_code=0086&__plat=android&__version=2.21.0&__app=inyu","1607237431"));
      testJni.destroy();
    }
}
```
5、运行看结果


虽然报了个错,但是结果还是输出来了。(与目标结果一致)有大神如果知道哪里的问题,请告知下小弟。

# 参考资料
https://www.52pojie.cn/forum.php?mod=viewthread&tid=1321190&highlight=unidbg
https://blog.csdn.net/qq_41855420/article/details/106265603
https://www.cnblogs.com/xbjss/p/12110083.html

# 附件

Dispa1r 发表于 2020-12-8 12:33

其实我觉得unidbg的一系列集成的hook框架才是精华,http://caicai.gold/2020/05/01/undbg-0x2/,可惜已经不做这些了,还要unidbg的unpack功能,也很有意思

AnxiangLemon 发表于 2022-4-7 02:12

Exception in thread "main" java.lang.IllegalStateException: Illegal JNI version: 0xffffffff
        at com.github.unidbg.linux.android.dvm.BaseVM.checkVersion(BaseVM.java:206)
        at com.github.unidbg.linux.android.dvm.DalvikModule.callJNI_OnLoad(DalvikModule.java:39)
        at com.bytedance.frameworks.core.day1.EncryptUtilsJni.<init>(EncryptUtilsJni.java:136)
        at com.bytedance.frameworks.core.day1.EncryptUtilsJni.main(EncryptUtilsJni.java:175)

啥情况这是? 用的楼主demo? 是不是少传了so 还是什么环境

williamblake 发表于 2020-12-6 16:25

感谢楼主分析,很有用

Henryhaohao 发表于 2020-12-6 16:32

感谢楼主大佬分析,很有用!

d0gkiller87 发表于 2020-12-7 03:02

牛B,感谢大佬分享

TickDown 发表于 2020-12-7 10:31

学习了 感觉很有用 {:17_1062:}

编程小手 发表于 2020-12-7 13:26

学习之中,希望楼主更多帖子:lol

mengfang1 发表于 2020-12-7 13:43

感谢!!!!!!!!学习!

Tonywey 发表于 2020-12-7 20:59

大佬厉害,学习ing

whngomj 发表于 2020-12-8 07:53

学习之中

zipl1985 发表于 2020-12-8 08:25

学习了,学习
页: [1] 2 3 4
查看完整版本: unidbg初探