unidbg支持多种Hook框架,如HookZz、Dobby、xHook、whale等。此处我们使用HookZz来完成对32位so程序的Hook。
首先修改build/native-lib.cpp文件,如下所示,添加add函数来完成绝对值相加的操作。
接着重新编写MainActivity.java代码,并模拟执行add()方法,如图3—17所示。
图3—17 模拟执行add()方法
成功模拟执行add()方法后,接下来在MainActivity.java中编写hook()方法,如图3—18所示。
图3—18 hook()方法
首先通过HookZz.getInstance()方法获取到HookZz实例,然后调用它的replace()方法。
replace()方法的第一个参数是需要被Hook的函数的首地址,可以通过IDA来查看,如图3—19所示。由于这里使用thumb指令集,因此需要对地址进行+1操作。
图3—19 IDA查看add函数地址
第二个参数是ReplaceCallback回调类,通过新建一个匿名内部类来传入。ReplaceCallback类有三个方法可供重写,其中两个onCall()方法是在函数执行之前执行,postCall()方法是在函数执行结束之后执行。postCall()方法默认是不执行的,需要配置第三个参数enablePostCall为true来启用。
onCall()有两个可重写的方法,区别在于是否带有参数context,该参数可用于读写寄存器相关内容。
在main()方法的“mainActivity.callAdd();”前调用该hook方法进行Hook,运行,可以观察到相应函数的Hook的执行流程,如图3—20所示。
图3—20 Hook的执行流程
对于onCall()方法,可以在函数执行前获取和修改函数的参数,如图3—21所示。
对于postCall()方法,可以借助后端工厂来进行寄存器的写入操作,以达到修改返回值的目的,如图3—22所示。
图3—21 调用onCall()方法获取和修改函数的参数
图3—22 调用postCall()方法修改返回值