# 补环境

# 运行流程

对于 unidbg 来讲,整体的运行流程如下:

构造方法:

  • 构建模拟器实例
  • 创建虚拟机
  • 加载 so
  • 调用 jni_onload (针对构造方法)

mian:

  • 初始化类实例
  • 调用方法,计算参数

这样一来,主要的逻辑就在所编写的对应方法中,这样一来,我们只需要针对不同的 native 方法编写对应的逻辑,调用即可。但随之而来了一些问题,比如,依赖了其他的 so 文件,对于使用了 java 层的方法,在 unidbg 中没有实现,在 native 类中调用了其他的静态方法等等。

对于这些问题,我们就需要手动的补出对应的环境,解决对应的问题。

# 类型介绍
# String

在 java 中对于字符串类型啥的,都直接通过 String str 声明,但是在 Unidbg 中有所不同

new StringObject(vm, "12345")

跟进去看

image-20220808150043257

然后这里也其实就相当于

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 不存在
  • 动态函数

image-20220808173958950

这种的就需要借助 jnitrace

直接 pip install jnitrace

Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

Mr2 WeChat Pay

WeChat Pay