绕过App某加密企业版加固Frida检测
字数 1001 2025-08-22 12:23:06
绕过App企业版加固Frida检测技术分析
0x00 测试环境
- 设备: Pixel 3
- Android版本: 12
- 面具版本: Magisk Delta 26.4-kitsune(26400)
0x01 目标应用
- 某App最新版本(24年9月最新版本)
- 使用某加密企业版加固
0x02 检测机制分析
Root检测分析
App的root检测主要在Java代码层面实现,主要检测以下路径:
/system/xbin/
/system/bin/
/system/sbin/
/sbin/
/vendor/bin/
/su/bin/
绕过方法:
- 使用Magisk Delta版本,通过设置App访问root权限白名单
- 使用Shamiko插件进行绕过
Frida检测分析
Frida检测通常在Native层(so层)实现,需要定位检测进程所在的so文件。
0x03 检测定位技术
1. 动态链接库加载监控
使用android_dlopen_ext hook监控so加载流程:
var dlopen_interceptor = hook_dlopen();
function hook_dlopen() {
Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
onEnter: function(args) {
this.fileName = args[0].readCString();
console.log(`dlopen onEnter: ${this.fileName}`);
},
onLeave: function(retval){
console.log(`dlopen onLeave fileName: ${this.fileName}`);
}
});
}
关键发现:
- 程序总是在加载
/lib/arm64/libnllvm1717052779924.so后崩溃 - 初步判断该so中实现了Frida检测进程
2. 线程创建监控
尝试hook pthread_create函数:
function hook_pthred_create(){
var interceptor = Interceptor.attach(Module.findExportByName(null, "pthread_create"), {
onEnter: function(args) {
var module = Process.findModuleByAddress(ptr(this.returnAddress));
if(module != null) {
console.log("[pthread_create] called from", module.name);
} else {
console.log("[pthread_create] called from", ptr(this.returnAddress));
}
},
});
}
问题:
- 程序会卡死白屏或强制退出
- 需要寻找替代方案
3. 动态符号解析监控
hook dlsym函数监控符号加载:
function hook_dlsym() {
console.log("=== HOOKING dlsym ===");
var interceptor = Interceptor.attach(Module.findExportByName(null, "dlsym"), {
onEnter: function(args) {
const name = ptr(args[1]).readCString();
console.log("[dlsym]", name);
},
onLeave: function(retval) {
console.log("=== EXIT ===");
}
});
return interceptor;
}
关键发现:
libnllvm1717052779924.so加载了两次pthread_create- 推测这些进程与Frida检测相关
0x04 绕过技术实现
1. 创建虚假pthread_create函数
function create_fake_pthread_create() {
const fake_pthread_create = Memory.alloc(4096);
Memory.protect(fake_pthread_create, 4096, "rwx");
Memory.patchCode(fake_pthread_create, 4096, code => {
const cw = new Arm64Writer(code, { pc: ptr(fake_pthread_create) });
cw.putRet();
});
return fake_pthread_create;
}
2. 替换真实pthread_create
var fake_pthread_create = create_fake_pthread_create();
function hook_dlsym() {
console.log("=== HOOKING dlsym ===");
var interceptor = Interceptor.attach(Module.findExportByName(null, "dlsym"), {
onEnter: function(args) {
const name = ptr(args[1]).readCString();
console.log("[dlsym]", name);
},
onLeave: function(retval) {
retval.replace(fake_pthread_create);
console.log("=== EXIT ===");
interceptor.detach();
}
});
return interceptor;
}
3. 综合绕过方案
var dlopen_interceptor = hook_dlopen();
var fake_pthread_create = create_fake_pthread_create();
function hook_dlopen() {
Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
onEnter: function(args) {
this.fileName = args[0].readCString();
console.log(`dlopen onEnter: ${this.fileName}`);
if(this.fileName.indexOf("libnllvm1717052779924.so") >= 0 ||
this.fileName.indexOf("libface_nllvm.so") >= 0) {
hook_dlsym();
}
},
onLeave: function(retval){
console.log(`dlopen onLeave fileName: ${this.fileName}`);
}
});
}
0x05 补充分析(pthread_create)
1. 直接hook的问题
直接hook pthread_create会导致:
- 白屏
- 死机
- 偶尔不死机的情况
2. 偏移量计算方案
function hook_pthread_libnllvm1717052779924(){
var interceptor = Interceptor.attach(Module.findExportByName(null, "pthread_create"), {
onEnter: function(args) {
var module = Process.findModuleByAddress(ptr(this.returnAddress));
if(module != null) {
console.log("hook_pthread_libnllvm1717052779924 "+Process.findModuleByName("libnllvm1717052779924.so").base);
console.log("[pthread_create] called from", module.name);
let func_addr = args[2];
console.log(`The thread Called function address is: ${func_addr}`);
} else {
console.log("[pthread_create] called from", ptr(this.returnAddress));
}
},
});
}
3. 基于偏移量的替换
function hook_64d10(){
let secmodule = Process.findModuleByName("libnllvm1717052779924.so");
console.log("secmodule " + secmodule);
Interceptor.replace(secmodule.base.add(0x64d10), new NativeCallback(function() {
console.log(`hook_sub_64d10 replace`);
}, 'void'));
console.log("替换完毕");
}
0x06 总结
-
检测机制:
- Root检测主要在Java层
- Frida检测在Native层通过多so文件实现
-
绕过方案:
- 监控so加载流程定位检测点
- 创建虚假函数替换关键检测函数
- 基于偏移量的精确替换方案
-
适用场景:
- 企业级加固应用的Frida检测绕过
- 多so文件协同检测的场景
- 直接hook会导致崩溃的防护机制
-
扩展应用:
- 该方法可应用于其他类似防护机制
- 可扩展用于其他关键函数的替换
- 适用于不同架构的so文件分析