本文来自互联网,我只是收集整理,unidbg作者写这个东西不容易,有条件的小伙伴可以去支持一下
unidbg是一个允许你用来模拟执行Android的ELF和的IOS的MachO原生文件。
Elf文件:从组成结构上可以看得出他主要是服务于section的,而section又是so的资源,所以狭义上我们可以理解成此表为告诉计算机要怎么加载解析so资源的一张表.
unidbg可以帮助你快速上手一个Elf文件,以一个黑盒的形式来模拟执行其中的代码,就像Android中那样,而无需关心它是如何实现的,大大降低了逆向分析的成本。而相应的就是性能的开销(因为涉及到指令转换,就像虚拟机),如果使用unidbg来模拟执行运算结果,那运行效率也会大打折扣。但是如果是把它作为一个工具,帮助你对Elf文件做动态分析,unidbg的调试功能真的是相当nice的。可以这么说:在undibg中,一切可控。
unidbg的特性有:
- 模拟 JNI 调用 API,因此可以调用 JNI_OnLoad
- 支持 JavaVM、JNIEnv
- 模拟系统调用指令
- 支持 ARM32 和 ARM64
- 支持 Inline hook, 感谢 Dobby
- 支持 GOT hook, 感谢 xHook
- iOS fishhook 和 substrate 和 whale hook
- unicorn 后端支持简单的控制台调试器、gdb 存根、指令跟踪、内存读/写跟踪
- 支持 iOS objc 和 swift 运行时
- 支持 dynarmic 快速后端
- 支持 Apple M1 hypervisor,最快的 ARM64 后端
- 使用 Raspberry Pi B4 支持 Linux KVM 后端
快速上手
unidbg对新手比较友好,在github上下载unidbg的源码之后,我们通过IDEA导入(IDEA正版授权码可以上各大电商平台搜索,几块钱用一年),导图后目录结构如下:
在项目的unidbg-android子模块中的src/test目录下,包含了几个体验Demo,您可以尝试将Demo运行起来,即可看到unidbg的效果。当然你也可以通过如下示例快速上手:
//1.创建Android模拟器实例
AndroidEmulator emulator = AndroidEmulatorBuilder
// 模拟32位系统
.for32Bit()
// Backend的作用是用来模拟执行机器指令
.addBackendFactory(new DynarmicFactory(true))
// 构建一个模拟器
.build();
//2.获取操作内存的接口
Memory memory = emulator.getMemory();
//3.设置库解析器(SDK版本)
memory.setLibraryResolver(new AndroidResolver(23));
//4.创建虚拟机
VM vm = emulator.createDalvikVM();
//5.加载ELF文件file_path中传入你需要逆向的so路径
Module module = emulator.loadLibrary(new File("file_path"), true);
//6.调用JNI_OnLoad
vm.callJNI_OnLoad(emulator, module);
//此时ELF将加载到内存,可以对其做任意操作
//7.创建DvmObject
DvmObject<?> obj = ProxyDvmObject.createObject(vm, this);
//8.模拟执行目标函数
boolean result = obj.callJniMethodBoolean(emulator, "jnitest(Ljava/lang/String;)Z", "arg");
//9.打印执行结果
System.out.println("执行结果:"+result);
下面,我们以上述代码为索引,和大家介绍下这些Api的使用和详细使用方法。
AndroidEmulator
AndroidEmulator是一个抽象的Android模拟器接口。它作为一个枢纽,协调unidbg中大多数模块相互工作。我们需要的大多数操作也都需要借助于它。
创建AndroidEmulator实例
使用AndroidEmulatorBuilder可以来帮助你快速创建一个AndroidEmulator的实例。
AndroidEmulator emulator = AndroidEmulatorBuilder
//指定32位处理器
.for32Bit()
//指定64位处理器
//.for64bit()
//添加后端工厂
.addBackendFactory(