最新消息:本站技术交流 QQ 群:28124927

【Frida 实战】如何拦截 sub_xxxx 这种函数

iOS/MacOSX/移动安全 exchen 5579浏览 0评论

本文是 Frida 实战系列教程的第三篇,讲解如何拦截 sub_xxxx 这种函数,以及如何替换和调用原始函数。

第一篇:https://www.ioshacker.net/thread-360-1-1.html

第二篇:https://www.ioshacker.net/thread-379-1-1.html

在 IDA 里看到的 sub_xxxx 这种类型的函数是因为没有符号,所以 IDA 解析时就显示 sub_xxxx,其中 xxxx 是 IDA 读取到的函数地址。在第二篇教程中,我们初步学习了拦截器(Interceptor)的使用,知道了怎么拦截函数,但是如果是自定义函数,去掉符号信息可能就没有名称,我们该怎么拦截呢?下面我们来实际操作,自定义一个静态函数,名称是 add,功能就是将第一个参数和第二个参数相加,返回相加的结果,然后调用 add 函数时第一个参数和第二个参数都传入 1,执行之后会打印出 “1 + 1 = 2",具体代码如下:

编译成功之后,执行下面的命令即可去掉符号。这时使用 IDA 查看可执行文件只会显示 sub_xxxx 这类名称,没有函数的真实名称。

接下来开始编写 frida 脚本,get_func_addr 是我们定义的一个函数用来获取函数地址的,需要传入两个参数,第一个参数是模块的名称,第二个参数是在 IDA 里看到的函数地址。查看这个地址的方法,我一般是在 IDA 里将基址设为 0,然后定位到目标函数,此时的地址就是函数地址。得到地址之后就可以使用 Interceptor.attach() 拦截函数。

执行 frida 附加进程并加载 test.js 脚本

有时候目标函数是在进程启动后马上就触发,使用附加的方式可能来不及注入脚本,函数就已经触发了。这种情况可以先退出进程,使用 -f 参数直接启动进程,可以在启动时马上注入脚本。需要注意的是进程名称填写的是包名。

此时进入交互模式,然后输入 %resume,让进程继续运行,不然过一会进程会被强制退出,如果不想每次都输入 %resume,就添加 --no-pause 参数,这样在运行进程时不会暂停。

脚本执行后会打印出基址、基址内存中的数据、add 函数地址、add 函数内存中的数据,信息如下:

为什么要将可执行文件的基址数据和 add 函数内存中数据打印出来呢?这是为了验证我们获取到的地址是否正确,比如基址内存中的数据是 cf fa ed fe,说明是 Mach-O 头部,确实是可执行文件。打印出 add 函数内存中的数据也是为了验证结果,查看函数内存中的数据与 IDA 里看到的十六进制机器码对比是否一致,如果不一致说明获取到的函数地址是错误的,如果一致代表正确。IDA 里看到的十六进制机器码数据如下图所示,图中的原本是显示的函数名是 sub_6684,为了演示方便,我没有去掉符号,所以显示是函数原始名称 add。

当 add 函数触发时,在调用 add 函数时会打印出 “1 + 1 = 3”,因为返回值被替换成 3。

Interceptor.attach() 拦截到相应的函数时不能阻止原始函数的执行,比如有些情况,我们不想执行原始函数,或者是判断参数达到某个条件时才执行原始函数,否则不执行,这种情况可以使用 Interceptor.replace() 来替换原始函数,比如下面这段代码可以替换掉 add 函数, NativeFunction 里有三个 int,分别代表是返回值、第一个参数、第二个参数。

有些情况我们需要拦截系统的函数,比如要拦截 open 函数,可以使用下面的代码。

转载请注明:exchen's blog » 【Frida 实战】如何拦截 sub_xxxx 这种函数

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址