原创文章,首发至博客http://t.csdn.cn/Pd9aL
文章仅供思路参考,请勿用作非法攻击
使用frida以spawn模式启动应用,frida进程直接被杀掉了
我需要知道是那个so在检测frida,可以hook dlopen看一下so的加载流程
由so的加载流程可知,当libmsaoaidsec.so被加载之后,frida进程就被杀掉了,因此监测点在libmsaoaidsec.so中。
如果有了解过so的加载流程,那么就会知道linker会先对so进行加载与链接,然后调用so的.init_proc函数,接着调用.init_array中的函数,最后才是JNI_OnLoad函数,所以我需要先确定检测点大概在哪个函数中。
使用frida hook JNI_OnLoad函数,如果调用了该函数就输出一行日志,如果没有日志输出,那么就说明检测点在.init_xxx函数中,注入的时机可以选择dlopen加载libmsaoaidsec.so完成之后。
并没有输出日志,那么说明检测的位置在JNI_OnLoad函数之前,所以我需要hook .init_xxx的函数,但这里有一个问题,dlopen函数调用完成之后.init_xxx函数已经执行完成了,这个时候不容易使用frida进行hook
这个问题其实很麻烦的,因为你想要hook linker的call_function并不容易,这里面涉及到linker的自举,我想到了一个取巧的办法,请看接下来的操作。
首先在.init_proc函数中找一个调用了外部函数的位置,时机越早越好
我选择了_system_property_get函数,接下来使用frida hook dlopen函数,当加载libmsaoaidsec.so时,在onEnter回调方法中hook _system_property_get函数,以"ro.build.version.sdk"字符串作为过滤器。
如果_system_property_get函数被调用了,那么这个时候也就是.init_proc函数刚刚调用的时候,在这个时机点可以注入我想要的代码,具体实现如下:
在获取了一个非常早的注入时机之后,就可以定位具体的frida检测点了。网上对frida的检测通常会使用openat、open、strstr、pthread_create、snprintf、sprintf、readlinkat等一系列函数,从这里下手是一个不错的选择。
我对pthread_create函数进行hook,打印一下新线程要执行的函数地址
这里面有两个线程是libmsaoaidsec.so创建的,对应的函数偏移分别是0x11129和0x10975
这两个函数都检测了frida,想要了解具体检测方法的可以自己看看,这里不再深入。
绕过的方法很简单,直接nop掉pthread_create或者替换检测函数的代码逻辑都可以,我是直接把pthread_create函数nop掉了,下面是完整代码。
至此,frida检测也就成功绕过了。
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 hook_dlopen(soName
=
'') {
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();
if
(path.indexOf(soName) >
=
0
) {
this.is_can_hook
=
true;
}
}
},
onLeave: function (retval) {
if
(this.is_can_hook) {
hook_JNI_OnLoad()
}
}
}
);
}
function hook_JNI_OnLoad(){
let module
=
Process.findModuleByName(
"libmsaoaidsec.so"
)
Interceptor.attach(module.base.add(
0xC6DC
+
1
), {
onEnter(args){
console.log(
"call JNI_OnLoad"
)
}
})
}
setImmediate(hook_dlopen,
"libmsaoaidsec.so"
)
function hook_dlopen(soName
=
'') {
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();
if
(path.indexOf(soName) >
=
0
) {
this.is_can_hook
=
true;
}
}
},
onLeave: function (retval) {
if
(this.is_can_hook) {
hook_JNI_OnLoad()
}
}
}
);
}
function hook_JNI_OnLoad(){
let module
=
Process.findModuleByName(
"libmsaoaidsec.so"
)
Interceptor.attach(module.base.add(
0xC6DC
+
1
), {
onEnter(args){
console.log(
"call JNI_OnLoad"
)
}
})
}
setImmediate(hook_dlopen,
"libmsaoaidsec.so"
)
function hook_dlopen(soName
=
'') {
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();
if
(path.indexOf(soName) >
=
0
) {
locate_init()
}
}
}
}
);
}
function locate_init() {
let secmodule
=
null
Interceptor.attach(Module.findExportByName(null,
"__system_property_get"
),
{
/
/
_system_property_get(
"ro.build.version.sdk"
, v1);
onEnter: function (args) {
secmodule
=
Process.findModuleByName(
"libmsaoaidsec.so"
)
var name
=
args[
0
];
if
(name !
=
=
undefined && name !
=
null) {
name
=
ptr(name).readCString();
if
(name.indexOf(
"ro.build.version.sdk"
) >
=
0
) {
/
/
这是.init_proc刚开始执行的地方,是一个比较早的时机点
/
/
do something
}
}
}
}
);
}
setImmediate(hook_dlopen,
"libmsaoaidsec.so"
)
function hook_dlopen(soName
=
'') {
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();
if
(path.indexOf(soName) >
=
0
) {
locate_init()
}
}
}
}
);
}
function locate_init() {
let secmodule
=
null
Interceptor.attach(Module.findExportByName(null,
"__system_property_get"
),
{
/
/
_system_property_get(
"ro.build.version.sdk"
, v1);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!