1. 项目概述与核心思路
最近在逆向分析圈子里,360加固的App一直是个绕不开的话题。很多开发者为了保护自己的应用,会选择使用360加固这类商业方案,它就像给App穿上了一套“盔甲”,把核心的Java代码(Dex文件)加密、隐藏甚至动态加载,让传统的静态分析工具直接“抓瞎”。但作为安全研究员或者有学习需求的开发者,我们总需要一种方法来“拆解”这套盔甲,看看里面的运行逻辑。这次,我就用大家手边最常见的工具——MT管理器,来完整走一遍破解一个360加固应用的全过程。
你可能会问,为什么是MT管理器?在Root环境下,MT管理器集文件管理、反编译、十六进制编辑、脚本执行于一身,对于安卓逆向来说,它就像一把瑞士军刀,灵活且强大。更重要的是,这个过程不依赖于复杂的IDA动态调试或者Xposed框架Hook,思路相对直接,适合有一定安卓基础、想入门加固脱壳的朋友。整个流程的核心思路可以概括为:定位被保护的Dex文件 -> 在内存中捕获其解密后的镜像 -> 将其从内存中DUMP(导出)到本地 -> 修复并还原成可分析的Dex/Jar文件。下面,我们就一步步拆解这个“手术”过程。
2. 环境与工具准备
工欲善其事,必先利其器。在开始对加固应用动刀之前,一个稳定、纯净且配置得当的逆向环境至关重要。这里我推荐使用一台已经获取Root权限的安卓真机,模拟器在某些情况下可能会被加固应用检测并拒绝运行。
2.1 核心工具清单
- MT管理器 (v2.x以上):这是我们的主战场。确保你安装的是已获得Root权限授权的版本。它的“Activity记录”功能、内存搜索和文件DUMP能力是我们成功的关键。
- 目标应用:一个你确定使用了360加固的应用。可以在应用宝等市场下载一些中小型游戏或工具类App,很多都会采用免费版的360加固。
- ADB (Android Debug Bridge):用于电脑与手机之间的命令行通信。虽然MT管理器能完成大部分工作,但ADB在推送脚本、执行命令时更加灵活高效。
- Frida(可选但强烈推荐):一个动态插桩工具。对于高版本或复杂逻辑的360加固,单纯靠内存DUMP可能不够,Frida可以注入脚本来Hook关键的解密函数,实现更精准的脱壳。本次流程以MT管理器为主,但会提及Frida的辅助思路。
- 文本编辑器:用于编写和修改简单的Shell或Python脚本。
- 一台已Root的安卓手机:这是基础条件。确保Magisk或SuperSU等Root管理工具正常工作,并已对MT管理器授予Root权限。
2.2 关键环境配置
在手机上,除了安装MT管理器,还需要进行一项关键设置:开启“显示隐藏文件”和“显示系统文件”选项。因为加固应用释放的临时文件或解密后的Dex,有时会存放在/data分区下以点.开头的隐藏目录,或者属于系统应用的数据目录里。在MT管理器的设置中,务必勾选这些显示选项,避免遗漏关键文件。
另外,建议将手机的开发者选项打开,并启用“USB调试”。这样即使MT管理器内的终端功能出现异常,我们还可以通过ADB连接到手机,从电脑端执行补救命令。
注意:整个操作请在用于学习和研究的合规环境下进行,切勿用于破解他人拥有合法版权的商业软件,以免引发法律风险。
3. 360加固基本原理与破解入口分析
要破解,先得了解它是如何保护的。360加固(尤其是其免费或基础版本)的流程相对经典,理解其原理能帮助我们精准找到突破口。
3.1 360加固的“盔甲”是如何穿上的
开发者使用360加固平台对APK进行处理后,原APK会发生以下核心变化:
- Dex加密/隐藏:原始应用逻辑的classes.dex文件会被加密或替换。安装包中可能只保留一个或多个体积很小的“壳Dex”,这些壳Dex的唯一职责就是解密和加载真正的应用代码。
- Application替换:AndroidManifest.xml中的Application类会被替换为360加固提供的
StubApplication或类似名称的类。这个壳Application会在应用启动时最早被加载,由它来初始化加固环境,并负责在适当时机解密和加载真实的Application及Dex。 - 动态加载:真实的Dex文件通常不会在安装时解压到
/data/app/目录下,而是以加密形式存放在APK内或资产目录中。在运行时,由壳代码在内存中动态解密,并通过DexClassLoader或PathClassLoader加载到内存中。
3.2 我们的破解入口在哪里
既然真正的代码是在内存中被解密并加载的,那么我们的目标就很明确了:从内存中把这个已经解密、但还未被虚拟机销毁的Dex文件镜像抓取出来。这个时刻通常发生在壳Application完成解密,将控制权交给真实Application之后,应用界面完全启动之前。对于MT管理器方案,我们主要依赖以下两个入口点:
- 进程内存搜索:Android系统中的Dex文件在内存中有固定的结构特征,例如魔数
dex\n035\0。我们可以在目标应用进程的内存空间中搜索这个特征,从而定位到解密后的Dex镜像在内存中的起始地址。 - 文件系统监控:有些版本的加固,可能会将解密后的Dex文件以临时文件的形式写入到
/data/data/<包名>/或/data/local/tmp/目录下。虽然它们可能很快被删除,但如果我们监控文件系统变化,就有机会在删除前将其复制出来。
MT管理器的“活动记录”和“内存编辑”功能,正是为我们利用这两个入口点而准备的。
4. 实战流程:使用MT管理器进行脱壳
假设我们的目标应用包名为com.example.protectedapp。下面进入具体的操作环节。
4.1 第一步:信息收集与初步分析
- 安装并启动目标应用:确保应用能正常运行一次,完成其初始化解密流程。
- 使用MT管理器查看安装包:
- 定位到
/data/app/目录下找到目标应用的安装文件夹(通常包含包名)。 - 查看其中的
base.apk或split_*.apk。用MT管理器直接点击APK文件,选择“查看”。你会发现,在assets目录或根目录下,可能存在一些名称可疑的.jar、.dex或.so文件(如ijiami.dat,libshell.so等),这些就是360加固的壳文件。而原始的classes.dex可能很小或者结构异常。 - 查看
AndroidManifest.xml(MT管理器可以反编译),确认<application android:name="...">处的类名是否为com.qihoo.util.StubApp或类似的360壳Application。这是加固的明显标志。
- 定位到
4.2 第二步:监控应用启动与内存DUMP
这是最核心的步骤,目的是在内存中捕获解密后的Dex。
开启MT管理器“Activity记录”:
- 在MT管理器侧边栏或工具菜单中找到“Activity记录”功能并启动它。
- 在记录列表中,找到并选中我们的目标应用
com.example.protectedapp。 - 返回到手机桌面,然后重新启动目标应用。此时MT管理器的“Activity记录”会像录像机一样,记录下该应用启动过程中所有Activity的创建顺序。我们关心的不是Activity本身,而是这个记录功能会将应用进程的内存状态“冻结”在一个可调试的时机。
附加到进程并搜索Dex特征:
- 当目标应用界面启动后,切换回MT管理器。在“Activity记录”界面,应该能看到
com.example.protectedapp的进程记录。 - 长按该进程记录,选择“附加到进程”或“内存查看/编辑”。这样MT管理器就关联到了目标应用的内存空间。
- 在内存编辑界面,寻找“搜索”功能。在搜索框中,我们输入Dex文件的魔数十六进制值:
64 65 78 0A 30 33 35 00(对应字符串dex\n035\0)。选择搜索类型为“十六进制”。 - 点击搜索。MT管理器会遍历进程的内存空间,寻找所有匹配该特征的位置。这个过程可能需要几秒到十几秒。
- 当目标应用界面启动后,切换回MT管理器。在“Activity记录”界面,应该能看到
定位并DUMP内存中的Dex:
- 搜索完成后,你会得到一个地址列表。这些地址可能就是解密后Dex在内存中的起始位置。通常,第一个或第二个结果(地址较小的)可能是壳Dex,我们需要找的是体积更大的那个,它才是真正的应用Dex。
- 如何判断?点击一个搜索结果,跳转到该内存地址。MT管理器会以十六进制和文本形式显示内存数据。除了开头的魔数,Dex文件头部附近还会有
file_size等字段。我们可以粗略估算大小。更稳妥的方法是,记录下你认为可能是真实Dex的起始地址。 - 假设我们找到的起始地址是
0x756F2000。在内存编辑界面,通常会有“导出内存”或“DUMP内存”的选项。点击后,需要输入起始地址和长度。长度是个难点,因为我们不知道确切的Dex文件大小。一个经验值是DUMP 10MB到20MB的内存数据,这通常能覆盖一个完整Dex。你可以输入起始地址0x756F2000,长度0xA00000(10MB)。 - 将DUMP出的内存数据保存为文件,例如
dump.bin。
4.3 第三步:修复与还原Dex文件
从内存中DUMP出来的数据是原始的内存镜像,它可能包含一些不属于Dex本身的内存页,或者Dex文件在内存中不是连续存放的(虽然对于大多数加固情况,解密后是连续的)。我们需要从中裁剪出正确的Dex文件。
使用十六进制编辑器定位Dex边界:
- 在MT管理器中打开刚才DUMP的
dump.bin文件,选择“十六进制编辑”。 - 从文件开头(偏移0x0处)开始向下翻看。你应该能很快看到
64 65 78 0A 30 33 35 00这个魔数,这就是Dex的起点。 - 接下来需要找到Dex的结束位置。Dex文件头部的
0x20偏移处,存储着file_size字段(小端序)。例如,读取0x20开始的4个字节是E0 84 0C 00,那么转换为十进制就是0x000C84E0 = 820,448字节,约801KB。这意味着从魔数开始,往后820,448字节就是整个Dex文件的结束。 - 在十六进制编辑器中,跳转到偏移量
0x20处,确认文件大小。然后,跳转到偏移量[文件大小]处。如果这里紧接着就是另一个Dex的魔数或者一片零值/杂乱数据,说明这个Dex是完整的。
- 在MT管理器中打开刚才DUMP的
裁剪并保存:
- 在MT管理器的十六进制编辑器中,通常有“选择块”的功能。从魔数开始(偏移0x0),选择直到
文件大小-1的字节。 - 选择“保存选中部分”或类似功能,将其另存为一个新文件,例如
classes_dex.dex。
- 在MT管理器的十六进制编辑器中,通常有“选择块”的功能。从魔数开始(偏移0x0),选择直到
验证与反编译:
- 现在,你可以用MT管理器直接点击这个
classes_dex.dex文件,选择“查看”。如果它能够正常反编译,显示出大量的Java类和方法,那么恭喜你,脱壳基本成功了。 - 你也可以将其复制到电脑上,使用更强大的反编译工具如
jadx-gui或Bytecode Viewer打开,进行更深入的分析。
- 现在,你可以用MT管理器直接点击这个
5. 进阶技巧与问题排查
上面的流程是理想情况。实际操作中,你可能会遇到各种问题。下面分享一些进阶技巧和常见坑点。
5.1 应对高版本或复杂加固
- 搜索不到Dex魔数:高版本加固可能会对内存中的Dex进行混淆或变形。此时可以尝试搜索变形后的魔数,或者搜索Dex文件中部的一些固定结构特征字符串。更有效的方法是使用Frida进行主动Hook。
- 编写Frida脚本,Hook
dalvik.system.DexFile或java.lang.ClassLoader的loadClass、defineClass等方法。当壳代码调用这些方法加载真实Dex时,我们可以获取到对应的DexFile对象或内存地址,然后通过Frida的API直接将内存中的Dex数据DUMP出来。这比盲目搜索更精准。
- 编写Frida脚本,Hook
- DUMP出的数据无法解析:可能Dex在内存中被分段或插入了干扰数据。除了精确计算
file_size,还可以尝试从DUMP的数据中,搜索多个Dex魔数。有时应用会有多个Dex文件(如classes2.dex),需要分别DUMP和修复。
5.2 MT管理器无Root执行Shell的妙用
在某些临时环境或对Root权限管理严格的情况下,MT管理器的“终端”功能(即使无Root)也能帮上忙。你可以编写一个简单的Shell脚本,利用/proc/<pid>/mem接口来读取进程内存。虽然需要一些Linux知识,但这是一个非常底层且有效的方法。
例如,已知目标进程PID为12345,Dex内存起始地址为0x756F2000,大小0xA00000,可以执行:
# 在MT管理器终端或ADB Shell中执行 (需要Root或部分权限) dd if=/proc/12345/mem bs=1 skip=$((0x756F2000)) count=$((0xA00000)) of=/sdcard/dump.bin这个命令直接从进程内存空间中读取数据。但请注意,直接读写/proc/<pid>/mem通常需要完整的Root权限。
5.3 常见问题速查表
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| MT管理器无法附加到进程 | 1. 目标应用有反调试检测。 2. MT管理器Root权限未生效。 | 1. 尝试在应用启动后再附加,避开初始反调试。 2. 重启MT管理器,确认Magisk/SuperSU已授权。 |
| 内存搜索无结果 | 1. 搜索时机不对,Dex还未解密加载。 2. 加固修改了Dex魔数。 3. 搜索范围或类型错误。 | 1. 尝试在应用完全启动后,多等几秒再搜索。 2. 尝试搜索 dex\n036\0(Android O)或dex\n037\0(Android P)。3. 确认选择“十六进制”搜索,并输入正确的字节序列。 |
| DUMP出的文件反编译失败 | 1. Dex文件不完整或起始地址错误。 2. 内存中的数据已被破坏或混淆。 | 1. 重新确认起始地址,尝试DUMP更大范围,然后手动根据file_size精确裁剪。2. 换用Frida等动态Hook工具,在Dex加载的瞬间DUMP。 |
| 应用启动闪退 | 1. MT管理器的Activity记录或内存操作触发了加固的崩溃保护。 2. 系统环境不兼容。 | 1. 尝试不使用Activity记录,而是在应用启动后,快速切换到MT管理器进行附加和搜索。 2. 更换手机系统或Android版本尝试。 |
5.4 个人实操心得
- 耐心与时机:内存DUMP脱壳是个“时机活”。有时候需要反复启动应用、尝试不同的附加时机才能成功。建议在操作前,清理后台,确保一个纯净的环境。
- 多工具协同:不要死磕MT管理器。当MT管理器搞不定时,立刻想到Frida。准备一个常用的Frida脱壳脚本(例如基于
DexFile的mCookieDUMP),能解决90%的难题。 - 文件大小是关键:从内存DUMP数据后,一定要用十六进制编辑器核对Dex头部的
file_size字段。这是修复出正确Dex的唯一可靠依据。盲目保存DUMP的整个文件,99%是无法直接分析的。 - 注意系统版本:不同Android版本,Dex文件格式、加载细节略有差异。遇到问题,先查查目标应用的编译SDK版本和手机系统版本,这能帮你缩小排查范围。
6. 总结与后续分析建议
通过以上步骤,我们完成了一次使用MT管理器对360加固应用的静态脱壳。这个过程本质上是对加固运行时行为的“快照”捕捉。成功DUMP并修复出Dex文件,只是逆向分析的第一步。接下来,你可以用反编译工具打开这个Dex,研究其业务逻辑、算法实现或寻找潜在的安全漏洞。
对于更复杂的加固方案(如企业版360加固、腾讯乐固等),它们可能采用了更深的混淆、虚拟化保护或更强的反调试机制。这时,单纯的MT管理器内存DUMP可能力不从心,需要结合Frida、Xposed、Unidbg等高级工具进行动态分析、算法还原甚至指令虚拟化跟踪。
逆向工程是一场与防护技术的持续博弈。理解基础原理,掌握核心工具链,保持耐心和探索精神,才能层层剥开看似坚固的“盔甲”。希望这份基于MT管理器的全流程解析,能为你打开安卓逆向脱壳这扇门提供一块坚实的敲门砖。记住,所有技术都应在法律和道德允许的范围内,用于安全研究和个人学习提升。