大杀器Unidbg真正的威力

有图有真相 Unidbg的杀手锏 CPU指令级别Trace

ps :Unidbg跟010Editor更配哦!

图片描述


上干货

今天作者就来带大家以自身使用的经验去了解一下Unidbg!

上面那张图片呢,用的就是小弟魔改的UnidbgTraceCode出来的文件,通过Trace方法可以快速定位某个函数在指令级别的作用,帮助逆向人员更快的分析出想要的算法.

当然Unidbg能做的远远不止这些,本文并不是一篇科普文,所以本文假定读者都是有一定基础的同学.

callFunction:

如果你仔细观摩过Uniidbg源码的话,你会发现所有callJniMethodObject最终都会并入一个叫callFunction的函数.
那么我们在分析So的过程中,发现了一个非JNI函数能不能主动调用呢?
答案是:必须能.

这种好处的体现在于,逆向人员不必使用Jni函数去分析大量的无用代码,而是能精确的定位一个小的Func的具体作用,以及算法逻辑.

通过该函数我们能得到这个小函数在内部到底做了什么操作,并且能Trace出更精确的指令文件

1

2

3

4

5

6

7

8

9

10

11

public final Number[] callFunction(Emulator<?> emulator, String symbolName, Object... args) {

    Symbol symbol = findSymbolByName(symbolName, false);

    if (symbol == null) {

        throw new IllegalStateException("find symbol failed: " + symbolName);

    }

    if (symbol.isUndef()) {

        throw new IllegalStateException(symbolName + " is NOT defined");

    }

    return symbol.call(emulator, args);

}

该函数的第一个参数毋庸置疑是当前的模拟器

1

emulator = createARMEmulator();

第二个参数可以是导出函数名,或者是指定地址偏移

后面的参数就是个变长的参数列表,由逆向人员分析得到.

当然如果你是进行so内部函数调用的话,你大概率会填充一个指针,这里在给大家分享一段自己填充char* 类型的函数源码,别的类型参数同理,不在赘述.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

private static void CallVMPFunc(Module module,AndroidEmulator emulator){

    try {

        Symbol malloc = module.findSymbolByName("malloc");

        Symbol free = module.findSymbolByName("free");

        MemoryBlock block = MemoryAllocBlock.malloc(emulator,malloc,free,0x1000);

        MemoryBlock namebyte = MemoryAllocBlock.malloc(emulator,malloc,free,0x1000);

        UnidbgPointer blockpoint = block.getPointer();

        UnidbgPointer namepoint = namebyte.getPointer();

        String name = "magicillusion";

        String data = "hello worid";

        namepoint.write(name.getBytes());

        blockpoint.write(data.getBytes());

    Number[] ret = module.callFunction(emulator,0x13B30+1,namepoint,blockpoint,2);

    UnidbgPointer ret1 = new UnidbgPointer(emulator,ret[0].intValue(),4);

        String string = ret1.getString(0);

    System.out.println("Number => " +  (string));

    finally {

    }

}

大杀器内置的HOOK框架

当然Unidbg还内置了多种HOOK框架,今天讲一个分析So比较实用的一款HookZz

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

// 1. 获取HookZz对象

IHookZz hookZz = HookZz.getInstance(emulator); // 加载HookZz,支持inline hook,文档看https://github.com/jmpews/HookZz

// 2. enable hook

hookZz.enable_arm_arm64_b_branch(); // 测试enable_arm_arm64_b_branch,可有可无

index = 0;

hookZz.replace(module.findSymbolByName("lrand48"), new ReplaceCallback() {

    @Override

    public void postCall(Emulator<?> emulator, HookContext context) {

            ((EditableArm32RegisterContext)context).setR0(0x12345678);

        int ptrace_args0 = context.getIntArg(0);

        System.out.println("lrand48=" + ptrace_args0);

    }

},true);

//aesdecode hook

hookZz.wrap((module.base)+0x39634+1, new WrapCallback<RegisterContext>() { // inline wrap导出函数

    UnidbgPointer addr = null;

    @Override

    // 4. 方法执行前

    public void preCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {

        addr= ctx.getPointerArg(0);

        UnidbgPointer pointerArg = ctx.getPointerArg(1);

        UnidbgPointer pointer = pointerArg.getPointer(12);

        int anInt = pointerArg.getInt(8);

        byte[] byteArray = pointer.getByteArray(0, anInt);

        String s =xuzi1(byteArray);

        System.out.println("aes aesdecode= " + s);

    }

    @Override

    // 5. 方法执行后

    public void postCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {

        byte[] aaaa = addr.getPointer(0).getPointer(12).getByteArray(0,0x30);

        String s =xuzi1(aaaa);

        System.out.println("aes aesdecode1= " + s);

    }

});

同理,此框架也支持导出函数HOOK以及InlineHOOK 有了这个方法,在你分析一些函数的时候,可以充当Log的效果 或者强行改变一些函数的返回值让你更容易的分析,比如本例中笔者改变了Lrand48的返回值,让函数每次都强行返回0x12345678,这样在逆向分析的时候能让一些不确定性变成可控性.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值