frida 发布了新特性, 支持硬件断点, 能更好的对内存区域进行扫描, 并快速定位出哪段代码读写了这片内存区域
感兴趣的可以看下
贴上地址 https://frida.re/news/
为了测试这个新特性, 我自己写了一个app
当用户点击按钮, 数字就减去1
让我们来看看native层实现
1 | static int num = 1000; |
我们定义了一个全局静态变量, 每次用户点击button getInt函数就会被调用 并且返回-1后的值.
接下来我们试试用frida的新特性来快速分析一下, 看看到底是哪里实现了 -1 的操作.
根据官方文档
1 | let matches = []; |
我们执行一下
1 | frida -U my_md5 -l 00bang/tt.js |
然后执行
1 | scan(patternFromU32(1000)) |
结果如下
搜了一圈, 应该是还不支持linux, 于是决定改写一下
主要是这段代码报错了 Process.enumerateMallocRanges(), 枚举所有的 malloc动态申请的堆内存.
那这篇文章主题就应该是 frida 内存扫描.
我改写了一下代码, 如下
1 | let matches = []; |
然后执行一下
1 | linux_scan(patternFromU32(1000)) |
结果如下
结果有四处 都匹配的1000, 1000的16进制是 0x3e8 跟图中正好匹配. 看来匹配的没毛病
然后我们点击一下按钮, 数字变成了 999, 然后执行一下
1 | reduce(999) |
这个功能太强大了, 类似于 CE以及 GG修改器中的搜索, 在上一次搜索的基础上再次搜索.
就相当于看看1000中的四处, 现在有几处变成了 999, 结果如下
可以看到只有一处.
这时候可以该地址 减去 so的基地址. 可以通过 frida api 获取基址或者 通过下面代码查看基址
1 | cat /proc/$(pidof com.xx.my_md5 )/maps | grep checkout.so |
0x7ac95687d8 - 0x7ac951f000 = 0x497d8
ida打开 checkout.so 查看 0x497d8
可以看到 已初始化的全局静态变量 放在 .data 段, 并且值是 0x3E8, 对应十进制 1000
我们对该地址添加一个写断点, 看看哪里往该地址写入数据
1 | function installWatchpoint(address, size, conditions) { |
然后执行该函数, 结果如下
关注这个地址 0x7ac953dbbc
0x7ac953dbbc - so基址 = 0x1ebbc
ida查看地址 0x1ebbc
yyds!!!!!
最后放上完整代码
1 | let matches = []; |
回顾一下, 学到了什么
1、通过frida 扫描内存中的数字/字符串
2、定位存放关键数据的内存后, 对该地址下写断点, 当该地址的值发生变化后, 就知道是哪里的代码操作的了.