查看哪个so在检测frida
管他检测啥、直接一把梭
检测D-Bus可以通过hook系统库函数,比如strstr、strcmp等等
maps文件中存储的是APP运行时加载的依赖
当启动frida后,在maps文件中就会存在 frida-agent-64.so
、frida-agent-32.so
文件。
绕过
在 /proc/pid/task
目录下,可以通过查看不同的线程子目录,来获取进程中每个线程的运行时信息。这些信息包括线程的状态、线程的寄存器内容、线程占用的CPU时间、线程的堆栈信息等。通过这些信息,可以实时观察和监控进程中每个线程的运行状态,帮助进行调试、性能优化和问题排查等工作。
/proc/pid/fd
目录的作用在于提供了一种方便的方式来查看进程的文件描述符信息,这对于调试和监控进程非常有用。通过查看文件描述符信息,可以了解进程打开了哪些文件、网络连接等,帮助开发者和系统管理员进行问题排查和分析工作。
打开frida调试后这个task目录下会多出几个线程,检测点在查看这些多出来的线程是否和frida调试相关。
在某些app中就会去读取 /proc/stask/线程ID/status
文件,如果是运行frida产生的,则进行反调试。例如:gmain/gdbus/gum-js-loop/pool-frida
等
绕过
https://zhuanlan.zhihu.com/p/557713016
替换一个正常的
function hook_dlopen() {
Interceptor.attach(Module.findExportByName(
null
,
"android_dlopen_ext"
),
{
onEnter: function (args) {
var pathptr = args[
0
];
if
(pathptr !== undefined && pathptr !=
null
) {
var path = ptr(pathptr).readCString();
console.log(
"load "
+ path);
}
}
}
);
}
function hook_dlopen() {
Interceptor.attach(Module.findExportByName(
null
,
"android_dlopen_ext"
),
{
onEnter: function (args) {
var pathptr = args[
0
];
if
(pathptr !== undefined && pathptr !=
null
) {
var path = ptr(pathptr).readCString();
console.log(
"load "
+ path);
}
}
}
);
}
function replace_str() {
var pt_strstr = Module.findExportByName(
"libc.so"
,
'strstr'
);
var pt_strcmp = Module.findExportByName(
"libc.so"
,
'strcmp'
);
Interceptor.attach(pt_strstr, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(
str2.indexOf(
"REJECT"
) !== -
1
||
str2.indexOf(
"tmp"
) !== -
1
||
str2.indexOf(
"frida"
) !== -
1
||
str2.indexOf(
"gum-js-loop"
) !== -
1
||
str2.indexOf(
"gmain"
) !== -
1
||
str2.indexOf(
"linjector"
) !== -
1
) {
console.log(
"strstr-->"
, str1, str2);
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
});
Interceptor.attach(pt_strcmp, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(
str2.indexOf(
"REJECT"
) !== -
1
||
str2.indexOf(
"tmp"
) !== -
1
||
str2.indexOf(
"frida"
) !== -
1
||
str2.indexOf(
"gum-js-loop"
) !== -
1
||
str2.indexOf(
"gmain"
) !== -
1
||
str2.indexOf(
"linjector"
) !== -
1
) {
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
})
}
replace_str();
function replace_str() {
var pt_strstr = Module.findExportByName(
"libc.so"
,
'strstr'
);
var pt_strcmp = Module.findExportByName(
"libc.so"
,
'strcmp'
);
Interceptor.attach(pt_strstr, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(
str2.indexOf(
"REJECT"
) !== -
1
||
str2.indexOf(
"tmp"
) !== -
1
||
str2.indexOf(
"frida"
) !== -
1
||
str2.indexOf(
"gum-js-loop"
) !== -
1
||
str2.indexOf(
"gmain"
) !== -
1
||
str2.indexOf(
"linjector"
) !== -
1
) {
console.log(
"strstr-->"
, str1, str2);
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
});
Interceptor.attach(pt_strcmp, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(
str2.indexOf(
"REJECT"
) !== -
1
||
str2.indexOf(
"tmp"
) !== -
1
||
str2.indexOf(
"frida"
) !== -
1
||
str2.indexOf(
"gum-js-loop"
) !== -
1
||
str2.indexOf(
"gmain"
) !== -
1
||
str2.indexOf(
"linjector"
) !== -
1
) {
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
})
}
replace_str();
遍历连接手机所有端口发送D-bus消息,如果返回
"REJECT"
这个特征则认为存在frida-server。
内存中存在frida rpc字符串,认为有frida-server
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 [1]: Open Port: %d"
, i);
memset
(res, 0 , 7);
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) {
}
}
}
close(sock);
}
遍历连接手机所有端口发送D-bus消息,如果返回
"REJECT"
这个特征则认为存在frida-server。
内存中存在frida rpc字符串,认为有frida-server
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 [1]: Open Port: %d"
, i);
memset
(res, 0 , 7);
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) {
}
}
}
close(sock);
}
function replace_str() {
var pt_strstr = Module.findExportByName(
"libc.so"
,
'strstr'
);
var pt_strcmp = Module.findExportByName(
"libc.so"
,
'strcmp'
);
Interceptor.attach(pt_strstr, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(str2.indexOf(
"REJECT"
) !== -
1
) {
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
});
Interceptor.attach(pt_strcmp, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(str2.indexOf(
"REJECT"
) !== -
1
) {
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
})
}
replace_str();
function replace_str() {
var pt_strstr = Module.findExportByName(
"libc.so"
,
'strstr'
);
var pt_strcmp = Module.findExportByName(
"libc.so"
,
'strcmp'
);
Interceptor.attach(pt_strstr, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(str2.indexOf(
"REJECT"
) !== -
1
) {
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
});
Interceptor.attach(pt_strcmp, {
onEnter: function (args) {
var str1 = args[
0
].readCString();
var str2 = args[
1
].readCString();
if
(str2.indexOf(
"REJECT"
) !== -
1
) {
this
.hook =
true
;
}
}, onLeave: function (retval) {
if
(
this
.hook) {
retval.replace(
0
);
}
}
})
}
replace_str();
char
line[
512
];
FILE* fp;
fp = fopen(
"/proc/self/maps"
,
"r"
);
if
(fp) {
while
(fgets(line,
512
, fp)) {
if
(strstr(line,
"frida"
)) {
}
}
char
line[
512
];
FILE* fp;
fp = fopen(
"/proc/self/maps"
,
"r"
);
if
(fp) {
while
(fgets(line,
512
, fp)) {
if
(strstr(line,
"frida"
)) {
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)