某企业版加固app绕过hook
字数 1124 2025-08-19 12:42:28
企业版加固APP绕过Frida Hook技术分析
1. 环境准备
- 测试设备: Pixel 2
- 目标APP: 某企业版加固APP(具体名称未透露)
- 工具版本: Frida 15.1.28
2. Frida检测绕过技术
2.1 初步检测分析
发现直接使用Frida进行hook会导致APP闪退,但更改Frida端口后未检测到防护行为,表明APP可能通过以下方式检测Frida:
- 检测默认Frida端口
- 检测Frida相关进程
- 检测内存中的Frida痕迹
2.2 pthread_create hook绕过
通过拦截pthread_create函数调用,分析线程创建行为,发现libexec.so中特定偏移量的线程创建与Frida检测相关。
关键代码实现:
function hook_pthread() {
var pthread_create_addr = Module.findExportByName(null, 'pthread_create');
var pthread_create = new NativeFunction(pthread_create_addr, "int", ["pointer", "pointer", "pointer", "pointer"]);
Interceptor.replace(pthread_create_addr, new NativeCallback(function (parg0, parg1, parg2, parg3) {
var so_name = Process.findModuleByAddress(parg2).name;
var so_base = Module.getBaseAddress(so_name);
var offset = parg2 - so_base;
var PC = 0;
if ((so_name.indexOf("libexec.so") > -1)) {
console.log("find thread func offset", so_name, offset);
// 关键检测点绕过
if ((207076 === offset) || (207308 === offset) || (283820 === offset) ||
(286488 === offset) || (292416 === offset) || (78136 === offset) ||
(293768 === offset)) {
console.log("anti bypass");
} else {
PC = pthread_create(parg0, parg1, parg2, parg3);
}
} else {
PC = pthread_create(parg0, parg1, parg2, parg3);
}
return PC;
}, "int", ["pointer", "pointer", "pointer", "pointer"]))
}
hook_pthread();
2.3 关键检测点
在libexec.so中识别出以下关键偏移量,这些位置创建的线程可能与Frida检测相关:
- 207076
- 207308
- 283820
- 286488
- 292416
- 78136
- 293768
3. Java层Hook技术
3.1 类枚举方法
绕过Frida检测后,使用以下方法枚举已加载的类:
Java.enumerateLoadedClasses({
onMatch: function(className) {
console.log("found class >> " + className);
// 遍历类中所有的方法和属性
var jClass = Java.use(className);
console.log(JSON.stringify({
_name: className,
_methods: Object.getOwnPropertyNames(jClass.__proto__).filter(function(m) {
return !m.startsWith('$') // 过滤掉Frida相关特殊属性
|| m == 'class'
|| m == 'constructor'
}),
_fields: jClass.class.getFields().map(function(f) {
return f.toString();
})
}));
},
onComplete: function() {
console.log("[*] class enumeration complete");
}
});
3.2 加固APP的特殊处理
由于APP经过加固,常规的ClassLoader无法加载所有类和方法,需要特殊处理:
方法1: 重加载指定ClassLoader
var application = Java.use("android.app.Application");
application.attach.overload('android.content.Context').implementation = function(context) {
var result = this.attach(context);
var classloader = context.getClassLoader();
Java.classFactory.loader = classloader;
var Hook_class = Java.classFactory.use("com.xxx.xxx");
console.log("Hook_class: " + Hook_class);
// 正常hook代码
Hook_class.函数.implementation = function() {
// 有参数填参数
}
return result;
}
方法2: 枚举并尝试所有ClassLoader(更有效)
Java.enumerateClassLoaders({
onMatch: function(loader){
Java.classFactory.loader = loader;
var TryClass;
try {
// 尝试加载目标类
TryClass = Java.use("cn.xxx");
// Hook目标方法
TryClass.xx.implementation = function(p1,p2){
console.log('p1:'+p1);
console.log('p2:'+p2);
return this.xx(p1,p2);
}
} catch(error) {
if(error.message.includes("ClassNotFoundException")){
console.log("Trying next loader");
} else {
console.log(error.message);
}
}
},
onComplete: function(){
console.log("ClassLoader enumeration complete");
}
});
4. 关键要点总结
-
Frida检测绕过:
- 修改默认Frida端口
- 拦截并分析
pthread_create调用 - 识别并绕过特定so文件中的检测线程
-
Java层Hook难点:
- 加固APP使用非常规ClassLoader
- 部分类和方法在内存中加密/隐藏
- 需要枚举所有ClassLoader并尝试加载目标类
-
成功前提:
- 需要先对APP进行脱壳处理
- 需要知道目标类和方法名称
- 可能需要多次尝试不同的ClassLoader
-
注意事项:
- 企业版加固通常有多层防护
- 可能需要结合静态分析和动态调试
- 不同版本APP的偏移量可能不同
5. 扩展思考
-
更高级的检测绕过:
- 使用Frida的
--no-pause参数 - 修改Frida-server的进程名
- 使用内存补丁技术修改检测逻辑
- 使用Frida的
-
加固APP分析:
- 结合Xposed框架进行分析
- 使用模拟器+内存dump工具
- 动态调试脱壳过程
-
自动化工具开发:
- 自动识别关键偏移量
- ClassLoader自动枚举和尝试
- 方法签名自动识别
通过以上技术,可以有效绕过企业版加固APP的Frida检测机制,并成功Hook目标方法。需要注意的是,不同厂商的加固方案可能有不同的防护策略,需要根据实际情况调整技术方案。