过某交友软件frida反调试
过某交友软件frida反调试
今天在分析一款交友软件时遇见了frida反调试,收获挺大的,于是记录一下。
frida是逆向人员的神器,有了它就事半功倍,但正是因为frida太有名了,因此出现了很多检测方案,这个软件就检测了frida,不管是attach模式还是spawn模式都附加不上。
一般来说,frida检测由如下几个方面:
- 检测frida-server文件名
- 检测27042默认端口
- 双进程保护
- 检测D-Bus
- 检测/proc/pid/maps映射文件
- 检测/proc/pid/tast/tid/stat或/proc/pid/tast/tid/status
前三种可以通过改文件名、改端口和以spawn模式启动过掉,检测D-Bus可以通过hook系统库函数,比如strstr、strcmp等等,最后两种检测可以更改frida-server的特征从而达到隐藏的效果,这个可以具体参照这篇文章手动编译Hluda Frida Server,下面看具体演示
这里直接使用hluda server,它更改了frida的诸多特征,自己使用时记得把文件名给改了,并且换个端口,不要使用默认端口
然后以spawn模式启动应用,主要是为了过掉双进程保护(虽然这个应用是没有双进程保护的~~)
然后就。。。挂掉了,纳尼,神马情况,缓缓情绪,虽然hluda server改了很多特征,但也还有特征能够发现
先不说hluda server,先说说正常的frida server附加进应用之后它的/proc/pid/maps的文件的变化
很明显的发现出现了/data/local/tmp/re.frida.server/***,等等,re.frida.server
是什么呢?这是当使用frida server的时候自动创建的,里面存放着frida的功能模块。
那么当使用hluda server会发生什么变化呢?
可以发现re.frida.server
已经没有了,反而变成了一串没有意义的字符串,并且功能模块文件名也被混淆了,那么为什么还是被检测到了呢?会不会是D-Bus检测呢?别急,认真比对正常的与附加后的/proc/pid/maps文件,发现正常的maps里面是没有/data/local/tmp路径下的模块映射的,但附加了frida之后,不管模块名有没有被混淆,/data/local/tmp路径名总会出现的,见下图:
因此应用完全有理由去检测maps文件里是否有/data/local/tmp目录下的模块映射,所以我就尝试着伪造一个/proc/pid/maps文件,去掉所有有关/data/local/tmp的映射,并且hook open函数让其打开我伪造的maps文件,具体代码如下:
function main() {
const openPtr = Module.getExportByName('libc.so', 'open');
const open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
var readPtr = Module.findExportByName("libc.so", "read");
var read = new NativeFunction(readPtr, 'int', ['int', 'pointer', "int"]);
var fakePath = "/data/data/com.xyz.qingtian/maps";
var file = new File(fakePath, "w");
var buffer = Memory.alloc(512);
Interceptor.replace(openPtr, new NativeCallback(function (pathnameptr, flag) {
var pathname = Memory.readUtf8String(pathnameptr);
var realFd = open(pathnameptr, flag);
if (pathname.indexOf("maps") >= 0) {
while (parseInt(read(realFd, buffer, 512)) !== 0) {
var oneLine = Memory.readCString(buffer);
if (oneLine.indexOf("tmp") === -1) {
file.write(oneLine);
}
}
var filename = Memory.allocUtf8String(fakePath);
return open(filename, flag);
}
var fd = open(pathnameptr, flag);
return fd;
}, 'int', ['pointer', 'int']));
}
setImmediate(main)
很惊喜的发现成功过掉了frida检测