Frida和调试器共存的问题

当我们希望同时使用调试器与Frida时,这个问题就会出现——似乎无法同时使用调试器(诸如IDA,GDB)和Frida。这会带来一些不便,先说一下两者一同使用的好处:

IDA调试时,我们往往需要对App进行下拉、刷新、点击等操作从而触发需要调试的函数,很难保证每次情景都能复现(因为入参不同),也可能业务逻辑跑了好几圈才到我们的目标函数,很麻烦,调试时App还有失联的问题(手机以为App卡了,傻不拉几的提醒你要不要把这个App关了)。如果使用Frida主动调用我们想要调试的函数,那就完全不一样了。主动调用目标函数,既可以保证每一次重新调试时环境完全一样,数据流稳定,又不用担心App崩溃,稳定的一批。

为什么会出问题呢?这是因为大名鼎鼎的ptrace。Ptrace提供对进程追踪的功能,能在一个进程里观察与控制另一个进程的运行状态,Ptrace有许多用法,如下。

  • 编写调试器,如GDB
  • 反调试,一个进程只能被一个进程追踪,若此进程已被追踪,其他基于ptrace的追踪器将无法再追踪此进程,更进一步可以实现子母进程双线执行动态解密代码等更高级的反分析技术
  • 代码注入,往其他进程里注入代码。
    引自:https://blog.betamao.me/2019/02/02/Linux%E6%B2%99%E7%AE%B1%E4%B9%8Bptrace/

诸如GDB等调试器都重度依赖ptrace,而Frida恰巧也要用ptrace,一个进程不能被两个进程同时追踪,因此就会导致占用和堵塞,鱼和熊掌只能选其一。

调试器会使用ptrace是铁定的事实,Frida是啥时候使用ptrace的?我们测试一下,首先我们启动手机上的frida server,我的server习惯根据版本命名,你呢?
在这里插入图片描述
接下来选择测试App,我这边测试app为myend,读者也可以下载这个App试试,因为随便挑选商用App测试,很可能有反调试啥的,没有效果。(心累,现在App防护措施真是五花八门。)
启动myend这个app,先看一下进程ID,我这里是21554。

#Windows
frida-ps -U | findstr myend
#Linux/Mac
frida-ps -U | grep myend

在这里插入图片描述
然后查看这个进程的信息
在这里插入图片描述

cat /proc/{pid}/status

ptrace 为0,即意味着这个进程现在还没有被ptrace,接下来我们frida attach这个进程试一下。
在这里插入图片描述
再来看一下进程状况,你会发现TracerId依然为0,这是怎么回事呢?
Frida没用到ptrace?当然不是。Frida作者大胡子一句话就说的很清楚了——“Our injector needs to ptrace() the target briefly while attaching on Linux/Android.”,即attach app时只是短暂的使用了ptrace,就用了那么一下下,用完就detach分离掉了。

既然这样,是不是能先运行Frida,attach App,运行脚本,再用IDA/GDB调试即可?

我们使用Strace来测试一下,Strace 是Linux下的调试利器,它可以跟踪所有的系统调用,打印系统调用的参数和返回值,还可以指定跟踪子线程/子进程,andriod 使用了Linux操作系统,因此也可以使用strace。(ps.strace其实也是基于ptrace搞的。)

并不是所有的手机都自带strace,我们下载一下strace,根据自己的架构选择对应的文件,我这里选择arm64。

adb push 到/data/local/tmp下
adb push C:\Users\Lenovo\Downloads\strace /data/local/tmp
Strace有两种基本用法

  1. strace <elf_file> 启动该Elf程序,同时跟踪执行流程
  2. strace -p pid 对于已经启动的程序,通过-p参数attach,跟踪执行流程;

我们选择第二种,除此之外,我们还需要追踪其子线程以及过滤ptrace

-f: 同时追踪子进程的系统调用情况(如果是多线程程序的话,会同时追踪所有线程)。如果不加 -f 参数的话默认只追踪指定的单个进程。
-e : 过滤事件,只输出符合规则的事件,可以用来指定只看某些系统调用的情况
-p : 附加到进程中,记录某个进程的系统调用和进程信号信息。多个 -p 可以实现同时追踪多个进程。
Strace更多操作可以看这篇文章

接下来我们找一下Frida相关的进程,笔者对frida具体哪个线程起作用也不甚了解,我们ptrace这两个进程
在这里插入图片描述
在这里插入图片描述
接下来我们frida attach app,随便加载一个脚本
在这里插入图片描述
Strace内容如下,确实使用了一些ptrace,最后Detach结束了对进程的追踪。此后IDA就可以正常附加该App。
./mystrace -f -s 128 -e trace=ptrace -p 19487
我们知道,Frida脚本修改后,会自动进行热加载,重新注入新脚本,这个过程需要Ptrace吗?会不会因此和调试器冲突?我们%reload手动重新加载一下脚本,发现strace追踪的情况并无变化,呼,不影响,大功告成。

如果想实现更多花哨的操作,可以参考这个,对Frida server进行定制化编译。

后记:2020/3/25晚十点突然很饿,大吃两碗饺子,以及一大碗番茄,感觉很爽,我永远喜欢这样强烈的食欲,以及强烈的求知欲,强烈的,燃烧的,狂野的……各种各样的欲望。永远年轻,用于燃烧,永远热泪盈眶,永远狂热的追索。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Frida 是一款强大的动态分析工具,可以用于在运行时对应用程序进行动态修改,例如 Hook 某些函数、修改函数的返回值、修改变量的值等。下面是使用 Frida 进行动态调试的步骤: 1. 安装 Frida:在命令行中使用 pip install frida 进行安装。 2. 在需要进行动态调试的应用程序中添加 Frida 的依赖:在 Gradle 文件中添加以下依赖: ``` implementation 'com.github.frida:frida-gson:12.4.5' implementation 'com.github.frida:frida-android:12.4.5' ``` 3. 在应用程序中初始化 Frida: ``` FridaAndroid.initialize(); ``` 4. 在需要进行动态调试的地方添加 Frida 的 Hook 代码: ``` FridaAndroid.attach(this); FridaAndroid.executeJavaScript("Interceptor.attach(Module.findExportByName(null, '函数名'), {onEnter: function(args) {console.log('参数1:', args[0].readCString());console.log('参数2:', args[1].readCString());}});"); ``` 其中,函数名为需要进行动态调试的函数名。 5. 运行应用程序,并在命令行中使用 Frida 的命令进行 Hook: ``` frida -U com.example.packagename -l hook.js --no-pause ``` 其中,com.example.packagename 为需要进行动态调试的应用程序的包名,hook.js 为 Hook 代码所在的 JavaScript 文件。 6. 在命令行的输出中查看 Hook 的结果,以及在 Android Studio 的 Logcat 中查看输出信息。 需要注意的是,在使用 Frida 进行动态调试时,需要先将应用程序安装在设备上,并且需要在设备上启动应用程序后才能进行动态调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值