executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-mobile-packAndroid 加固脱壳专项:乐固/360/梆梆/爱加密、DEX 恢复。 触发词:脱壳、Android加固、DEX脱壳、乐固、梆梆、360加固、爱加密
Independent GitHub snapshot · Automated classification · Original documentation governs
动态脱壳默认在受控设备 / 模拟器快照内执行([[re-analyze/platform-tips]] 最高原则——默认沙箱)。所有工具先验证再使用。
pip install frida-tools(Python 3.8+;建议 venv);frida-server 版本必须与主机一致并推送设备(安装与反检测完整流程见 [[re-frida]] 工具准备)pip install frida-dexdump(Python 3)——运行时搜索内存中的 DEX 魔数并 dumpfrida --version;frida-dexdump -h(能看到 -U/-f/-d 参数)frida-dexdump -U -f <包名>(spawn 起步脱壳)、frida-dexdump -U <pid>(attach)、frida-dexdump -U -f <包名> -d(深度搜索,覆盖多 DEX / 部分抽取)https://github.com/CodingGay/BlackDex/releases;32 位与 64 位是两个独立 APK(目标 App 不出现在列表就换另一个架构版本)hook_*.dex(hook 系统 API 得到)与 cookie_*.dex(DexFile cookie 技术)https://github.com/Youlor/Youpk——基于 Android 7.1.2_r33 二次开发,仅支持 Google Pixel 1:Android Studio 构建后 flash-all.sh 刷入定制 ROMadb shell "echo <包名> >> /data/local/tmp/unpacker.config" → 启动目标 App 自动主动调用脱壳(日志见 "unpack end")→ adb pull /data/data/<包名>/unpackerjava -jar dexfixer.jar ./unpacker ./out(配套 DEX 修复,回填方法指令)adb shell ls /data/data/<包名>/unpacker 能看到 dex/method 产物adb --version;模拟器场景 adb shell 即可dexdump -hmemory dump 或按 [[re-memdump]] 从转储 grep DEX 魔数 dex\n0xx 提取——frida-dexdump 不可用时的兜底路径按顺序执行,每步产物(DEX 路径 + sha256)存档(见 [[re-triage]])。
加固识别(先确认再动手):
com.stub.StubApp(爱加密)、com.secneo.apkwrapper / com.bangcle.*(梆梆)等;入口 Application 被替换成壳类ls out/lib/——libjiagu.so / libprotectClass.so(360 加固)、libDexHelper.so / libexec.so(爱加密)、libsecexe.so / libsecmain.so(梆梆)ls -la out/classes*.dex——真实 DEX 加密存放(assets/ 或运行时解密),壳内 classes.dex 体积异常小运行脱壳(frida-dexdump,默认路径):
adb shell monkey -p <包名> 1 # 先启动 App,让壳把真 dex 加载进内存
frida-dexdump -U -f <包名> # 或 spawn 起步
frida-dexdump -U <pid> # 已运行 attach
frida-dexdump -U -f <包名> -d # 深度搜索(多 DEX / 部分抽取场景)
产物在当前目录 <包名>/<时间戳>/*.dex。时机:等 App 进到业务页面再 dump([[re-analyze/platform-tips]] 关键经验——转储时机),一启动就 dump 拿到的是壳初始状态。
静态脱壳(BlackDex / Youpk,frida 被检测时的替代路径):
unpacker/ 目录 → java -jar dexfixer.jar ./unpacker ./outDEX 修复与完整性检查:
file out/*.dex # 应见 "Dalvik dex file version 035"(magic: dex\n035\0)
dexdump out/classes.dex 2>/dev/null | head -30
jadx -d java-out out/ # 反编译验证:业务类是否齐全
-d 深度搜索兜底;jadx 多 DEX 直接分析脱壳后分析(走 [[re-apk]] 全流程):
-d 深度搜索、hook ClassLoader 枚举已加载 dex([[re-frida]] 枚举)、内存转储全部提取;jadx 直接加载全部 dex 分析VMRunner.invoke("...") 空壳,模拟器上跑几秒就退;原因——Play 上架自动套的加固三件套:①代码虚拟化:逻辑抽进加密 VM blob(assets 随机名无扩展名文件,\x00IAP 头为解密判据)+ native 解释器 libpairipcore.so(executeVM 等符号名运行时从 XOR 表解码,strings 搜不到);②TEE 密钥:blob 是 AES/GCM 密文,wrapping key 存在设备 TEE(AndroidKeyStore),Play 经 importWrappedKey(SecureKeyWrapper ASN.1)下发——三个硬前提:Play 安装(gpdeku split 载体)、过 Play Integrity、有登录 Google 账号,缺一即 Finsky 日志 FAILURE → 本地伪造 isEncryptionKeyPresent() 也没用;③运行时反篡改:dl_iterate_phdr/opendir 扫 maps 发现注入 so → 故意给 std::vector 喂非法 length → std::__throw_length_error abort(tombstone 指纹 length_error was thrown in -fno-exceptions mode)→ abort 被中和则执行流落 abort 下一条指令踩内存 SIGSEGV + SIG_DFL 复位——信号层 hook 拦不住,根因在检测端(maps 不露脸);对策——先过 Integrity(三绿真机或 PlayIntegrityFix)+ 清掉可见注入模块(Zygisk disable 后重启)VMRunner 任何方法(getVmByteCode/executeVM/readByteCode)进程立刻自毁;原因——PairIP 盯 ArtMethod 完整性:frida hook 改写 entry_point_from_quick_compiled_code 即命中检测;对策——反射直接调用解密函数(getVmByteCode 是 private static,frida 反射可调;blob 名带不带 assets/ 前缀版本间不一致,两种都试),零 hook 零 ArtMethod 改动即可解出全部 blob 明文——脱 PairIP 不需要内核级隐身,只有必须动态跟解释器时才需要lib*sec*/lib*shell* 风格)、动态 DEX loader so、壳 stub 入口类、单一超大 classes.dex 且无业务字符串、smali→dex 往返拆出多个空 stub DEX);确认加固即放弃 apktool 重打包;转储内存必须卡解密窗口——壳瞬态自卸载,/proc/self/maps 里可能都看不到壳,过早/过晚都拿不到解密 DEX;若应用自身还自检「壳是否存在」,脱壳需一并中和该检查(来源:reverse-skills(inliver233),MIT)