初探frida反调试
本帖最后由 胡凯莉 于 2023-3-23 08:32 编辑## 常见frida检测
- 1、检测文件名(改名)、端口名27042(改端口)、双进程保护(spawn启动)
- 2、检测D-Bus
- D-Bus是一种进程间通信(IPC)和远程过程调用(RPC)机制,最初是为Linux开发的,目的是用一个统一的协议替代现有的和竞争的IPC解决方案。
- ```
遍历连接手机所有端口发送D-bus消息,如果返回"REJECT"这个特征则认为存在frida-server。
内存中存在frida rpc字符串,认为有frida-server
/*
* Mini-portscan to detect frida-server on any local port.
*/
for(i = 0 ; i <= 65535 ; i++) {
sock = socket(AF_INET , SOCK_STREAM , 0);
sa.sin_port = htons(i);
if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME,"FRIDA DETECTION : Open Port: %d", i);
memset(res, 0 , 7);
// send a D-Bus AUTH message. Expected answer is “REJECT"
send(sock, "\x00", 1, NULL);
send(sock, "AUTH\r\n", 6, NULL);
usleep(100);
if (ret = recv(sock, res, 6, MSG_DONTWAIT) != -1) {
if (strcmp(res, "REJECT") == 0) {
/* Frida server detected. Do something… */
}
}
}
close(sock);
}
```
- 检测D-Bus可以通过hook系统库函数,比如strstr、strcmp等等
- 3、检测/proc/pid/maps映射文件
- 4、检测/proc/pid/tast/tid/stat/或者/proc/pid/task/tip/status
- 因为so载入的时候,底层最后open去打开的。 所以再用frida去hook应用中的open函数,看看读取了哪些so或者文件,可以看到最后断在了/proc/self/maps。对于3、4有效
- 5、直接调用openat的syscall的检测在text节表中搜索frida-gadget.so / frida-agent.so字符串,避免了hook libc来anti-anti的方法
- 注入方式改为
- 1、frida-inject
- 2、ptrace注入 配置文件的形式注入
- 3、编译rom注入
- 6、从inlinehook角度检测frida
- https://bbs.kanxue.com/thread-269862.htm未学习
https://zhuanlan.zhihu.com/p/557713016
hook_open函数可以查看是哪里检测了so文件
```
function hook_open(){
var pth = Module.findExportByName(null,"open");
Interceptor.attach(ptr(pth),{
onEnter:function(args){
this.filename = args;
console.log("",this.filename.readCString())
if (this.filename.readCString().indexOf(".so") != -1){
args = ptr(0)
}
},onLeave:function(retval){
return retval;
}
})
}
setImmediate(hook_open)
```
替换一个正常的
```
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.app/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)
```
## 检测点是maps、status
- 1、替换
- 2、映射
- !(https://img-pool-own.oss-cn-shanghai.aliyuncs.com/img/image-20230304202127820.png)
- 使用方法把解压后的maps和status文件拷贝到sdcard目录下,并chmod给777权限 然后frida使用bypassFulao2.js脚本
- 查看当前运行软件的包名和类名:
- `adb shell dumpsys window |grep mCurrentFocus`
- 去脱壳的dex文件夹中搜索
- `grep -ril "com.ilulutv.fulao2.main.MainActivity"`
- jadx查看
-`jadx-gui classes08.dex`
!(https://img-pool-own.oss-cn-shanghai.aliyuncs.com/img/image-20230304205839578.png)
## 新版jadx修改checknum
!(https://img-pool-own.oss-cn-shanghai.aliyuncs.com/img/image-20230304210155082.png) function hook_open(){
var pth = Module.findExportByName(null,"open");
Interceptor.attach(ptr(pth),{
onEnter:function(args){
this.filename = args;
if (this.filename.readCString().indexOf(".so") != -1){
console.log("",this.filename.readCString())
}
},onLeave:function(retval){
return retval;
}
})
}
setImmediate(hook_open)
这个这么写才有结果吧? 从inlinehook的思路比较通用,因为不管frida如何改变,它总要修改内存,这个方案相对通用一点 感谢分享,多多益善 路过看看 非常感谢楼主的分享 学习学习。感谢楼主分享! 好 但是看不懂 感谢分享 感谢的分享 感谢楼主分享 感谢分享,学习一下{:1_893:}