# 补环境
# 运行流程
对于 unidbg 来讲,整体的运行流程如下:
构造方法:
- 构建模拟器实例
- 创建虚拟机
- 加载 so
- 调用 jni_onload (针对构造方法)
mian:
- 初始化类实例
- 调用方法,计算参数
这样一来,主要的逻辑就在所编写的对应方法中,这样一来,我们只需要针对不同的 native 方法编写对应的逻辑,调用即可。但随之而来了一些问题,比如,依赖了其他的 so 文件,对于使用了 java 层的方法,在 unidbg 中没有实现,在 native 类中调用了其他的静态方法等等。
对于这些问题,我们就需要手动的补出对应的环境,解决对应的问题。
# 类型介绍
# String
在 java 中对于字符串类型啥的,都直接通过 String str 声明,但是在 Unidbg 中有所不同
new StringObject(vm, "12345") |
跟进去看
然后这里也其实就相当于
DvmObject(vm.resolveClass("java/lang/string"), value) |
# Byte []
与 String 类似
String input = "123"; | |
byte[] inputByte = input.getBytes(StandardCharsets.UTF_8); | |
ByteArray inputByteArray = new ByteArray(vm,inputByte); |
# Content (上下文)
content 类由于 unidbg 中未实现,所以需要手动实现一下
DvmObject<?> context = vm.resolveClass("android/content/Context").newObject(null) | |
// 这里的 newObject 其实就是相当于给 DvmObject 了个 value 原理还是和上述类似 | |
public DvmObject<?> newObject(Object value) { | |
return new DvmObject<>(this, value); | |
} |
这里给 null 主要是因为,这玩意一般是用于计算签名参数,所以给任何值都无所谓,只要在 so 计算签名的时候 patch 掉就行。
# 补环境
在补环境之前,先把日志打开,这样就可以看到运行流程中的
import org.apache.log4j.Level; | |
import org.apache.log4j.Logger; | |
*** | |
public static void main(String[] args) { | |
Logger.getLogger(DalvikVM.class).setLevel(Level.DEBUG); | |
Logger.getLogger(BaseVM.class).setLevel(Level.DEBUG); | |
} |
接下来介绍两种类型的补法:
- 普通函数
java.lang.UnsupportedOperationException: | |
android/app/ActivityThread->sPackageManager:Landroid/content/pm/IPackageManager; | |
at com.github.unidbg.linux.android.dvm.AbstractJni.getStaticObjectField(AbstractJni.java:103) | |
// 意思是 在运行getStaticObjectField方法时,签名为android/app/ActivityThread->sPackageManager:Landroid/content/pm/IPackageManager 不存在 |
- 动态函数
这种的就需要借助 jnitrace
直接 pip install jnitrace