Unidbg 问题汇总(一)

1.Long参数的传递

假设一个native函数中参数是long类型,比如这样

在这里插入图片描述

在编译成arm32的SO时,一定概率会被转成两个int.

long a = 0x1000L → int a1 = 0,int a2 = 0x1000

在Unidbg主动调用时,一定要记得处理,否则会出问题.这是一个常见问题,JAVA层传入的时间戳,常常就是jlong.

处理办法有2

1是按照SO的情况,传给它两个int

2是按照传入诸如 long tm= 1621265630L;的标准写法,Unidbg自动帮我们分割成两个

Unidbg 问题汇总(一)_第1张图片

2.jbytearray 怎么查看

更宽泛的问法是,有个jobject对象,想查看它的内容,最常见的就是jbyteArray

Frida中可以这么操作

hexdump(ptr(Java.vm.tryGetEnv().getByteArrayElements(args[0])))

Unidbg中当然也可以,以hookZz中为例

public void preCall(Emulator<?> emulator, HookZzArm32RegisterContext ctx, HookEntryInfo info) {
    UnidbgPointer jbytearrayptr = ctx.getPointerArg(2);

    DvmObject<?> dvmbytes = vm.getObject(jbytearrayptr.toIntPeer());
    // 取出byte
    byte[] result = (byte[]) dvmbytes.getValue();
    // 转换成String 或者按需转成其他
    System.out.println(new String(result));
};

3.std::string 的读写

public String readStdString(Pointer strptr){
    Boolean isTiny = (strptr.getByte(0) & 1) == 0;
    if(isTiny){
        return strptr.getString(1);
    }
    return strptr.getPointer(emulator.getPointerSize()* 2L).getString(0);
}

public void writeStdString(Pointer strptr, String content){
    Boolean isTiny = (strptr.getByte(0) & 1) == 0;
    if(isTiny){
        strptr.write(1, content.getBytes(StandardCharsets.UTF_8), 0, content.length());
    }
    strptr.getPointer(emulator.getPointerSize()* 2L).write(0, content.getBytes(StandardCharsets.UTF_8), 0, content.length());
};

4.TraceCode为什么trace不到module init中的指令

Unidbg 问题汇总(一)_第2张图片

是因为traceCode的执行时机晚了,load library在它前面…只需要确认module base 和module size后,将emulator.traceCode写在loadlibrary前面即可.

5.HOOK 框架使用问题

Unidbg支持了数个Hook框架,HookZz和Dobby就是其中两个.有人会困惑,HookZz不就是Dobby前身吗,两者不是一个东西吗?为什么要说两个Hook框架?

这其实是有原因的,Unidbg作者在注释中写道:HookZz在arm32位上支持较好,Dobby在64位上支持较好.(因此将两者,或者说Dobby以及其前身HookZz作为两个独立Hook工具)

你可能感兴趣的:(SO逆向实战十三篇)