ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

apk-reverse dex补丁实战(下):会毁掉你构建的 dex 头部完整性字段

apk-reverse dex补丁实战(下):会毁掉你构建的 dex 头部完整性字段 apk-reverse dex补丁实战下会毁掉你构建的 dex 头部完整性字段【免费下载链接】apk-reverseSuitable for Android APK reverse engineering analysis项目地址: https://gitcode.com/gh_mirrors/ap/apk-reverse在 apk-reverse 这个安卓 APK 逆向分析项目里dex 补丁有两种路线整方法重写和原地等长字节补丁。前一篇讲了怎么定位指令、怎么打补丁这一篇只讲最容易翻车、也最容易被忽视的一步——重新计算 dex 头部的 checksum 与 signature 两个完整性字段。顺序写反你的补丁文件就会在设备上看起来能装、实际全挂。为什么头部完整性字段是最隐蔽的翻车点 一个 dex 文件的头部里有 4 个看不见的守卫字段位置算法覆盖范围checksum第 8~12 字节adler32从第 12 字节到文件尾signature第 12~32 字节SHA-1从第 32 字节到文件尾你在文件任意位置改了哪怕 1 个字节这两个字段立刻失效。而最坑的是失效后的症状根本不是校验失败四个字Android 日志打印Failure to verify dex file ...: Bad checksum (computed, expected)——注意真正的正确值会被当成 expected 显示方向是反的系统随后降级为直接解释执行这个 dex进程可能照常启动但类加载器开始随机罢工ClassNotFoundException: 你的 Application 类或者某个功能页打不开、某类VerifyError。也就是说我构建的 APK 坏了这个结论其实根因只是头部两个字段过期了。排查方向完全被带偏这就是它毁掉构建的方式。关键规则signature 先算checksum 后算 ⚠️两个字段的覆盖范围是嵌套的——checksum的覆盖范围包含了signature所在的字节。所以重算顺序只有一种正确写法data[12:32] hashlib.sha1(data[32:]).digest() # 第一步signature data[8:12] zlib.adler32(data[12:]).to_bytes(4, little) # 第二步checksum如果反过来先算checksum此时signature字段还是旧的或被清零adler32 就是拿着一份错误的输入算出来的——无论你后面怎么改这个头部永远校验不过。更糟的是有些 R8/优化工具产出的 dex其signature字段本来就是全零已知产物缺陷。这类文件在没打过补丁前自洽bug 完全隐形一旦你动了任何字节再按错误顺序重算问题才爆出来——而且看起来像你的补丁搞坏的。真实案例记录见 l1-equal-length-patch-case-4.md。项目中已经把正确顺序固化成了工具函数fix_dex_header()—— 按正确顺序重算两个字段dexutil.pyverify_dex_header()—— 返回(checksum_ok, signature_ok)写完必须自检dexutil.py用 dex_patch_bytes.py 打补丁时头部修复是自动的 ✅如果你用项目的字节补丁脚本头部完整性由工具兜底流程是这样的先结构校验源码 dex结构不清直接拒写按 JSON spec 定位指令、校验expect_next极性检查等长替换指令字节调用fix_dex_header重算头部然后自我校验不通过就FATAL: header does not self-verify; nothing written拒绝写出坏文件。工具源码dex_patch_bytes.py等长字符串补丁脚本 dex_strpatch.py 同理替换字符串后先写sha1(data[32:])到 12~32再写adler32(data[12:])到 8~12顺序一步不乱。想验证整套行为是否符合预期可以看回归测试里的硬断言补丁前后只有第 8~32 字节的头部字段和被改的 4 个指令字节变化且输出必须通过verify_dex_header自检——见 test_dex_patch_bytes_regression.py。打补丁前后自己动手验证一次的三步清单 工具说成功不算数自己从写出的字节重新推一遍才算数重算并比对对输出的 dex 重新计算sha1(data[32:])和adler32(data[12:])两个都要和文件里存的值相等——这一步能同时证明顺序是对的全文件 diff原始文件 vs 补丁文件差异应只出现在你声明的字节窗口 头部 8~32 字节重解码把补丁后的方法完整解码一遍断言恰好落在insns_off insns_size * 2结束防止替换指令吞掉了下一条。常见错误 → 症状对照表 你犯的错设备上的表现实际根因checksum 先于 signature 重算Bad checksum日志 ClassNotFoundException头部顺序写反只改了字节完全没重算头部启动随机崩溃、类加载失败两个字段全部过期在signature全零的 R8 产物上打补丁补丁后才开始报错像补丁的锅源文件本来就带陈旧字段非等长替换指令方法解码错位VerifyError越过了指令边界与头部无关但常被混淆延伸阅读 等长字节补丁完整约束与指令格式表byte-level-patching.md方法级重写 vs 字节补丁的选型决策dex-patching.md真实案例UnCrackable-Level1 四字节补丁全链路l1-equal-length-patch-case-4.md打完补丁之后的重打包、签名与验证规则SKILL.md一句话总结dex 补丁本身只有几个字节但决定成败的是那 24 字节的头部——signature 先算、checksum 后算、写完必自检。把这三件事变成肌肉记忆你的构建就不会再被看似合理的头部悄悄毁掉。【免费下载链接】apk-reverseSuitable for Android APK reverse engineering analysis项目地址: https://gitcode.com/gh_mirrors/ap/apk-reverse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表