0-前言
之前用ai结合unidbg操作的有点云里雾里,手似懂非懂,脑子也是什么都没学到,所以单独写一个关于unidbg的笔记,学习视频是大佬的黑盒魔法之Unidbg,课件:《安卓逆向这档事》吾爱破解等
1-准备
为了更好的trace可以对如下进行更改
1
| log4j.logger.com.github.unidbg.linux.file=DEBUG
|

1>>常用知识储备
①.在IDA Pro里的“Exports”
“别人可以直接调用我的哪些函数?”
②.DT_SONAME 代表库名
- 在 Android 中,系统加载器(Linker)识别一个库到底叫什么,不是看它的文件名,而是看它 ELF 头部里
DT_SONAME 这个字段。
③.trace与js逆向里相似
- 可以使用Trace进行汇编的导出,但请注意指令级的 Trace (
traceCode) 颗粒度太细了,分分钟会爆炸。
④.Unidbg对32位更完善
(随着时代发展可能会变)

⑤.常用api模块对比
| 模块 |
作用 |
| Emulator |
CPU + 进程 + 执行 |
| Memory |
内存 + SO + 指针 |
| VM |
Java 层 |
Ⅰ. 常用 Emulator API
| 方法名(签名) |
返回类型 |
简短描述 |
在 unidbg 中是否存在 / 备注 |
getMemory() |
Memory |
获取内存操作接口(读写/映射/断点等) |
示例:Memory memory = emulator.getMemory(); |
getPid() |
int |
获取模拟进程的 PID |
通常用于日志/区分多个 emulator 实例。 |
createDalvikVM() |
VM 或 DalvikVM(类名会有变体) |
创建一个 Dalvik/Android 虚拟机(无 APK) |
vm = emulator.createDalvikVM(); |
createDalvikVM(File apkFile) |
VM |
使用指定 APK 创建虚拟机(会把 APK 的 dex/classPath 加入 VM) |
常用:vm = emulator.createDalvikVM(new File("xxx.apk")); |
getDalvikVM() |
VM |
获取已创建的虚拟机实例(如果有) |
vm = emulator.getDalvikVM();(若之前 create 过) |
showRegs() |
void |
打印/显示当前寄存器状态(可指定寄存器) |
(用于调试,输出寄存器信息)。 |
getBackend() |
Backend |
获取后端 CPU(Unicorn 后端)接口 |
用于低层操作或获取后端信息。 |
getProcessName() |
String |
返回模拟的进程名(你在构建时可设置) |
由 AndroidEmulatorBuilder.setProcessName(...) 指定。 |
getContext() |
RegisterContext |
获取当前寄存器上下文(用于读写寄存器) |
类型名可能根据版本为 RegisterContext 或具体实现。 |
traceRead(long begin, long end) |
void |
打开内存读跟踪(指定地址范围) |
可用于监测某地址区间被读取。 |
traceWrite(long begin, long end) |
void |
打开内存写跟踪(指定地址范围) |
常用于找写入密钥/解密表的地方。 |
traceCode(long begin, long end) |
void |
跟踪/打印执行的汇编指令(指定地址范围) |
用于动态分析执行流/断点辅助。 |
isRunning() |
boolean |
判断当前 Emulator 是否正在运行(线程/CPU) |
通常用于控制循环或调试。 |
Ⅱ.Memory 常用API
| 方法名(签名) |
返回类型 |
作用说明 |
setLibraryResolver(AndroidResolver resolver) |
void |
设置 Android 系统库解析器(决定如何加载 libc、libm 等) |
getStackPoint() |
long |
获取当前栈指针(SP)位置 |
pointer(long address) |
UnidbgPointer |
将一个地址包装成指针对象(方便读写内存) |
getMemoryMap() |
Collection<MemoryMap> |
获取当前内存映射(类似 /proc/self/maps) |
findModule(String moduleName) |
Module |
根据模块名查找已加载的 SO |
findModuleByAddress(long address) |
Module |
根据地址查找所属模块 |
loadLibrary(File file, boolean forceLoad) |
ElfModule |
手动加载 SO(底层调用 linker) |
allocateStack(int size) |
UnidbgPointer |
在栈上分配一段空间 |
writeStackString(String value) |
UnidbgPointer |
往栈里写字符串(返回指针) |
writeStackBytes(byte[] value) |
UnidbgPointer |
往栈写字节数组 |
malloc(int size, boolean runtime) |
UnidbgPointer |
分配堆内存(类似 C 的 malloc) |
Ⅲ.VM 常用 API
| 方法名(签名) |
返回类型 |
作用说明 |
createDalvikVM(File apkFile) |
VM |
创建虚拟机并加载 APK(dex) |
setVerbose(boolean verbose) |
void |
是否打印 JNI / VM 日志 |
loadLibrary(File soFile, boolean callInit) |
DalvikModule |
加载 SO 文件(可选择是否调用 init) |
setJni(Jni jni) |
void |
设置 JNI 回调接口(你自己实现) |
getJNIEnv() |
Pointer |
获取 JNIEnv 指针 |
getJavaVM() |
Pointer |
获取 JavaVM 指针 |
callJNI_OnLoad(Emulator emulator, Module module) |
void |
手动调用 JNI_OnLoad |
addGlobalObject(DvmObject<?> obj) |
int |
添加全局引用对象 |
addLocalObject(DvmObject<?> obj) |
int |
添加局部引用对象 |
getObject(int hash) |
DvmObject<?> |
根据引用 ID 获取对象 |
resolveClass(String className) |
DvmClass |
解析类(核心 API) |
getPackageName() |
String |
获取 APK 包名 |
getVersionName() |
String |
获取版本名 |
getVersionCode() |
String/int |
获取版本号 |
openAsset(String assetName) |
InputStream |
读取 APK assets 文件 |
getManifestXml() |
String |
获取 AndroidManifest.xml 内容 |
getSignatures() |
CertificateMeta[] |
获取 APK 签名信息 |
findClass(String className) |
DvmClass |
查找已加载类 |
getEmulator() |
Emulator<?> |
获取 emulator 实例 |
2>>熟悉常见api
1 2 3 4 5 6 7 8 9 10 11 12
| emulator = AndroidEmulatorBuilder.for64Bit() .setProcessName("com.xxxx.app") .addBackendFactory(new Unicorn2Factory(true)) .build();
|
1 2 3
| Module module = memory.findModule("libxxx.so"); long base = module.base;
|
1 2 3
| UnidbgPointer ptr = memory.pointer(0x12345678); int value = ptr.getInt(0);
|
1 2
| UnidbgPointer buf = memory.malloc(0x100, true);
|
1 2 3 4 5 6 7
| vm = emulator.createDalvikVM(new File(apkPath)); vm.setVerbose(true);
vm.setJni(this);
new AndroidModule(emulator, vm).register(memory);
|
1 2 3
| VM dalvikVM = createDalvikVM(new File("apk file path"))
|
1 2 3 4 5 6 7 8 9 10 11
| DalvikModule dm = vm.loadLibrary("xxx", false);
hook_xxx();
module.callEntry(emulator); dm.callJNI_OnLoad(emulator);
|
待续。。。