29、商业加固产品分析:360加固、腾讯加固、娜迦加固的特征与脱壳思路
做逆向这些年,我接触最多的就是这三家加固:360、腾讯、娜迦。说实话,它们几乎垄断了国内Android加固市场。你随便从应用商店下个热门App,十有八九就是其中之一。
今天我就把这三家的特征和脱壳思路掰开揉碎了讲。嗯,都是实战中摸爬滚打出来的经验,希望能帮你少走弯路。
29.1 360加固:老牌劲旅,特征明显
360加固是我最早接触的商业加固产品。它的特征非常鲜明,一眼就能认出来。
特征识别
- 包名特征:解压APK后,你会看到
libjiagu.so、libjiagu_art.so等文件。这是360加固的招牌文件。 - 入口点修改:AndroidManifest.xml 中的 Application 类会被替换为
com.qihoo.util.StubApplication或类似名称。 - Dex结构:classes.dex 通常是一个壳dex,真正的业务代码被加密存储在
assets/目录或lib/下的so文件中。 - so文件:除了
libjiagu.so,还可能有libjiagu_x86.so、libjiagu_64.so等,用于不同架构。
快速判断技巧:用jadx打开APK,如果看到 com.qihoo 包名,基本就是360加固无疑了。
脱壳思路
360加固的脱壳,我个人习惯用 Frida + DumpDex 方案。为什么?因为它的壳在运行时会把原始dex加载到内存中,我们只需要在合适时机dump出来就行。
// Frida脚本:Hook ArtMethod的入口,dump dex
function dumpDex() {
var dexOffset = Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPNS_12OatDexFileEPS9_");
Interceptor.attach(dexOffset, {
onEnter: function(args) {
var dexAddr = args[1];
var dexSize = args[2].toInt32();
var dexData = ptr(dexAddr).readByteArray(dexSize);
var file = new File("/sdcard/dump_" + dexSize + ".dex", "wb");
file.write(dexData);
file.close();
console.log("[+] Dumped dex, size: " + dexSize);
}
});
}
setTimeout(dumpDex, 1000);
我曾经遇到过一个问题:360加固在Android 10以上版本增加了反调试,Frida一attach就闪退。后来我改用 frida-gadget 注入方式,绕过了这个检测。
避坑指南:360加固的so文件有完整性校验。如果你修改了so文件,App会直接crash。建议用内存dump方式,不要尝试静态修改。
29.2 腾讯加固:大厂风范,多层防护
腾讯加固(也叫腾讯云加固、乐固)是另一大主流。它的防护层级更多,脱壳难度也更高。
特征识别
- 包名特征:解压后能看到
libshell.so、libtup.so、libBugly.so等文件。其中libshell.so是核心壳so。 - 入口点修改:Application 类被替换为
com.tencent.StubShell或com.tencent.mm开头的类。 - Dex结构:classes.dex 非常小,只有几百KB,真正的代码被加密存储在
lib/armeabi/libshell.so中。 - 资源保护:腾讯加固会对资源文件进行加密,直接解压看到的图片、布局文件都是乱码。
快速判断技巧:在jadx中搜索 StubShell 或 tup 字符串,如果出现,基本就是腾讯加固。
脱壳思路
腾讯加固的脱壳,我建议用 内存dump + 修复 两步走。为什么不能一步到位?因为腾讯加固会把dex分段加载,直接dump出来的dex可能不完整。
// Frida脚本:Hook libart.so 的 LoadMethod 方法
function hookLoadMethod() {
var symbols = Module.enumerateSymbolsSync("libart.so");
var loadMethod = null;
for (var i = 0; i < symbols.length; i++) {
if (symbols[i].name.indexOf("LoadMethod") !== -1) {
loadMethod = symbols[i].address;
break;
}
}
if (loadMethod) {
Interceptor.attach(loadMethod, {
onEnter: function(args) {
// 这里可以获取到dex的起始地址和大小
console.log("[+] LoadMethod called");
}
});
}
}
setTimeout(hookLoadMethod, 2000);
我记得有一次,腾讯加固的某个版本用了 VMP(虚拟机保护),把核心逻辑都转成了自定义指令。那一次我不得不先分析它的虚拟机解释器,再写脚本还原。嗯,确实折腾了好几天。
注意事项:腾讯加固有反Frida检测。它会检查 /data/local/tmp/ 目录下是否有frida-server文件。建议把frida-server重命名,或者用 frida-gadget 模式。
29.3 娜迦加固:小而精悍,定制化强
娜迦加固虽然市场份额不如前两家,但它的技术方案很有特色。很多金融类App喜欢用它。
特征识别
- 包名特征:解压后能看到
libnaga.so、libnagavm.so等文件。娜迦的so命名很统一,都带naga前缀。 - 入口点修改:Application 类被替换为
com.naga.stub或com.naga.core开头的类。 - Dex结构:娜迦会把原始dex拆分成多个片段,分别加密存储。你可能会看到
classes2.dex、classes3.dex等,但都是假的。 - so文件:娜迦的so文件通常有
libnaga.so(核心壳)、libnagavm.so(虚拟机)、libnagadump.so(反调试)等。
快速判断技巧:在APK的 lib/ 目录下搜索 naga 关键字,如果有,就是娜迦加固。
脱壳思路
娜迦加固的脱壳,我个人觉得最有效的是 定制Frida脚本 + 手动修复。为什么?因为娜迦的壳会动态解密dex,而且解密时机很晚,需要耐心等待。
// Frida脚本:监控dex文件的加载
function monitorDexLoad() {
var dexFileOpen = Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPNS_12OatDexFileEPS9_");
Interceptor.attach(dexFileOpen, {
onEnter: function(args) {
this.dexAddr = args[1];
this.dexSize = args[2].toInt32();
},
onLeave: function(retval) {
if (this.dexAddr && this.dexSize > 0) {
var dexData = ptr(this.dexAddr).readByteArray(this.dexSize);
// 检查dex魔数
if (dexData[0] === 0x64 && dexData[1] === 0x65 && dexData[2] === 0x78) {
var file = new File("/sdcard/naga_dex_" + Date.now() + ".dex", "wb");
file.write(dexData);
file.close();
console.log("[+] Naga dex dumped, size: " + this.dexSize);
}
}
}
});
}
setTimeout(monitorDexLoad, 3000);
我曾经在脱娜迦加固时,发现dump出来的dex无法直接用jadx打开。后来分析发现,娜迦对dex的字符串表做了混淆。需要写一个修复脚本,把字符串表还原才能正常反编译。
避坑指南:娜迦加固有 时间戳校验。如果你用调试器附加,它会检测系统时间是否被修改。建议在真机上操作,不要用模拟器。
29.4 三家加固对比总结
说了这么多,我整理了一个对比表格,方便你快速查阅。
| 加固产品 | 核心特征 | 脱壳难度 | 推荐方案 | 常见坑点 |
|---|---|---|---|---|
| 360加固 | libjiagu.so、StubApplication | ★★☆☆☆ | Frida内存dump | so完整性校验 |
| 腾讯加固 | libshell.so、StubShell | ★★★☆☆ | 内存dump + 修复 | 反Frida检测、VMP保护 |
| 娜迦加固 | libnaga.so、naga包名 | ★★★★☆ | 定制脚本 + 手动修复 | 字符串混淆、时间戳校验 |
29.5 核心知识体系图
下面这张图,我把三家的特征和脱壳思路串起来了。你保存下来,以后遇到加固App,先对照这张图快速定位。
嗯,以上就是我对这三家商业加固产品的实战分析。说白了,脱壳这件事没有银弹,每家都有各自的防护特点。但核心思路是一样的:找到dex在内存中的加载时机,用合适的方式dump出来。你多练几次,自然就熟练了。