AI自动化脱壳②:42 个 DEX 已经 Dump 出来,为什么只有 5 个能打开?

作者:0xSec笔记本 发布:2026-08-25 08:08 收录:2026-09-03 09:16 2 次阅读 约 15375 字
摘要:0xSEC 笔记本AI FORENSICS / 002AI × ANDROID · 自动化脱壳 0242 个
推荐理由:本文涵盖「DEX脱壳」、「Androguard」、「Frida-dexdump」等多个主题,重点关注 DEX脱壳。
0xSEC 笔记本
AI FORENSICS / 002
AI × ANDROID · 自动化脱壳 02

42 个 DEX 已经 Dump 出来
为什么只有 5 个能打开?

第一篇把加固 APK 里的运行时代码导了出来。第二个问题随即出现:日志已经显示 All done,42 个文件也真实存在,但解析器只接受 5 个。我让 AI 把“打不开”拆成可计算的 Header 字段、逐文件修复和机器复验,最终把可解析数从 5/42 提高到 17/42。

修复原始副本 · 逐文件完整 SHA256 · 解析成功不等于源码完整
INDEX / 目录All done 的真实含义零基础:内存 DEX固定 42 个基线DEX Header审计工具源码三脚本自动化五个真实文件42 个逐文件复验日志 MD5AI 做了什么六个为什么完成边界完整复现下一篇
0x00

42 个文件真实落盘,不等于 42 个都能解析

脱壳工具最后打印了 [*] All done...。输出目录里也确实存在 42 个互不重复的 DEX。可我把它们逐个交给 Androguard 4.1.4 后,只有 5 个返回解析成功。

INFO:frida-dexdump:[+] Searching...
INFO:frida-dexdump:[*] Successful found 49 dex, used 3 time.
INFO:frida-dexdump:[+] Starting dump to './work/raw_dex'...
...
INFO:frida-dexdump:[*] All done...

真实日志不是“发现 42 个”,而是发现 49 个候选区域。逐行计数得到 42 条保存日志和 4 条 memory_dump 访问冲突;源码只剩一条未打印保存日志的分支——MD5 已出现后执行 continue。因此剩余数量为 49 - 42 - 4 = 3,对应 3 个重复 MD5 候选。

● ● ●0xSEC_CAPTURE / FIG.01
49 个候选 DEX 到 42 个落盘文件的精确对账
图 1 49 个候选区域逐项对账:42 个保存、4 个访问冲突、3 个 MD5 重复跳过。
All done 的准确含义:
它表示候选区域循环执行完毕,不表示每个候选都成功读取,也不表示 42 个落盘文件通过 Header 校验、结构解析或源码恢复。

如果只看工具最后一行,我会把“转储循环执行完毕”误写成“42 个 DEX 全部恢复”。如果只看文件扩展名,我又会把 37 个解析失败文件当成已经可用的源码载体。AI 在这里最有价值的工作,不是宣布成功,而是继续追问:每个文件的魔数、长度、Header 大小、端序、SHA-1、Adler-32、解析状态分别是什么?

42落盘 DEX
42 个完整 SHA256
5/42修复前
可解析
17/42修复后
可解析
28,10317 个可解析 DEX
class_def 合计
● ● ●0xSEC_CAPTURE / FIG.02
42 个 DEX 修复前后精确对比
图 2 Header 修复前后:可解析数从 5/42 提高到 17/42;25/42 仍保留为解析失败,不用修复后的校验字段替代结构解析结果。
📢 免责声明
本文内容仅供学习参考,所述技术仅限用于合法授权的安全研究、教学演示及防御机制开发。请勿用于未经授权的访问、测试、数据获取或其他违法活动。读者应自行确保使用行为符合适用的法律法规,并承担因不当使用本内容产生的相应责任。
公开版脱敏说明:应用显示名、真实包名、版本、文件大小、原始 APK 的 MD5/SHA256、设备序列号及可关联业务主机均不公开。日志中的 YOUR_AUTHORIZED_PACKAGE 和方括号字段是公开占位符,不是证据值;42 个 DEX 的数量、完整逐文件哈希和修复结果仍按真实产物保留。
本篇只解决一个技术问题:对同一份样本在隔离设备中产生的 42 个运行时 DEX,保留原始转储,创建修复副本,重算 Header 中可确定的长度、SHA-1 和 Adler-32 字段,再用同一解析器逐文件复验。本文不讨论应用业务性质,不把修头写成完整结构修复,也没有生成可重新安装的 APK。
0x01

0. 从零开始:为什么内存里的 DEX 能运行,导出后却打不开?

先把 DEX 想成一本带目录和防错码的技术手册。真正的类、方法和指令是正文;最前面的 0x70 字节 Header 则记录版本、全文长度、目录位置,以及两项完整性值。Android 运行时已经装载并使用某段代码,不等于把该内存片段原样另存为文件后,离线解析器会跳过自己的文件校验。

层次
它回答什么
本文的验收方式
文件存在
输出目录里有没有真实字节?
逐文件大小与完整 SHA256
Header 自洽
魔数、长度、端序、SHA-1、Adler-32 是否与落盘字节一致?
Python 按字段公式重算
结构可解析
map、string、type、class_data 等结构能否被固定解析器读取?
Androguard 4.1.4 逐文件实例化 DEX
源码有价值
是否含有需要分析的类,而不是零类、单类或公共依赖?
class_def、命名空间与真实方法体复核
为什么转储工具要自己写 fix_header()
工具从扫描到的地址按候选长度复制内存字节。作者已经预见落盘切片的 magic、file_size、header_size 或 endian tag 不满足文件工具预期,所以在写盘前修正这四处。本文的源码审计进一步发现,该函数没有重算 SHA-1 与 Adler-32。
为什么解析成功也不能直接写成 Header 完整?
本轮修复前有 5 个 DEX 能被 Androguard 解析,但只有 3 个同时满足 SHA-1 signature 与 Adler-32 checksum。另 2 个文件 checksum 正确、signature 错误,解析器仍然接受。解析器的接受条件与完整性核验不是同一件事。
本轮验收目标:不以文件扩展名判断 DEX 是否可用,而是分别回答“存在、完整、自洽、可解析、含类”五个逐文件问题。
0x02

第一步不是修,而是把修复前状态固定下来

本次实验继续使用第一篇中的同一份 APK。内部复核材料用完整 MD5 与完整 SHA256 固定样本身份;公开版不展示原始 APK 身份字段:

文件大小:内部复核值不公开
原始 APK MD5:内部复核值不公开
原始 APK SHA256:内部复核值不公开

42 个 DEX 是第一次成功转储轮次的原始输出,总计 62155380 字节。最小文件是 classes09.dex,284 字节;最大文件是 classes05.dex,6897932 字节。版本字段实测为 DEX 035 共 15 个、DEX 039 共 27 个。

修复脚本不在原目录覆盖文件,而是把每个结果写入新的 ./work/repaired_dex。脚本现在会拒绝源目录与输出目录相同,也会拒绝覆盖输出目录中已经存在的同名 DEX。这样才能同时回答“原始转储是什么”和“修复算法改了什么”。

检查项
原始转储 42 个
修复副本 42 个
文件数
42
42
互不重复的完整 SHA256
42
42
magic 正确
42
42
Header file_size 等于落盘长度
42
42
header_size 等于 0x70
42
42
endian_tag 合法
42
42
SHA-1 signature 正确
5
42
Adler-32 checksum 正确
28
42
Androguard 解析成功
5
17
Androguard 解析失败
37
25
解析成功文件的 class_def 合计
810
28103
● ● ●0xSEC_CAPTURE / FIG.03
修复前 42 个 DEX 的 Header 完整性和解析状态不是同一集合
图 3 两个 5/42 不能混写:signature 正确文件与解析成功文件只重合 3 个。

修复前 42 个文件可以精确分成四组:3 个 signature 与 checksum 均正确且解析成功;2 个 signature 错误但解析成功;23 个 checksum 通过但因 HiddenApi flag 4 或 6 解析失败;14 个 checksum 错误并全部先报 Wrong Adler32 checksum

为什么不用 file *.dex 的输出当完成标准?
file 主要识别魔数、版本和头部外观。一个文件能被识别为 Dalvik dex,不代表 map、class_data、method_code 等内部结构都能被解析。本文的机器验收同时检查 Header 三项完整性与解析器结果。
基线口径:修复前 42 个文件均有独立完整 SHA256;5/42 可解析,37/42 解析失败。这个状态固定后,后续的“17/42”才是能够直接对照的实测变化。
0x03

DEX Header 里,哪些字段可以确定性重算?

DEX 文件头固定占 0x70 字节。对已经落盘的字节序列,文件长度、SHA-1 signature 与 Adler-32 checksum 都有明确计算规则,不需要 AI 猜值。

● ● ●0xSEC_CAPTURE / FIG.04
DEX Header 字段位置和重算顺序
图 4 本文实际重算的 Header 字段:file_size、signature、checksum;计算顺序不可颠倒。
偏移
字段
本文的确定性计算
0x00–0x07
magic / version
要求前 4 字节为 dex\n;本批次保留原版本 035 或 039。
0x08–0x0B
checksum
对 0x0C 到文件末尾计算 Adler-32,按小端写回。
0x0C–0x1F
signature
对 0x20 到文件末尾计算 SHA-1,写回 20 字节。
0x20–0x23
file_size
以落盘字节长度写回 32 位小端整数。
0x24–0x27
header_size
写回 DEX Header 固定长度 0x70

把公式写完整,就是:

signature = SHA1(DEX[0x20 : 文件末尾])
checksum  = Adler32(DEX[0x0C : 文件末尾])

注意:checksum 覆盖 signature,
所以必须先写 signature,再写 checksum。
repaired[0x20:0x24] = struct.pack("<I", len(repaired))
repaired[0x24:0x28] = struct.pack("<I", 0x70)
repaired[0x0C:0x20] = hashlib.sha1(repaired[0x20:]).digest()
repaired[0x08:0x0C] = struct.pack(
    "<I", zlib.adler32(repaired[0x0C:]) & 0xFFFFFFFF
)
为什么先写 file_size,再计算 SHA-1,最后计算 Adler-32?
signature 覆盖从 0x20 开始的内容,其中包含 file_size;checksum 又覆盖从 0x0C 开始的内容,其中包含刚写入的 signature。先算 checksum 再改 signature,会立即让 checksum 失效。
为什么本文不把 magic 一律改成 DEX 035?
本批次修复副本实测包含 15 个 DEX 035 与 27 个 DEX 039。修复脚本要求已有 dex\n 魔数并保留原版本,避免把版本号改写当成通用修复。

三种看似合理、实际上会破坏复核的做法

错误做法
为什么不成立
直接覆盖原始 dump
覆盖后无法重新计算源 SHA256,也无法证明改了哪些字节。
先算 checksum,再写 signature
signature 位于 checksum 的覆盖范围内,写完 signature 后先前 checksum 立即失效。
为了让解析器通过而替换 map/type/class_data 数值
这些字段没有由文件字节自动推出的单一值;缺少结构关系证明时,改值属于制造新内容。
本轮修复的物理范围:42 个源/修复文件大小全部相同;39 个文件发生变化,3 个逐字节不变;全套共改变 888 个字节位置。42/42 文件从偏移 0x20 到末尾逐字节相同,实测变化只发生在 checksum 与 signature 区域。
0x04

问题藏在工具源码里:它修了长度,却没重算两项校验

本次使用的 frida-dexdump 2.0.1 在保存前调用 fix_header()。源码显示,它会处理 magic、file_size、header_size 和 endian tag;函数随后直接返回,没有重算 SHA-1 signature 与 Adler-32 checksum。

源码副本:frida_dexdump_2.0.1_main.py
文件大小:4660 bytes
MD5:e35f028f0f0abf5801835a876ee0705d
SHA256:6c15bfa424d023947c3d33378d9e44d75c5a2add3d25d15ecd925079022120db
# frida-dexdump 2.0.1,保留关键行序
bs = self.agent.memory_dump(dex['addr'], dex['size'])
md = md5(bs)
...
bs = fix_header(bs)
with open(out_path, 'wb') as out:
    out.write(bs)

def fix_header(dex_bytes):
    ...
    # 修 magic / file_size / header_size / endian
    return dex_bytes
源码位置
确定性观察
能够得出的结论
81–82
先执行 memory_dump,随后计算 md5(bs)
日志 DexMd5 属于修头前内存字节
83–85
MD5 已存在则 continue
49 个候选中有 3 个重复 MD5 未保存
86–91
fix_header
 后写盘,日志仍打印之前的 md
落盘文件必须重新计算哈希
108–124
只处理 magic、file_size、header_size、endian
没有重算 SHA-1 与 Adler-32

四次失败也必须进入结论

49 个候选中有 4 个在读取内存时触发相同的访问冲突地址 0x762dc5e000,候选起始地址与声明长度分别为:

addr=0x762d7db620  size=6923808
addr=0x762d7db700  size=6660980
addr=0x762d7dbfc0  size=5426448
addr=0x762d7e17b0  size=6179036
为什么不能把 4 次异常删掉?
因为“找到候选”与“成功读取”是两个状态。删除失败日志会让 49 与 42 之间出现无法解释的缺口,也会把工具循环完成伪装成全量读取成功。
由源码能得出的准确结论:工具日志中的 DexMd5 对应 fix_header() 之前的内存字节;落盘文件对应调用后的字节。该工具没有在落盘前重算 DEX Header 的 SHA-1 signature 和 Adler-32 checksum。
这能解释全部 37 个解析失败吗?
不能。它能解释 Header 完整性不一致,也能解释为什么重算后有 12 个文件从解析失败变为成功;修复后仍有 25 个文件触发具体结构解析异常,因此不能把 37 个失败全部归因于两项校验。
● ● ●0xSEC_CAPTURE / FIG.05
原始 DEX 到修复副本和机器验收的自动化链
图 5 AI 协助搭建流程,脚本执行确定性变换,解析器与完整哈希负责验收。
0x05

把“帮我修一下”改成三条互相制约的自动化链

我没有让 AI 直接修改 42 个文件,而是让它生成三个职责分离的脚本:修复脚本只创建副本;核验脚本只逐文件计算 Header 与解析状态;字节审计脚本只比较源/修复集合,证明修复究竟碰了哪些位置。

参与者
本篇实际职责
AI
阅读工具源码、拆解 Header 依赖顺序、生成三份脚本、把异常转成下一项可验证检查。
确定性脚本
读取真实文件、重算字段、输出完整 SHA256、调用固定解析器、比对变化字节并逐文件落表。
限定输入与输出目录、保留原始转储、核对脚本边界、复算汇总数字,并区分已验证结果、解析器观察与未确定原因。
脚本
行数
完整 SHA256
repair_dex_headers.py
69
6e354f292513d3108277af12714d7d6b3b6bfa7a194d7d8faa059485ce23de66
verify_dex_set.py
194
ea0ef81a3b8df3ac50e5e67615c1a22cfe87c0ce09a777b6a05873de8ec35395
audit_dex_repair.py
113
c97d10e7352dcde7ba2b16d418449589b6b93931f132eeb9154080d6d72c2d47
set -eu
mkdir -p ./work/verify

python ./tools/verify_dex_set.py ./work/raw_dex \
  --tsv ./work/verify/raw.tsv \
  --summary ./work/verify/raw.json

python ./tools/repair_dex_headers.py \
  ./work/raw_dex ./work/repaired_dex \
  > ./work/verify/source_to_repaired.tsv

python ./tools/verify_dex_set.py ./work/repaired_dex \
  --tsv ./work/verify/repaired.tsv \
  --summary ./work/verify/repaired.json

python ./tools/audit_dex_repair.py \
  ./work/raw_dex ./work/repaired_dex \
  --tsv ./work/verify/byte_audit.tsv \
  --summary ./work/verify/byte_audit.json

./work/raw_dex 是原始转储输入目录。复现时应放入自己在合法授权环境中获得的 DEX,并从头生成属于该批输入的完整 SHA256、Header 核验结果和解析记录。

让失败条件也自动化

# 下面两次调用都必须返回非 0
python ./tools/repair_dex_headers.py \
  ./work/raw_dex ./work/raw_dex
# refusing to overwrite source DEX: source and output are equal

python ./tools/repair_dex_headers.py \
  ./work/raw_dex ./work/repaired_dex
# 输出目录已有同名 DEX 时拒绝覆盖
自动化的验收条件:输入 42 个、输出 42 个;原始目录不写入;每行保留完整 SHA256;magic、file_size、header_size、endian、signature、checksum 逐项落表;修复后六项均为 42/42;源/修复文件大小 42/42 相同,从 0x20 到末尾 42/42 相同;解析结果逐文件落表。
0x06

不只看汇总:逐字节拆开五个真实 DEX

42 个文件不是同一种错误。下面选取五个文件,不是为了只展示成功,而是分别保留“无需修改、修复成功、只改 4 字节、解析器宽松、修复后仍失败”五种边界。

● ● ●0xSEC_CAPTURE / FIG.06
五个真实 DEX 的修复前后结果
图 6 五种真实结果:修复函数幂等、Header 修复成功、仅 checksum 变化、解析器接受但 signature 错误、Header 修复后暴露结构异常。

样例一:classes10.dex 一个字节都不需要改

文件大小:577588 bytes
源 SHA256:af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169
修复后 SHA256:af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169
实际变化:0 bytes
修复前:解析成功,502 class_def
修复后:解析成功,502 class_def

这证明修复函数对已经自洽的 Header 是幂等的:重新计算得到相同 signature 和 checksum,输出字节与输入完全一致。本轮共有 classes09.dexclasses10.dexclasses15.dex 3 个文件逐字节不变。

样例二:classes.dex 只改 24 字节,恢复 4416 个 class_def

源 SHA256:55d0b11c5f5ea08522442c063e962339d4e90deb9320595824107442f66bd10d
修复后 SHA256:097b85f40cd3c09b534eeaae2fc3c462c388d073147d15f2399c007d518127be

修复前 checksum:8be99671
按原 signature 计算:18486796
修复前 signature:977378c61c36a45e6dd85e3c62eecbbb88714a59
按 0x20 至末尾计算:f228622dccb40f5ab1456ca90e2adc91752fbfba

修复后 checksum:09f76708
修复后 signature:f228622dccb40f5ab1456ca90e2adc91752fbfba
实际变化:偏移 0x08–0x1F,共 24 bytes
解析状态:Wrong Adler32 checksum → 成功,4416 class_def
修复前 48 字节:
00000000: 64 65 78 0a 30 33 35 00 71 96 e9 8b 97 73 78 c6
00000010: 1c 36 a4 5e 6d d8 5e 3c 62 ee cb bb 88 71 4a 59
00000020: 84 67 52 00 70 00 00 00 78 56 34 12 00 00 00 00

修复后 48 字节:
00000000: 64 65 78 0a 30 33 35 00 08 67 f7 09 f2 28 62 2d
00000010: cc b4 0f 5a b1 45 6c a9 0e 2a dc 91 75 2f bf ba
00000020: 84 67 52 00 70 00 00 00 78 56 34 12 00 00 00 00
为什么原始计算值 18486796 不是最终 checksum?
它是基于错误 signature 计算的 Adler-32。先把正确 SHA-1 写入 0x0C–0x1F 后,checksum 覆盖范围发生变化,必须再次计算,最终值才是 09f76708

样例三:classes29.dex 只改 checksum 的 4 个字节

源 SHA256:f50faa6e925772e44cbf7db08af5d9b3f5a3c1595268bfad59c51495c9a7c1b0
修复后 SHA256:4c0fd46d15ea7f30b764de44e5eec1afb6f9b1e226c7b44a0a7944b9db4f4c90
signature:41fddae0324c7ffee1f2d75c89de5363bd7c5ea8(修复前已正确)
checksum:4d88277e → 56e362f9
实际变化:偏移 0x08–0x0B,共 4 bytes
解析状态:Wrong Adler32 checksum → 成功,79 class_def

这个文件说明不能固定地写“修复一个 DEX 就会改 24 字节”。42 个文件的真实变化分布是:0 字节 3 个、4 字节 2 个、22 字节 1 个、23 字节 6 个、24 字节 30 个。

样例四:classes38.dex 修复前能解析,signature 却是错的

源 SHA256:b2d310dc1ab2794bff723bc9d2e79cbb928318295cc03cd7d93491aeadb7ebad
修复后 SHA256:8c5217e754c4133b427b87a534934f45da1f3f6201a720e604d531cb5126a119
修复前 signature:b91c8677b65823f641afb5e55dc291c60996e2c2
计算 signature:ca6a8ef4223151a7ee035e7c29bfd5e8b8489127
解析状态:成功 1 class_def → 成功 1 class_def

这不是说 signature 没有意义,而是说明 Androguard 4.1.4 在本轮输入上“解析成功”的集合不等于“signature 正确”的集合。完整性核验必须独立执行。

样例五:classes14.dex 修好 Header,仍然打不开

源 SHA256:34b666fa173067ba144c64c965fddc355881546e0c680775964294efc9d37e61
修复后 SHA256:60fc0aab932cb91ffa94f3cca37c5a1132b864f1f5191225d10b959fb0f1b4e9
实际变化:24 bytes
修复前:ValueError: Wrong Adler32 checksum for DEX file!
修复后:ValueError: 31992 is not a valid TypeMapItem

修复前,解析器停在 checksum;修复后,解析器进入更深结构并暴露 TypeMapItem 31992。这不是“修坏了”,而是第一道门通过后看见了下一道错误。本篇没有依据替换该结构值,因此保留失败。

0x07

17 个能解析,但这 17 个也不能只写成一个数字

修复后,解析成功文件从 5 个增加到 17 个。其中 12 个是本次重算 Header 后新增的解析成功文件;另外 5 个在修复前已经能解析。

分类
精确文件
数量
修复前已可解析
classes09.dex、classes10.dex、classes15.dex、classes38.dex、classes42.dex
5
修复后新增可解析
classes.dex、classes02.dex、classes03.dex、classes04.dex、classes05.dex、classes06.dex、classes07.dex、classes08.dex、classes11.dex、classes12.dex、classes13.dex、classes29.dex
12
修复后仍解析失败
flag 4 共 15 个、flag 6 共 8 个、TypeMapItem 异常 2 个
25
● ● ●0xSEC_CAPTURE / FIG.07
42 个 DEX 修复后逐文件解析矩阵
图 7 42 个 DEX 的精确矩阵:绿色为解析成功且 class_def 大于 0;黄色为解析成功但 class_def 等于 0;红色为解析失败。

17 个解析成功文件中,classes11.dexclasses12.dexclasses13.dex 的解析结果为 0 个 class_def。因此:

  • “解析器接受该文件”可以写成 17/42
  • “解析后包含至少一个类定义”应写成 14/42
  • 17 个解析成功文件的 class_def 合计仍是实测的 28103,三个零类文件不会改变合计。
为什么 28103 不是 28103 个 Java 文件?
class_def 是 DEX 类定义计数;JADX 最终生成的文件数还会受到输入集合、内部类拆分、反编译成功状态和输出策略影响。第一篇中的 14275 个 Java 文件来自后续筛选的 7 个 DEX 分析集合,不能拿 28103 直接替换。

修复前后,失败类型怎样移动?

阶段
精确异常
文件数
修复前
Wrong Adler32 checksum for DEX file!
14
修复前
HiddenApi...DomapiApiFlag 4
15
修复前
HiddenApi...DomapiApiFlag 6
8
修复后
解析成功
17
修复后
HiddenApi...DomapiApiFlag 4
15
修复后
HiddenApi...DomapiApiFlag 6
8
修复后
TypeMapItem 31992
1
修复后
TypeMapItem 65535
1

14 个 Adler-32 入口失败中,12 个修复后解析成功;classes14.dex 与 classes16.dex 分别进入更深层后暴露 TypeMapItem 31992 和 65535。原来已经进入结构解析的 23 个 HiddenApi 异常文件,修复后仍是同一组 15+8。

25 个失败文件,解析器到底报了什么?

精确异常文本
精确文件
ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag

15 个
classes17.dex、classes18.dex、classes19.dex、classes21.dex、classes22.dex、classes25.dex、classes28.dex、classes30.dex、classes31.dex、classes32.dex、classes34.dex、classes35.dex、classes37.dex、classes39.dex、classes40.dex
ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag

8 个
classes20.dex、classes23.dex、classes24.dex、classes26.dex、classes27.dex、classes33.dex、classes36.dex、classes41.dex
ValueError: 31992 is not a valid TypeMapItem

1 个
classes14.dex
ValueError: 65535 is not a valid TypeMapItem

1 个
classes16.dex
这些错误能直接证明文件“损坏”吗?
不能。本文能复核的事实是:Header 三项校验已经一致,但 Androguard 4.1.4 在读取指定结构值时抛出以上异常。本篇没有形成能够在转储边界、内存态结构、壳处理和解析器兼容性之间确定原因的逐文件实验结论。
为什么不让 AI 把 25 个失败继续“修到能开”?
Header 字段有标准公式;内部 map、class_data 与 code item 的合法边界必须由真实结构关系证明。为了让解析器不报错而替换未知字段,会把“修复”变成伪造。没有可验证规则时,正确结果就是保留失败、记录异常。
0x08

还有一个容易踩坑的细节:日志 MD5 不一定是落盘 MD5

源码调用顺序是先对内存字节计算 MD5,再执行 fix_header(),最后写文件。因此日志中的 DexMd5 是修头前指纹。逐文件复算结果为:

  • 33/42:日志 DexMd5 与落盘 DEX 的 MD5 相同;
  • 9/42:日志 DexMd5 与落盘 DEX 的 MD5 不同;
  • 9 个文件是 classes.dex、classes02.dex、classes03.dex、classes04.dex、classes05.dex、classes06.dex、classes07.dex、classes08.dex、classes29.dex。
文件
日志 DexMd5(修头前)
落盘 MD5
classes.dex
9cf6c991b4ff82e5206875a4780437f2
ea59ca13add07a0d34ecf9a3dc98b148
classes02.dex
63ec8a22f4cb5794d2b0441552bc3d65
41f127905e8800525c854578f17afccb
classes03.dex
8df4ba9a0ecf9791e253eba7e83aabe1
edf4830ececc6b257357aa2eb8d9cfac
classes04.dex
19d4ea49140d1b9e42f41532cd6ef256
62597492b92a5674c251eed86d128727
classes05.dex
59468cbe96edf8765d953b2be683dc0a
1748fe5e6bd911ea5f491829172c4632
classes06.dex
f12e61dcd3c6e72758dc4ce1900fd7c1
b2c44b1d63ff8145402f9133b5a586da
classes07.dex
20ec37aa89701ee1e1bd5c55622abc32
602b06b5259a0e1b032fb9376b803374
classes08.dex
3f5efe431556eba45b0470db6894ce9e
4b218375fd1e994995e126b739bccf77
classes29.dex
20cba490ad8f1d764c2d087459e77a42
5eb4a6d181924d368d40d7b71d57f2f8
● ● ●0xSEC_CAPTURE / FIG.08
frida-dexdump 日志 MD5 和落盘字节的时序关系
图 8 DexMd5 的计算发生在 fix_header 之前;证据身份应对实际落盘文件重新计算完整 SHA256。
实用规则:工具日志中的指纹只表示源码定义的那个阶段。正式记录落盘 DEX 时,必须对真实文件重新计算完整 SHA256;不能把日志 MD5、文件名前缀或截断 hash 当成落盘证据字段。
0x09

AI 真正帮我的,是把“打不开”变成可证伪问题

如果我只问“怎样修复 DEX”,AI 很容易给出一段重算 checksum 的通用代码。真正有用的做法,是把每一轮回答都绑定到真实输出,并且要求下一轮问题能够被命令否定。

轮次
我与 AI 要回答的问题
真实验收
1
All done 到底完成了什么?
49 个候选=42 个保存+4 个异常+3 个重复
2
42 个文件为什么只开 5 个?
42 行 Header 字段+解析器异常,不凭文件扩展名判断
3
转储工具自己改过什么?
读取 frida-dexdump 2.0.1 源码第 81–124 行
4
哪些字段有唯一计算公式?
file_size、header_size、SHA-1、Adler-32
5
修复有没有碰 DEX 主体?
42/42 文件从 0x20 到末尾逐字节相同
6
修复后还剩什么失败?
25 个文件按 15+8+1+1 精确分组
AI 没有资格决定的三件事:
不能凭想象给 TypeMapItem 填一个“正常值”;不能把解析器成功写成源码完整;不能把 28103 个 class_def 写成样本自研类。脚本和解析器提供观察值,分析人员负责限制结论范围。
我从“不会修”变成“能验证”的关键:AI 帮我建立问题顺序和生成工具,但每次进展都必须落成真实文件、完整哈希、逐行 TSV 或精确异常。这样即使 AI 的解释错了,下一条命令也能把它推翻。
0x0A

初学者最容易混淆的六个为什么

为什么 magic 是 dex\n,文件仍打不开?

magic 只证明前几个字节像 DEX。本轮 42/42 magic 正确,但修复前只有 5/42 能解析。长度、checksum、signature 和内部结构都需要独立检查。

为什么同时有 SHA-1、Adler-32,还要另算 SHA256?

SHA-1 signature 与 Adler-32 是 DEX 格式内部字段,用于文件自洽;SHA256 是本文对整个落盘文件建立身份的外部哈希。修复字段后文件身份变化,因此源文件与修复副本必须各自计算完整 SHA256。

为什么 signature 错误的 DEX 还能被解析?

解析器实现可以在不同阶段执行不同检查。本轮 classes38.dex 与 classes42.dex 的 signature 复算不一致,但 Androguard 4.1.4 仍解析成功。这只能描述该版本解析器在这两个输入上的行为,不能推导所有解析器都忽略 signature。

为什么修 Header 后错误信息反而变了?

解析是逐层进入的。classes14.dex 修复前停在 Adler-32,修复后进入 map 并报 TypeMapItem 31992。错误变深说明入口校验已经通过,不等于全部结构已恢复。

为什么不把 25 个失败文件全部交给另一个解析器?

可以做解析器交叉验证,但必须单独记录工具版本和逐文件结果,不能用另一个工具“能打开”覆盖 Androguard 4.1.4 的失败事实。本篇只形成固定解析器的一致基线。

为什么 17 个可解析 DEX 最后只选 7 个进 JADX?

解析成功只代表结构可读。下一步还要排除 3 个零类文件、单类文件、公共依赖和与目标功能无关的命名空间,再建立有分析价值的集合。这正是第三篇要回答的问题。

0x0B

这次到底修复了什么,又没有修复什么?

可以确定的完成项
不能越界写成的结论
42 个原始 DEX 均保留并具有独立完整 SHA256。
不能写成 42 个都包含可用源码。
42 个修复副本的 file_size、signature、checksum 均通过确定性复算。
不能写成 42 个 DEX 的全部内部结构都已修复。
源/修复文件大小 42/42 相同,0x20 至末尾 42/42 相同;共改变 888 个字节位置。
不能写成脚本恢复或重建了 DEX 主体内容。
Androguard 可解析数从 5/42 提高到 17/42。
不能写成任何解析器都必然得到相同结果。
17 个可解析文件合计 28103 个 class_def,其中 3 个文件为 0。
不能把 28103 直接等同于样本自研类数。
25 个失败文件的精确异常与完整 SHA256 已逐行保留。
不能在未复验时把异常统一归因于壳、工具或解析器。
本篇完成边界:这是一轮 DEX Header 完整性修复与固定解析器复验。它没有恢复开发者原工程,没有证明 42 个文件全部完整,没有把 25 个失败文件强行改到解析成功,也没有生成可安装的脱壳 APK。
0x0C

完整复现:三份脚本、四张逐文件表、工具源码和原始日志

到这里,5/42 → 17/42 仍只是一组汇总数字。要重新算出这个结果,必须能够回答四个问题:修复脚本具体改了哪些字节;42 个源文件与修复副本怎样一一对应;每个 Header 字段和解析状态怎样逐文件验收;49 个内存候选为什么最终保存为 42 个文件。下面依次给出对应的脚本、映射、核验表、工具源码和完整转储日志。

附录 A:DEX Header 修复脚本

#!/usr/bin/env python3
"""Repair DEX header signature/checksum on copies of memory-dumped DEX files."""

from __future__ import annotations

import argparse
import hashlib
import struct
import zlib
from pathlib import Path


def repair_dex(data: bytes) -> bytes:
    if len(data) < 0x70:
        raise ValueError(f"DEX shorter than header: {len(data)} bytes")
    if data[:4] != b"dex\n":
        raise ValueError(f"unexpected magic: {data[:8]!r}")

    repaired = bytearray(data)
    repaired[0x20:0x24] = struct.pack("<I", len(repaired))
    repaired[0x24:0x28] = struct.pack("<I", 0x70)
    repaired[0x0C:0x20] = hashlib.sha1(repaired[0x20:]).digest()
    repaired[0x08:0x0C] = struct.pack("<I", zlib.adler32(repaired[0x0C:]) & 0xFFFFFFFF)
    return bytes(repaired)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("source", type=Path)
    parser.add_argument("output", type=Path)
    args = parser.parse_args()

    source_dir = args.source.resolve()
    output_dir = args.output.resolve()
    if not source_dir.is_dir():
        raise SystemExit(f"source directory does not exist: {args.source}")
    if source_dir == output_dir:
        raise SystemExit("refusing to overwrite source DEX: source and output are equal")

    dex_files = sorted(source_dir.glob("*.dex"))
    if not dex_files:
        raise SystemExit("no .dex files found")

    existing_targets = [output_dir / source.name for source in dex_files]
    existing_targets = [target for target in existing_targets if target.exists()]
    if existing_targets:
        raise SystemExit(
            "refusing to overwrite existing repaired DEX: "
            + ", ".join(target.name for target in existing_targets)
        )

    output_dir.mkdir(parents=True, exist_ok=True)

    print("file\tsize\tsource_sha256\trepaired_sha256")
    for source in dex_files:
        raw = source.read_bytes()
        repaired = repair_dex(raw)
        target = output_dir / source.name
        with target.open("xb") as handle:
            handle.write(repaired)
        print(
            f"{source.name}\t{len(raw)}\t{hashlib.sha256(raw).hexdigest()}\t"
            f"{hashlib.sha256(repaired).hexdigest()}"
        )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

附录 B:DEX 逐文件核验脚本

#!/usr/bin/env python3
"""Deterministically inventory and parse every DEX in a directory.

The TSV is the per-file evidence record. The JSON is the machine-readable
summary used to reproduce parser success/failure and class_def totals.
"""

from __future__ import annotations

import argparse
import hashlib
import json
import struct
import sys
import zlib
from collections import Counter
from pathlib import Path

from androguard.core.dex import DEX

try:
    from loguru import logger

    logger.remove()
except ImportError:
    pass


TSV_FIELDS = (
    "file",
    "size",
    "sha256",
    "magic_hex",
    "dex_version",
    "checksum_header",
    "checksum_calculated",
    "signature_header",
    "signature_calculated",
    "header_file_size",
    "header_size",
    "endian_tag",
    "header_class_defs",
    "magic_ok",
    "file_size_ok",
    "header_size_ok",
    "endian_ok",
    "signature_ok",
    "checksum_ok",
    "parse_ok",
    "parsed_class_defs",
    "top_namespaces",
    "parser_error",
)


def dex_sort_key(path: Path) -> tuple[int, str]:
    stem = path.stem
    if stem == "classes":
        return (1, path.name)
    suffix = stem.removeprefix("classes")
    return (int(suffix), path.name) if suffix.isdigit() else (10**9, path.name)


def sanitize(value: object) -> str:
    return str(value).replace("\t", " ").replace("\r", " ").replace("\n", " ")


def class_namespace(name: str) -> str:
    clean = name.removeprefix("L").removesuffix(";")
    parts = [part for part in clean.split("/") if part]
    if not parts:
        return "(empty)"
    if len(parts) == 1:
        return parts[0]
    if parts[0] in {"android", "androidx", "dalvik", "java", "javax", "kotlin"}:
        return parts[0]
    return "/".join(parts[:2])


def inspect(path: Path) -> dict[str, object]:
    raw = path.read_bytes()
    sha256 = hashlib.sha256(raw).hexdigest()
    row: dict[str, object] = {
        "file": path.name,
        "size": len(raw),
        "sha256": sha256,
        "magic_hex": raw[:8].hex(),
        "dex_version": "",
        "checksum_header": "",
        "checksum_calculated": "",
        "signature_header": "",
        "signature_calculated": "",
        "header_file_size": "",
        "header_size": "",
        "endian_tag": "",
        "header_class_defs": "",
        "magic_ok": False,
        "file_size_ok": False,
        "header_size_ok": False,
        "endian_ok": False,
        "signature_ok": False,
        "checksum_ok": False,
        "parse_ok": False,
        "parsed_class_defs": 0,
        "top_namespaces": "",
        "parser_error": "",
    }

    if len(raw) >= 0x70:
        calculated_signature = hashlib.sha1(raw[0x20:]).digest()
        calculated_checksum = zlib.adler32(raw[0x0C:]) & 0xFFFFFFFF
        row["magic_ok"] = raw[:4] == b"dex\n" and raw[7] == 0
        row["dex_version"] = raw[4:7].decode("ascii", errors="replace")
        row["checksum_header"] = f"{struct.unpack_from('<I', raw, 0x08)[0]:08x}"
        row["checksum_calculated"] = f"{calculated_checksum:08x}"
        row["signature_header"] = raw[0x0C:0x20].hex()
        row["signature_calculated"] = calculated_signature.hex()
        row["header_file_size"] = struct.unpack_from("<I", raw, 0x20)[0]
        row["header_size"] = struct.unpack_from("<I", raw, 0x24)[0]
        row["endian_tag"] = raw[0x28:0x2C].hex()
        row["header_class_defs"] = struct.unpack_from("<I", raw, 0x60)[0]
        row["file_size_ok"] = row["header_file_size"] == len(raw)
        row["header_size_ok"] = row["header_size"] == 0x70
        row["endian_ok"] = raw[0x28:0x2C] in {
            b"\x78\x56\x34\x12",
            b"\x12\x34\x56\x78",
        }
        row["signature_ok"] = raw[0x0C:0x20] == calculated_signature
        row["checksum_ok"] = struct.unpack_from("<I", raw, 0x08)[0] == calculated_checksum

    try:
        dex = DEX(raw)
        classes = dex.get_classes()
        namespaces = Counter(class_namespace(item.get_name()) for item in classes)
        row["parse_ok"] = True
        row["parsed_class_defs"] = len(classes)
        row["top_namespaces"] = ";".join(
            f"{name}={count}" for name, count in namespaces.most_common(8)
        )
    except Exception as exc:  # The exact parser exception is evidence.
        row["parser_error"] = f"{type(exc).__name__}: {sanitize(exc)}"
    return row


def write_tsv(path: Path | None, rows: list[dict[str, object]]) -> None:
    lines = ["\t".join(TSV_FIELDS)]
    lines.extend("\t".join(sanitize(row[field]) for field in TSV_FIELDS) for row in rows)
    payload = "\n".join(lines) + "\n"
    if path is None:
        sys.stdout.write(payload)
        return
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(payload, encoding="utf-8")


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("directory", type=Path)
    parser.add_argument("--tsv", type=Path, help="write the per-file TSV here")
    parser.add_argument("--summary", type=Path, help="write the summary JSON here")
    args = parser.parse_args()

    dex_files = sorted(args.directory.glob("*.dex"), key=dex_sort_key)
    if not dex_files:
        raise SystemExit(f"no .dex files found in {args.directory}")

    rows = [inspect(path) for path in dex_files]
    summary = {
        "directory": str(args.directory.resolve()),
        "files": len(rows),
        "unique_sha256": len({row["sha256"] for row in rows}),
        "parse_ok": sum(bool(row["parse_ok"]) for row in rows),
        "parse_fail": sum(not bool(row["parse_ok"]) for row in rows),
        "parsed_class_defs": sum(int(row["parsed_class_defs"]) for row in rows),
        "magic_ok": sum(bool(row["magic_ok"]) for row in rows),
        "file_size_ok": sum(bool(row["file_size_ok"]) for row in rows),
        "header_size_ok": sum(bool(row["header_size_ok"]) for row in rows),
        "endian_ok": sum(bool(row["endian_ok"]) for row in rows),
        "signature_ok": sum(bool(row["signature_ok"]) for row in rows),
        "checksum_ok": sum(bool(row["checksum_ok"]) for row in rows),
    }

    write_tsv(args.tsv, rows)
    summary_text = json.dumps(summary, ensure_ascii=False, indent=2) + "\n"
    if args.summary:
        args.summary.parent.mkdir(parents=True, exist_ok=True)
        args.summary.write_text(summary_text, encoding="utf-8")
    else:
        sys.stderr.write(summary_text)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

附录 C:源/修复 DEX 字节审计脚本

#!/usr/bin/env python3
"""Prove exactly which bytes changed between raw and repaired DEX sets."""

from __future__ import annotations

import argparse
import hashlib
import json
import sys
from pathlib import Path


FIELDS = (
    "file",
    "size",
    "source_sha256",
    "repaired_sha256",
    "changed_bytes",
    "changed_offsets",
    "same_size",
    "changes_within_0x08_0x27",
    "bytes_from_0x20_equal",
)


def dex_sort_key(path: Path) -> tuple[int, str]:
    stem = path.stem
    if stem == "classes":
        return (1, path.name)
    suffix = stem.removeprefix("classes")
    return (int(suffix), path.name) if suffix.isdigit() else (10**9, path.name)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("source", type=Path)
    parser.add_argument("repaired", type=Path)
    parser.add_argument("--tsv", type=Path)
    parser.add_argument("--summary", type=Path)
    args = parser.parse_args()

    source_files = {path.name: path for path in args.source.glob("*.dex")}
    repaired_files = {path.name: path for path in args.repaired.glob("*.dex")}
    if not source_files or not repaired_files:
        raise SystemExit("both directories must contain .dex files")
    if source_files.keys() != repaired_files.keys():
        missing_repaired = sorted(source_files.keys() - repaired_files.keys())
        missing_source = sorted(repaired_files.keys() - source_files.keys())
        raise SystemExit(
            f"filename sets differ: missing_repaired={missing_repaired}, "
            f"missing_source={missing_source}"
        )

    rows: list[dict[str, object]] = []
    for source_path in sorted(source_files.values(), key=dex_sort_key):
        repaired_path = repaired_files[source_path.name]
        source = source_path.read_bytes()
        repaired = repaired_path.read_bytes()
        shared_length = min(len(source), len(repaired))
        offsets = [
            index
            for index in range(shared_length)
            if source[index] != repaired[index]
        ]
        if len(source) != len(repaired):
            offsets.extend(range(shared_length, max(len(source), len(repaired))))
        rows.append(
            {
                "file": source_path.name,
                "size": len(source),
                "source_sha256": hashlib.sha256(source).hexdigest(),
                "repaired_sha256": hashlib.sha256(repaired).hexdigest(),
                "changed_bytes": len(offsets),
                "changed_offsets": ",".join(f"0x{offset:02x}" for offset in offsets),
                "same_size": len(source) == len(repaired),
                "changes_within_0x08_0x27": all(0x08 <= offset < 0x28 for offset in offsets),
                "bytes_from_0x20_equal": source[0x20:] == repaired[0x20:],
            }
        )

    lines = ["\t".join(FIELDS)]
    lines.extend("\t".join(str(row[field]) for field in FIELDS) for row in rows)
    tsv = "\n".join(lines) + "\n"
    if args.tsv:
        args.tsv.parent.mkdir(parents=True, exist_ok=True)
        args.tsv.write_text(tsv, encoding="utf-8")
    else:
        sys.stdout.write(tsv)

    summary = {
        "source": str(args.source),
        "repaired": str(args.repaired),
        "files": len(rows),
        "changed_files": sum(int(row["changed_bytes"]) > 0 for row in rows),
        "unchanged_files": sum(int(row["changed_bytes"]) == 0 for row in rows),
        "total_changed_bytes": sum(int(row["changed_bytes"]) for row in rows),
        "same_size": sum(bool(row["same_size"]) for row in rows),
        "changes_within_0x08_0x27": sum(
            bool(row["changes_within_0x08_0x27"]) for row in rows
        ),
        "bytes_from_0x20_equal": sum(bool(row["bytes_from_0x20_equal"]) for row in rows),
    }
    summary_text = json.dumps(summary, ensure_ascii=False, indent=2) + "\n"
    if args.summary:
        args.summary.parent.mkdir(parents=True, exist_ok=True)
        args.summary.write_text(summary_text, encoding="utf-8")
    else:
        sys.stderr.write(summary_text)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

附录 D:42 个源文件与修复副本的完整 SHA256 映射

file	size	source_sha256	repaired_sha256
classes.dex 5400452 55d0b11c5f5ea08522442c063e962339d4e90deb9320595824107442f66bd10d 097b85f40cd3c09b534eeaae2fc3c462c388d073147d15f2399c007d518127be
classes02.dex 2879428 87f008a16dd7a5ef99034de2d474127d2a84f798e494a0d65256bf586eb5d299 e20287ef6b7f0f7110d4b008fae58d2a92f1a02f7a9afed1400cb7e2102484c7
classes03.dex 1778324 31ed4f5a9d7ff9e481cda3956506f50922d6bb147479309dd109ea5f833fb4ef b79b9afce5de1fcc8d063248813e00864ed20c231d79b57be6fd9c5dcc759d5e
classes04.dex 6635344 a968e5686acd48d10c56cd44d357a96fbcd7f8d94373748d6fdbed5150d2a95b 31b8ad6b191c14a34d3ed520568548c758a931a3366220d1ed3952b9ea8a84fa
classes05.dex 6897932 2bf4d11ed2df017fde48d2a252537cf724e7315e0d8266e6d2d30c96bb712f57 0837a02db066727390da25b25087aaf40f20d23718096372e853c69686509e21
classes06.dex 6153080 909ff6406409a738c526e1584f4dd5629ea053f197761afa4ec4e504b37f0e58 1cf99ceee5ecc0c100cfced27486850f4d6910a517f6bf807445990b4f2d73f0
classes07.dex 2478464 491ec99521122a449c24a50b7a67eeb9690e904893040c5ff813753725811f29 75ceacfdeedf4f59a61c5b0cc31b6b441bdb1f30bcb1e974727aa060ae7bf5cd
classes08.dex 24400 960dca48086129f20ea2ba3dd52e5993679f5656f98c209b7799ff5d5aad6790 510c0b2af2defe660fc22b98d224d867dbf7d1e1f895ef08fb9570676e259d24
classes09.dex 284 9f8898ce35a47aeafced99ea0d17c33e73037bb2307c7688e50819966f4ae939 9f8898ce35a47aeafced99ea0d17c33e73037bb2307c7688e50819966f4ae939
classes10.dex 577588 af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169 af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169
classes11.dex 2908424 8aba8f65aa004764427e749e68deec2126794b77cfa87fddfb128087c0ce6f15 6bf87caeebb4928eda4822292eabafad3aa55b15e4b90bb2ce89cdadbe2c030e
classes12.dex 2504220 6f95033c783a5d89b93500f8b68d40ce7582500655e046c8e1563259c10c21c1 ea7c7dfd8fafef6d9b448944f5a36a8433c49668ac57b1ceeb1178d25ea8104e
classes13.dex 1804020 322f98136572342334e6facfa6716a5b8e158cc6bf913d7ccabbfa4f879137ad 0629fa4a4819a8ed2a8c329aaca386fd2b03ea4d600bc703b98a4431cf8c2922
classes14.dex 93504 34b666fa173067ba144c64c965fddc355881546e0c680775964294efc9d37e61 60fc0aab932cb91ffa94f3cca37c5a1132b864f1f5191225d10b959fb0f1b4e9
classes15.dex 255512 1131295c7abc870772432c49d6e0bb52fac5160cba4d5742eb1d81518b950db7 1131295c7abc870772432c49d6e0bb52fac5160cba4d5742eb1d81518b950db7
classes16.dex 284 43c449a26afe0f11d132192d8a89104f4048915560bca69117b79aaa057bf4ab f0cad9de0ed83090755ae3515c5d80bdd2de2c27646db339931c519d6394db90
classes17.dex 1013340 1f6a823a1669a4cb51b09a3deca50eb014f20493c3b8d15bab1ebbd6f88eee13 da1f939ffdec1b7d5d9da1b7fe3079e3efad19dc38011b937c03964e7a503c45
classes18.dex 499420 0e4c10c378a34985e04a15e5da1c32923a67b35b150a77b48465091b6a23cf60 a61aa408567a245318e3cae2dd3a9aa0deecf98211d284650291043896331e45
classes19.dex 680364 824460c298785a08db194c829848f4f9fc888fd5595d18f9830c44365d734427 11b2a800299c53eab0954b228241e824a49182c3103a520f091860c4ef61f5ee
classes20.dex 2832688 fca125bc2ab5b2ae0033e6e5fe78a2ef037c2888ba87fef81e90c1c84148e74f e964c9b07b77ca97b33de14c27acea5ab76e132e69cce685726f53795d820f8d
classes21.dex 614800 3945bab322e38cf48efcc05afe85c54b9cc70111db48116f6242d0274c0a3214 7dc497285ccd61b96afc7336bdf9038cbd8f15cb3bd6ee05bab903277b60e892
classes22.dex 5182212 e4049ec13d2c4d1e24c427fd0fdbfa4decfc1ef4fd52a72130d23f5e338843de 0dedac4e81f088ab42247bc06e26e3453a2e5cd248896df7f45a697b725706bd
classes23.dex 1212220 a71d29054c5684147c7a20bd54d6401dcb38400d7038aafcc6815b1421eaf262 c379a0b066e919f3199be92b998e1afa3d6b96b14e9620298af27369c7e75ea8
classes24.dex 5269596 07d6659f6af1d8ea4eae517eb78bd410dd64d01d8d7af63ea8fac1a0d5b0cd19 b74c357754e22825f7f45454511c8fb2f1f3e2b98ce55eb9674bacff649db615
classes25.dex 494576 21eecc327d31326c9dee3be96774fd30b5eb8b3a64f874649b6c5282fa32116d e43a29ff6a3924e8298650fe72bf9e8b4126cd69799759049e7b32bc01a6a945
classes26.dex 1477560 8d9df0ece076bc1d78dc9b4593b54d6ffdb99da0a24f6fb45444b16c5de7414c 190831053a69ee9222d9770a4f80b47fb459f529cc49f9c0601bd36768121507
classes27.dex 563660 9133534698f3e259fc793c9f32f8b841432773e7c92bd33efa3eda743909d0af 7ea255a01ddd2753dfa2f195dbde869c9289d41243a65c64dbdab4cfd6fb4823
classes28.dex 464136 5102f935d7846288a5be0955bc7db8d19267d793a6cd87e736999b6facb6712e bec5e57a68567db001837d0fa43aa1ae3bd94f1a89b5203522eb7638225e2036
classes29.dex 67888 f50faa6e925772e44cbf7db08af5d9b3f5a3c1595268bfad59c51495c9a7c1b0 4c0fd46d15ea7f30b764de44e5eec1afb6f9b1e226c7b44a0a7944b9db4f4c90
classes30.dex 382516 627cd94768a6ea67890519345757c1590fb3cee8f7c25e7ae722c5c4cf603719 9d75ea3508a094310caa9f4592b2f79afd637df8691f81f489cbf0c33e36e371
classes31.dex 177444 b75232e68dd13c4dfc54405a30e0a21518a0ccee689be1e59f34843099928810 8fadb485fb67e5795b9bca655db186edb42784893aa51e83ee16cd0d7b0af55d
classes32.dex 65196 d15113dcdee8d56728405f8b28f87d1aeddce7c276769894f5859c67d60d0250 054b13875de8e068ddcdf418692a7ab962315a0facdd17c230641b99fc076d0f
classes33.dex 74956 7629568ea42ceb6b1971c414d3b67ae7f17e0e073960c0235de323310c99a7af 2b0629d59dc51afecd79ee10552d8d92a3c574c83625014a019e7a5cba63c402
classes34.dex 141668 935cc98e5b5af5c6d2ebf89ee874a33fb966bfcb9f341dde449a5aee0409582d ee6a418fabd77868e6e692837b533c7d083db0329a06273c2ac8bbed42c97bda
classes35.dex 75320 e0d40be4e0e209669ff10886077c80ace1cc17152721a10be8eee85307d201a7 3b54393cd9a96c9c001af589e494478ea6ca58d1de27ba1d77f3fdd9edb6e330
classes36.dex 12284 b73507572610552bbcf41ac135f652c8359ee0622675e07e692347e93640e977 4703ca8ba530166547dc9bb07afec7930a4e311d43c74da148d34e5a6b7c3352
classes37.dex 25948 167b1ac6e3c9a2bbbcd97722a8db81fb7e48d2aa843eb9689e508c5269f1626f f5d0fd877459a3ba6496f06f58dcf2493a32658b1e3c907c68ba06b4abefd4a8
classes38.dex 612 b2d310dc1ab2794bff723bc9d2e79cbb928318295cc03cd7d93491aeadb7ebad 8c5217e754c4133b427b87a534934f45da1f3f6201a720e604d531cb5126a119
classes39.dex 9160 2cd61316d09bb5bd7201bf50fad84d3f663575fb5ce5ce359f741872ae0f00ac a073700d4f74f63f0b719304b1fba729da440ca7e48a02aaf18bb55c8c5b03f9
classes40.dex 11976 524d516a12ee7ba854c1920dc3f51165c2e1ff7c070b18d11a8e440f5b1351f2 026af4e41d5845bc4f474609facb4b382b6c7535d3e0a0cff86fb7967ef03286
classes41.dex 408516 dece29d831d4ba640f158f130a4ed0339e1c505e781e5053f9fd324b5e7c3a88 4ca121c27082a6f45665a7b9901f04b844f78b7e71331a11b06534a7b69f5158
classes42.dex 6064 1e2db216cc49ec42da32f8ff3d31eb0f19a7732c5cf0612b885c0d56e401825f 1e2cb8aebd677153b15239bf19bb282ba42211333fdc03326dfc63377164c017

附录 E:修复前 42 个 DEX 的完整 Header 与解析结果

file	size	sha256	magic_hex	dex_version	checksum_header	checksum_calculated	signature_header	signature_calculated	header_file_size	header_size	endian_tag	header_class_defs	magic_ok	file_size_ok	header_size_ok	endian_ok	signature_ok	checksum_ok	parse_ok	parsed_class_defs	top_namespaces	parser_error
classes.dex 5400452 55d0b11c5f5ea08522442c063e962339d4e90deb9320595824107442f66bd10d 6465780a30333500 035 8be99671 18486796 977378c61c36a45e6dd85e3c62eecbbb88714a59 f228622dccb40f5ab1456ca90e2adc91752fbfba 5400452 112 78563412 4416 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes02.dex 2879428 87f008a16dd7a5ef99034de2d474127d2a84f798e494a0d65256bf586eb5d299 6465780a30333500 035 43d8da6d 0015bb48 4e3073b49d63ad85aaefc1752b213c0038b579d4 6679841921c1a7b9518f1e6d66e179bf8d8d5168 2879428 112 78563412 2371 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes03.dex 1778324 31ed4f5a9d7ff9e481cda3956506f50922d6bb147479309dd109ea5f833fb4ef 6465780a30333500 035 0abc94a5 515052c7 ce19f2314f0cc6b1d576ad4cce1fbd4f669360bc 75370ae6acccc036832a1ee2068ea2836a4c8bb8 1778324 112 78563412 1776 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes04.dex 6635344 a968e5686acd48d10c56cd44d357a96fbcd7f8d94373748d6fdbed5150d2a95b 6465780a30333500 035 57e9bf00 dc862a6b dc6dccc1c2c7fdfd93cc9f8756590c9c18e532d2 551c6053c0eb0eaae52db116228e5b0a49fb892c 6635344 112 78563412 6324 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes05.dex 6897932 2bf4d11ed2df017fde48d2a252537cf724e7315e0d8266e6d2d30c96bb712f57 6465780a30333500 035 712e2cc6 6a202b18 768889a85c460f951fec745a7f3953335f47d915 46eec5cbaf92d01911126a6de7cf39b79592f407 6897932 112 78563412 5134 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes06.dex 6153080 909ff6406409a738c526e1584f4dd5629ea053f197761afa4ec4e504b37f0e58 6465780a30333500 035 c59481f2 8de15502 4c478f30a78538f827c32ec68925cd1c70ee4443 d45cc78fc2a3dc3274b1558a2f68319fc141ae55 6153080 112 78563412 4602 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes07.dex 2478464 491ec99521122a449c24a50b7a67eeb9690e904893040c5ff813753725811f29 6465780a30333500 035 a347a4a5 62e18635 154fc4da9cfed9166e62a631b804f9e454642d1c fb5f06ba6941b1bc46fc7474c4b49b6ffab859d8 2478464 112 78563412 2587 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes08.dex 24400 960dca48086129f20ea2ba3dd52e5993679f5656f98c209b7799ff5d5aad6790 6465780a30333500 035 b0735455 4447691f cd77add6e752d5b3236b61f148dcc6dc33fa95bd cd77add6e752d5b3236b61f148dcc6dc33fa95bd 24400 112 78563412 4 True True True True True False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes09.dex 284 9f8898ce35a47aeafced99ea0d17c33e73037bb2307c7688e50819966f4ae939 6465780a30333500 035 d2a82204 d2a82204 40165466736cc1d5a8e9bd01dd8f98e20bd407e0 40165466736cc1d5a8e9bd01dd8f98e20bd407e0 284 112 78563412 1 True True True True True True True 1 Empty=1
classes10.dex 577588 af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169 6465780a30333900 039 fc94307b fc94307b a2a0449ebc008b48a4f5392a83191b3d6602af9b a2a0449ebc008b48a4f5392a83191b3d6602af9b 577588 112 78563412 502 True True True True True True True 502 miui/provider=119;miui/yellowpage=87;com/milink=68;miui/bluetooth=51;miui/util=36;miui/notification=22;com/miui=21;miui/payment=21
classes11.dex 2908424 8aba8f65aa004764427e749e68deec2126794b77cfa87fddfb128087c0ce6f15 6465780a30333500 035 43d8da6d 95a64786 4e3073b49d63ad85aaefc1752b213c0038b579d4 525830743d0d1658a84d76677e0eb94ee9601c5e 2908424 112 78563412 2371 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes12.dex 2504220 6f95033c783a5d89b93500f8b68d40ce7582500655e046c8e1563259c10c21c1 6465780a30333500 035 a347a4a5 ad508cfa 154fc4da9cfed9166e62a631b804f9e454642d1c eb3fbc5bbe266af01b4700e86f2758432c4f2c88 2504220 112 78563412 2587 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes13.dex 1804020 322f98136572342334e6facfa6716a5b8e158cc6bf913d7ccabbfa4f879137ad 6465780a30333500 035 0abc94a5 719f1d6f ce19f2314f0cc6b1d576ad4cce1fbd4f669360bc bef044cc164fa5a3e8469c20e76d735cb29e8ddc 1804020 112 78563412 1776 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes14.dex 93504 34b666fa173067ba144c64c965fddc355881546e0c680775964294efc9d37e61 6465780a30333500 035 4d88277e d25b6767 41fddae0324c7ffee1f2d75c89de5363bd7c5ea8 dd9c73a2fcf8cf24d734a701be2ed3732f896394 93504 112 78563412 79 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes15.dex 255512 1131295c7abc870772432c49d6e0bb52fac5160cba4d5742eb1d81518b950db7 6465780a30333900 039 33422861 33422861 3a90d68606e5e2e50d3960b9ce2efc9514794876 3a90d68606e5e2e50d3960b9ce2efc9514794876 255512 112 78563412 302 True True True True True True True 302 miui/cloud=206;com/xiaomi=96
classes16.dex 284 43c449a26afe0f11d132192d8a89104f4048915560bca69117b79aaa057bf4ab 6465780a30333500 035 d2a82204 9c2c901d 40165466736cc1d5a8e9bd01dd8f98e20bd407e0 0f2fd9721360b1d88253785106c883904761a049 284 112 78563412 4278190080 True True True True False False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes17.dex 1013340 1f6a823a1669a4cb51b09a3deca50eb014f20493c3b8d15bab1ebbd6f88eee13 6465780a30333900 039 ffad814f ffad814f fe730457629abcf637e56a22acd01811731df223 f482808dcf8b85bba7e5e569d4e6537e32894da4 1013340 112 78563412 785 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes18.dex 499420 0e4c10c378a34985e04a15e5da1c32923a67b35b150a77b48465091b6a23cf60 6465780a30333900 039 4a8e5832 4a8e5832 7c251cc15b569617440c6f95d6d8532829e9798c 8683271bb9d7b96de4ff5943eaf74f394f8de5b8 499420 112 78563412 406 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes19.dex 680364 824460c298785a08db194c829848f4f9fc888fd5595d18f9830c44365d734427 6465780a30333900 039 36cd44df 36cd44df 33ff637ed3086f9536f9a4ac354d3c080ed35685 823b5225aab926e707200f3659a6d36165fd9e62 680364 112 78563412 645 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes20.dex 2832688 fca125bc2ab5b2ae0033e6e5fe78a2ef037c2888ba87fef81e90c1c84148e74f 6465780a30333900 039 9f8a756f 9f8a756f 03a85da3fec3d49250f9ddd7217b9b3aa0695942 0f859fa2b04ac5930651d6090da8018530773377 2832688 112 78563412 1747 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes21.dex 614800 3945bab322e38cf48efcc05afe85c54b9cc70111db48116f6242d0274c0a3214 6465780a30333900 039 e87fd7f4 e87fd7f4 5fd2361cd241850131dff427f02850cc96c37bd9 13e089b5957d65b47f420663365f27670164d270 614800 112 78563412 213 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes22.dex 5182212 e4049ec13d2c4d1e24c427fd0fdbfa4decfc1ef4fd52a72130d23f5e338843de 6465780a30333900 039 62b7d812 62b7d812 529e055ff9ac3c8809b8c3c0a78d691f1dfe8d37 bfcf5237804f17b102cdd5ff7d22a33a51a39d84 5182212 112 78563412 3334 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes23.dex 1212220 a71d29054c5684147c7a20bd54d6401dcb38400d7038aafcc6815b1421eaf262 6465780a30333900 039 6713df14 6713df14 6e3421faaa16b76a2d4cb5211e981ea78c622283 271d166e8caee93ae8f7c692d6ad8a05ed2b2e12 1212220 112 78563412 679 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes24.dex 5269596 07d6659f6af1d8ea4eae517eb78bd410dd64d01d8d7af63ea8fac1a0d5b0cd19 6465780a30333900 039 9baeed9d 9baeed9d d2a1a1063e945763e2b92c14d6dd6f08bad90ac7 c4b134bc1c1672ba2293fb2914b99d9cf54b73e6 5269596 112 78563412 3843 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes25.dex 494576 21eecc327d31326c9dee3be96774fd30b5eb8b3a64f874649b6c5282fa32116d 6465780a30333900 039 41f5dd01 41f5dd01 5d17719e0067453aa4fd45c78e419855f378bbc7 b2d0a49a3e9a5f9d431d57033dae039a3f3b422b 494576 112 78563412 446 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes26.dex 1477560 8d9df0ece076bc1d78dc9b4593b54d6ffdb99da0a24f6fb45444b16c5de7414c 6465780a30333900 039 c241bb36 c241bb36 17443fd728d7c8749a4da2b4bf3686eacf42c222 ad68b2e8dfa7595e8e428b643e6b63527ae31869 1477560 112 78563412 1186 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes27.dex 563660 9133534698f3e259fc793c9f32f8b841432773e7c92bd33efa3eda743909d0af 6465780a30333900 039 f2110bd7 f2110bd7 acf248f81b03ebcc79eb2064500c894fed0821f8 75f4659dd9b38a5aded31b53c2aa6aefe772d3e5 563660 112 78563412 449 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes28.dex 464136 5102f935d7846288a5be0955bc7db8d19267d793a6cd87e736999b6facb6712e 6465780a30333900 039 25137052 25137052 862aaccae39c7c37c215435ed95342565fb556da 280c90e1ca2768253d685467af65feb4bb875c0b 464136 112 78563412 346 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes29.dex 67888 f50faa6e925772e44cbf7db08af5d9b3f5a3c1595268bfad59c51495c9a7c1b0 6465780a30333500 035 4d88277e 56e362f9 41fddae0324c7ffee1f2d75c89de5363bd7c5ea8 41fddae0324c7ffee1f2d75c89de5363bd7c5ea8 67888 112 78563412 79 True True True True True False False 0 ValueError: Wrong Adler32 checksum for DEX file!
classes30.dex 382516 627cd94768a6ea67890519345757c1590fb3cee8f7c25e7ae722c5c4cf603719 6465780a30333900 039 1804d68d 1804d68d 9a30f2c1004772b0493d4b84a486e11eec3c5208 a42fc855098a968acf592a61bdad02a99396e2cc 382516 112 78563412 393 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes31.dex 177444 b75232e68dd13c4dfc54405a30e0a21518a0ccee689be1e59f34843099928810 6465780a30333900 039 ec50ef2e ec50ef2e 429a9ded2e7a3b5c4b840b6432f984bf5ebd71a6 bded30e41b4c47132e5bdcebe988828cb8f26924 177444 112 78563412 173 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes32.dex 65196 d15113dcdee8d56728405f8b28f87d1aeddce7c276769894f5859c67d60d0250 6465780a30333900 039 3186400f 3186400f 771e667b05a1f188e7c987202328ddc45e8f7d72 f1d3c662a22e141425ac9ec9c40ba0c694f95619 65196 112 78563412 81 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes33.dex 74956 7629568ea42ceb6b1971c414d3b67ae7f17e0e073960c0235de323310c99a7af 6465780a30333900 039 075b1d68 075b1d68 eeff0a10ad61408280d10220b4ec2d6f7b4cd0a3 b3561db8fcaea52f488c7db6d1b16a9c11889eeb 74956 112 78563412 49 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes34.dex 141668 935cc98e5b5af5c6d2ebf89ee874a33fb966bfcb9f341dde449a5aee0409582d 6465780a30333900 039 2664210d 2664210d 4f7bbb29c51727cb7f5447821871772e60f5189e 83a2c868c6f0fcb4b632f73831c6ad825443239a 141668 112 78563412 139 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes35.dex 75320 e0d40be4e0e209669ff10886077c80ace1cc17152721a10be8eee85307d201a7 6465780a30333900 039 0a6bd5d5 0a6bd5d5 b63e7d8ddb493478b93d7e42361360152de11be9 3808f2579ae37c72134b194c05bd66834dd74522 75320 112 78563412 61 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes36.dex 12284 b73507572610552bbcf41ac135f652c8359ee0622675e07e692347e93640e977 6465780a30333900 039 63c0f276 63c0f276 f93e640033fb6e11150f12aabdf025cf52d8132a b17a11a5b9c64b22b83564a1f2757965c764c4a8 12284 112 78563412 15 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes37.dex 25948 167b1ac6e3c9a2bbbcd97722a8db81fb7e48d2aa843eb9689e508c5269f1626f 6465780a30333900 039 0b356f58 0b356f58 d6961bd714e39ac7cb49a73745120833c23ea8c8 a0794f3a89e8c72af88eafcdc9c806586d7b158a 25948 112 78563412 40 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes38.dex 612 b2d310dc1ab2794bff723bc9d2e79cbb928318295cc03cd7d93491aeadb7ebad 6465780a30333900 039 900667b0 900667b0 b91c8677b65823f641afb5e55dc291c60996e2c2 ca6a8ef4223151a7ee035e7c29bfd5e8b8489127 612 112 78563412 1 True True True True False True True 1 android=1
classes39.dex 9160 2cd61316d09bb5bd7201bf50fad84d3f663575fb5ce5ce359f741872ae0f00ac 6465780a30333900 039 78f9fa98 78f9fa98 8fab2e416785ae290b1c509e52624aa51ccd9967 d34b241e16c4da2b97910bca544fcdc274c99d3e 9160 112 78563412 12 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes40.dex 11976 524d516a12ee7ba854c1920dc3f51165c2e1ff7c070b18d11a8e440f5b1351f2 6465780a30333900 039 895e9b2d 895e9b2d b6cb30c74a87263b8de588e7f1ac91f1b0f9b4e7 1c0b34bafe0d8f57ee46cf6ec6bef40847c8a219 11976 112 78563412 15 True True True True False True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes41.dex 408516 dece29d831d4ba640f158f130a4ed0339e1c505e781e5053f9fd324b5e7c3a88 6465780a30333900 039 06906f66 06906f66 9a2957bdb97b65dd602a7609426a987ec9680bbb 70fdd65e47f0f3ef1fbd619b9b6f0f291632482c 408516 112 78563412 242 True True True True False True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes42.dex 6064 1e2db216cc49ec42da32f8ff3d31eb0f19a7732c5cf0612b885c0d56e401825f 6465780a30333900 039 986807dd 986807dd 9ac617e973c3011fb71ac1125aad6a796898b71d dfca54280288093ed956b83b5d00d74877816e1a 6064 112 78563412 4 True True True True False True True 4 android=4

附录 F:修复后 42 个 DEX 的完整 Header 与解析结果

file	size	sha256	magic_hex	dex_version	checksum_header	checksum_calculated	signature_header	signature_calculated	header_file_size	header_size	endian_tag	header_class_defs	magic_ok	file_size_ok	header_size_ok	endian_ok	signature_ok	checksum_ok	parse_ok	parsed_class_defs	top_namespaces	parser_error
classes.dex 5400452 097b85f40cd3c09b534eeaae2fc3c462c388d073147d15f2399c007d518127be 6465780a30333500 035 09f76708 09f76708 f228622dccb40f5ab1456ca90e2adc91752fbfba f228622dccb40f5ab1456ca90e2adc91752fbfba 5400452 112 78563412 4416 True True True True True True True 4416 com/google=1716;com/huawei=871;com/tencent=549;com/qmuiteam=234;com/sina=166;com/huantansheng=132;com/sensetime=123;com/shuyu=116
classes02.dex 2879428 e20287ef6b7f0f7110d4b008fae58d2a92f1a02f7a9afed1400cb7e2102484c7 6465780a30333500 035 f5d2bb5b f5d2bb5b 6679841921c1a7b9518f1e6d66e179bf8d8d5168 6679841921c1a7b9518f1e6d66e179bf8d8d5168 2879428 112 78563412 2371 True True True True True True True 2371 com/tiocloud=1813;p/a=558
classes03.dex 1778324 b79b9afce5de1fcc8d063248813e00864ed20c231d79b57be6fd9c5dcc759d5e 6465780a30333500 035 8b835202 8b835202 75370ae6acccc036832a1ee2068ea2836a4c8bb8 75370ae6acccc036832a1ee2068ea2836a4c8bb8 1778324 112 78563412 1776 True True True True True True True 1776 com/watayouxiang=1392;p/a=384
classes04.dex 6635344 31b8ad6b191c14a34d3ed520568548c758a931a3366220d1ed3952b9ea8a84fa 6465780a30333500 035 4a0026a3 4a0026a3 551c6053c0eb0eaae52db116228e5b0a49fb892c 551c6053c0eb0eaae52db116228e5b0a49fb892c 6635344 112 78563412 6324 True True True True True True True 6324 com/google=4498;p/a=1738;com/github=88
classes05.dex 6897932 0837a02db066727390da25b25087aaf40f20d23718096372e853c69686509e21 6465780a30333500 035 af312da8 af312da8 46eec5cbaf92d01911126a6de7cf39b79592f407 46eec5cbaf92d01911126a6de7cf39b79592f407 6897932 112 78563412 5134 True True True True True True True 5134 androidx=2894;com/ehking=458;cn/jiguang=358;cn/jpush=291;com/alibaba=234;android=172;com/facebook=163;com/alipay=161
classes06.dex 6153080 1cf99ceee5ecc0c100cfced27486850f4d6910a517f6bf807445990b4f2d73f0 6465780a30333500 035 b9b45663 b9b45663 d45cc78fc2a3dc3274b1558a2f68319fc141ae55 d45cc78fc2a3dc3274b1558a2f68319fc141ae55 6153080 112 78563412 4602 True True True True True True True 4602 p/a=1057;kotlin=880;im/zego=553;com/xiaomi=477;org/webrtc=397;okhttp3/internal=214;com/watayouxiang=164;com/zego=141
classes07.dex 2478464 75ceacfdeedf4f59a61c5b0cc31b6b441bdb1f30bcb1e974727aa060ae7bf5cd 6465780a30333500 035 acb78829 acb78829 fb5f06ba6941b1bc46fc7474c4b49b6ffab859d8 fb5f06ba6941b1bc46fc7474c4b49b6ffab859d8 2478464 112 78563412 2587 True True True True True True True 2587 p/a=2153;com/watayouxiang=168;com/vivo=160;com/tiocloud=76;com/transitionseverywhere=17;com/trello=13
classes08.dex 24400 510c0b2af2defe660fc22b98d224d867dbf7d1e1f895ef08fb9570676e259d24 6465780a30333500 035 4447691f 4447691f cd77add6e752d5b3236b61f148dcc6dc33fa95bd cd77add6e752d5b3236b61f148dcc6dc33fa95bd 24400 112 78563412 4 True True True True True True True 4 com/tianyu=3;com/stub=1
classes09.dex 284 9f8898ce35a47aeafced99ea0d17c33e73037bb2307c7688e50819966f4ae939 6465780a30333500 035 d2a82204 d2a82204 40165466736cc1d5a8e9bd01dd8f98e20bd407e0 40165466736cc1d5a8e9bd01dd8f98e20bd407e0 284 112 78563412 1 True True True True True True True 1 Empty=1
classes10.dex 577588 af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169 6465780a30333900 039 fc94307b fc94307b a2a0449ebc008b48a4f5392a83191b3d6602af9b a2a0449ebc008b48a4f5392a83191b3d6602af9b 577588 112 78563412 502 True True True True True True True 502 miui/provider=119;miui/yellowpage=87;com/milink=68;miui/bluetooth=51;miui/util=36;miui/notification=22;com/miui=21;miui/payment=21
classes11.dex 2908424 6bf87caeebb4928eda4822292eabafad3aa55b15e4b90bb2ce89cdadbe2c030e 6465780a30333500 035 e7eb454c e7eb454c 525830743d0d1658a84d76677e0eb94ee9601c5e 525830743d0d1658a84d76677e0eb94ee9601c5e 2908424 112 78563412 2371 True True True True True True True 0
classes12.dex 2504220 ea7c7dfd8fafef6d9b448944f5a36a8433c49668ac57b1ceeb1178d25ea8104e 6465780a30333500 035 9abe8b57 9abe8b57 eb3fbc5bbe266af01b4700e86f2758432c4f2c88 eb3fbc5bbe266af01b4700e86f2758432c4f2c88 2504220 112 78563412 2587 True True True True True True True 0
classes13.dex 1804020 0629fa4a4819a8ed2a8c329aaca386fd2b03ea4d600bc703b98a4431cf8c2922 6465780a30333500 035 86651e72 86651e72 bef044cc164fa5a3e8469c20e76d735cb29e8ddc bef044cc164fa5a3e8469c20e76d735cb29e8ddc 1804020 112 78563412 1776 True True True True True True True 0
classes14.dex 93504 60fc0aab932cb91ffa94f3cca37c5a1132b864f1f5191225d10b959fb0f1b4e9 6465780a30333500 035 2b1f661b 2b1f661b dd9c73a2fcf8cf24d734a701be2ed3732f896394 dd9c73a2fcf8cf24d734a701be2ed3732f896394 93504 112 78563412 79 True True True True True True False 0 ValueError: 31992 is not a valid TypeMapItem
classes15.dex 255512 1131295c7abc870772432c49d6e0bb52fac5160cba4d5742eb1d81518b950db7 6465780a30333900 039 33422861 33422861 3a90d68606e5e2e50d3960b9ce2efc9514794876 3a90d68606e5e2e50d3960b9ce2efc9514794876 255512 112 78563412 302 True True True True True True True 302 miui/cloud=206;com/xiaomi=96
classes16.dex 284 f0cad9de0ed83090755ae3515c5d80bdd2de2c27646db339931c519d6394db90 6465780a30333500 035 aa4f8e32 aa4f8e32 0f2fd9721360b1d88253785106c883904761a049 0f2fd9721360b1d88253785106c883904761a049 284 112 78563412 4278190080 True True True True True True False 0 ValueError: 65535 is not a valid TypeMapItem
classes17.dex 1013340 da1f939ffdec1b7d5d9da1b7fe3079e3efad19dc38011b937c03964e7a503c45 6465780a30333900 039 aee08411 aee08411 f482808dcf8b85bba7e5e569d4e6537e32894da4 f482808dcf8b85bba7e5e569d4e6537e32894da4 1013340 112 78563412 785 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes18.dex 499420 a61aa408567a245318e3cae2dd3a9aa0deecf98211d284650291043896331e45 6465780a30333900 039 42ad5b24 42ad5b24 8683271bb9d7b96de4ff5943eaf74f394f8de5b8 8683271bb9d7b96de4ff5943eaf74f394f8de5b8 499420 112 78563412 406 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes19.dex 680364 11b2a800299c53eab0954b228241e824a49182c3103a520f091860c4ef61f5ee 6465780a30333900 039 3ccd4491 3ccd4491 823b5225aab926e707200f3659a6d36165fd9e62 823b5225aab926e707200f3659a6d36165fd9e62 680364 112 78563412 645 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes20.dex 2832688 e964c9b07b77ca97b33de14c27acea5ab76e132e69cce685726f53795d820f8d 6465780a30333900 039 e0c87274 e0c87274 0f859fa2b04ac5930651d6090da8018530773377 0f859fa2b04ac5930651d6090da8018530773377 2832688 112 78563412 1747 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes21.dex 614800 7dc497285ccd61b96afc7336bdf9038cbd8f15cb3bd6ee05bab903277b60e892 6465780a30333900 039 3bfed61c 3bfed61c 13e089b5957d65b47f420663365f27670164d270 13e089b5957d65b47f420663365f27670164d270 614800 112 78563412 213 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes22.dex 5182212 0dedac4e81f088ab42247bc06e26e3453a2e5cd248896df7f45a697b725706bd 6465780a30333900 039 d4b4d858 d4b4d858 bfcf5237804f17b102cdd5ff7d22a33a51a39d84 bfcf5237804f17b102cdd5ff7d22a33a51a39d84 5182212 112 78563412 3334 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes23.dex 1212220 c379a0b066e919f3199be92b998e1afa3d6b96b14e9620298af27369c7e75ea8 6465780a30333900 039 50d3e0df 50d3e0df 271d166e8caee93ae8f7c692d6ad8a05ed2b2e12 271d166e8caee93ae8f7c692d6ad8a05ed2b2e12 1212220 112 78563412 679 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes24.dex 5269596 b74c357754e22825f7f45454511c8fb2f1f3e2b98ce55eb9674bacff649db615 6465780a30333900 039 5192edc9 5192edc9 c4b134bc1c1672ba2293fb2914b99d9cf54b73e6 c4b134bc1c1672ba2293fb2914b99d9cf54b73e6 5269596 112 78563412 3843 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes25.dex 494576 e43a29ff6a3924e8298650fe72bf9e8b4126cd69799759049e7b32bc01a6a945 6465780a30333900 039 b0dbdaff b0dbdaff b2d0a49a3e9a5f9d431d57033dae039a3f3b422b b2d0a49a3e9a5f9d431d57033dae039a3f3b422b 494576 112 78563412 446 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes26.dex 1477560 190831053a69ee9222d9770a4f80b47fb459f529cc49f9c0601bd36768121507 6465780a30333900 039 2b8abada 2b8abada ad68b2e8dfa7595e8e428b643e6b63527ae31869 ad68b2e8dfa7595e8e428b643e6b63527ae31869 1477560 112 78563412 1186 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes27.dex 563660 7ea255a01ddd2753dfa2f195dbde869c9289d41243a65c64dbdab4cfd6fb4823 6465780a30333900 039 b77f0eca b77f0eca 75f4659dd9b38a5aded31b53c2aa6aefe772d3e5 75f4659dd9b38a5aded31b53c2aa6aefe772d3e5 563660 112 78563412 449 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes28.dex 464136 bec5e57a68567db001837d0fa43aa1ae3bd94f1a89b5203522eb7638225e2036 6465780a30333900 039 ec906f6c ec906f6c 280c90e1ca2768253d685467af65feb4bb875c0b 280c90e1ca2768253d685467af65feb4bb875c0b 464136 112 78563412 346 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes29.dex 67888 4c0fd46d15ea7f30b764de44e5eec1afb6f9b1e226c7b44a0a7944b9db4f4c90 6465780a30333500 035 56e362f9 56e362f9 41fddae0324c7ffee1f2d75c89de5363bd7c5ea8 41fddae0324c7ffee1f2d75c89de5363bd7c5ea8 67888 112 78563412 79 True True True True True True True 79 com/jg=64;com/qihoo=12;com/stub=3
classes30.dex 382516 9d75ea3508a094310caa9f4592b2f79afd637df8691f81f489cbf0c33e36e371 6465780a30333900 039 932cd7e9 932cd7e9 a42fc855098a968acf592a61bdad02a99396e2cc a42fc855098a968acf592a61bdad02a99396e2cc 382516 112 78563412 393 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes31.dex 177444 8fadb485fb67e5795b9bca655db186edb42784893aa51e83ee16cd0d7b0af55d 6465780a30333900 039 90b5f030 90b5f030 bded30e41b4c47132e5bdcebe988828cb8f26924 bded30e41b4c47132e5bdcebe988828cb8f26924 177444 112 78563412 173 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes32.dex 65196 054b13875de8e068ddcdf418692a7ab962315a0facdd17c230641b99fc076d0f 6465780a30333900 039 6a0940a8 6a0940a8 f1d3c662a22e141425ac9ec9c40ba0c694f95619 f1d3c662a22e141425ac9ec9c40ba0c694f95619 65196 112 78563412 81 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes33.dex 74956 2b0629d59dc51afecd79ee10552d8d92a3c574c83625014a019e7a5cba63c402 6465780a30333900 039 dc7b1eb5 dc7b1eb5 b3561db8fcaea52f488c7db6d1b16a9c11889eeb b3561db8fcaea52f488c7db6d1b16a9c11889eeb 74956 112 78563412 49 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes34.dex 141668 ee6a418fabd77868e6e692837b533c7d083db0329a06273c2ac8bbed42c97bda 6465780a30333900 039 b1322408 b1322408 83a2c868c6f0fcb4b632f73831c6ad825443239a 83a2c868c6f0fcb4b632f73831c6ad825443239a 141668 112 78563412 139 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes35.dex 75320 3b54393cd9a96c9c001af589e494478ea6ca58d1de27ba1d77f3fdd9edb6e330 6465780a30333900 039 a9bdd56e a9bdd56e 3808f2579ae37c72134b194c05bd66834dd74522 3808f2579ae37c72134b194c05bd66834dd74522 75320 112 78563412 61 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes36.dex 12284 4703ca8ba530166547dc9bb07afec7930a4e311d43c74da148d34e5a6b7c3352 6465780a30333900 039 385df4e1 385df4e1 b17a11a5b9c64b22b83564a1f2757965c764c4a8 b17a11a5b9c64b22b83564a1f2757965c764c4a8 12284 112 78563412 15 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes37.dex 25948 f5d0fd877459a3ba6496f06f58dcf2493a32658b1e3c907c68ba06b4abefd4a8 6465780a30333900 039 22ad702a 22ad702a a0794f3a89e8c72af88eafcdc9c806586d7b158a a0794f3a89e8c72af88eafcdc9c806586d7b158a 25948 112 78563412 40 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes38.dex 612 8c5217e754c4133b427b87a534934f45da1f3f6201a720e604d531cb5126a119 6465780a30333900 039 1e92669d 1e92669d ca6a8ef4223151a7ee035e7c29bfd5e8b8489127 ca6a8ef4223151a7ee035e7c29bfd5e8b8489127 612 112 78563412 1 True True True True True True True 1 android=1
classes39.dex 9160 a073700d4f74f63f0b719304b1fba729da440ca7e48a02aaf18bb55c8c5b03f9 6465780a30333900 039 099afc11 099afc11 d34b241e16c4da2b97910bca544fcdc274c99d3e d34b241e16c4da2b97910bca544fcdc274c99d3e 9160 112 78563412 12 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes40.dex 11976 026af4e41d5845bc4f474609facb4b382b6c7535d3e0a0cff86fb7967ef03286 6465780a30333900 039 3b8f9800 3b8f9800 1c0b34bafe0d8f57ee46cf6ec6bef40847c8a219 1c0b34bafe0d8f57ee46cf6ec6bef40847c8a219 11976 112 78563412 15 True True True True True True False 0 ValueError: 4 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes41.dex 408516 4ca121c27082a6f45665a7b9901f04b844f78b7e71331a11b06534a7b69f5158 6465780a30333900 039 5cea6fe7 5cea6fe7 70fdd65e47f0f3ef1fbd619b9b6f0f291632482c 70fdd65e47f0f3ef1fbd619b9b6f0f291632482c 408516 112 78563412 242 True True True True True True False 0 ValueError: 6 is not a valid HiddenApiClassDataItem.DomapiApiFlag
classes42.dex 6064 1e2cb8aebd677153b15239bf19bb282ba42211333fdc03326dfc63377164c017 6465780a30333900 039 9f0206d9 9f0206d9 dfca54280288093ed956b83b5d00d74877816e1a dfca54280288093ed956b83b5d00d74877816e1a 6064 112 78563412 4 True True True True True True True 4 android=4

附录 G:42 个源/修复文件的逐字节变化清单

file	size	source_sha256	repaired_sha256	changed_bytes	changed_offsets	same_size	changes_within_0x08_0x27	bytes_from_0x20_equal
classes.dex 5400452 55d0b11c5f5ea08522442c063e962339d4e90deb9320595824107442f66bd10d 097b85f40cd3c09b534eeaae2fc3c462c388d073147d15f2399c007d518127be 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes02.dex 2879428 87f008a16dd7a5ef99034de2d474127d2a84f798e494a0d65256bf586eb5d299 e20287ef6b7f0f7110d4b008fae58d2a92f1a02f7a9afed1400cb7e2102484c7 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes03.dex 1778324 31ed4f5a9d7ff9e481cda3956506f50922d6bb147479309dd109ea5f833fb4ef b79b9afce5de1fcc8d063248813e00864ed20c231d79b57be6fd9c5dcc759d5e 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes04.dex 6635344 a968e5686acd48d10c56cd44d357a96fbcd7f8d94373748d6fdbed5150d2a95b 31b8ad6b191c14a34d3ed520568548c758a931a3366220d1ed3952b9ea8a84fa 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes05.dex 6897932 2bf4d11ed2df017fde48d2a252537cf724e7315e0d8266e6d2d30c96bb712f57 0837a02db066727390da25b25087aaf40f20d23718096372e853c69686509e21 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes06.dex 6153080 909ff6406409a738c526e1584f4dd5629ea053f197761afa4ec4e504b37f0e58 1cf99ceee5ecc0c100cfced27486850f4d6910a517f6bf807445990b4f2d73f0 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes07.dex 2478464 491ec99521122a449c24a50b7a67eeb9690e904893040c5ff813753725811f29 75ceacfdeedf4f59a61c5b0cc31b6b441bdb1f30bcb1e974727aa060ae7bf5cd 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes08.dex 24400 960dca48086129f20ea2ba3dd52e5993679f5656f98c209b7799ff5d5aad6790 510c0b2af2defe660fc22b98d224d867dbf7d1e1f895ef08fb9570676e259d24 4 0x08,0x09,0x0a,0x0b True True True
classes09.dex 284 9f8898ce35a47aeafced99ea0d17c33e73037bb2307c7688e50819966f4ae939 9f8898ce35a47aeafced99ea0d17c33e73037bb2307c7688e50819966f4ae939 0 True True True
classes10.dex 577588 af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169 af3d0526fa5c97530deb63b5d2a20e2005dcb3b264211c17ca1ec7ab0a2ab169 0 True True True
classes11.dex 2908424 8aba8f65aa004764427e749e68deec2126794b77cfa87fddfb128087c0ce6f15 6bf87caeebb4928eda4822292eabafad3aa55b15e4b90bb2ce89cdadbe2c030e 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes12.dex 2504220 6f95033c783a5d89b93500f8b68d40ce7582500655e046c8e1563259c10c21c1 ea7c7dfd8fafef6d9b448944f5a36a8433c49668ac57b1ceeb1178d25ea8104e 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes13.dex 1804020 322f98136572342334e6facfa6716a5b8e158cc6bf913d7ccabbfa4f879137ad 0629fa4a4819a8ed2a8c329aaca386fd2b03ea4d600bc703b98a4431cf8c2922 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes14.dex 93504 34b666fa173067ba144c64c965fddc355881546e0c680775964294efc9d37e61 60fc0aab932cb91ffa94f3cca37c5a1132b864f1f5191225d10b959fb0f1b4e9 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes15.dex 255512 1131295c7abc870772432c49d6e0bb52fac5160cba4d5742eb1d81518b950db7 1131295c7abc870772432c49d6e0bb52fac5160cba4d5742eb1d81518b950db7 0 True True True
classes16.dex 284 43c449a26afe0f11d132192d8a89104f4048915560bca69117b79aaa057bf4ab f0cad9de0ed83090755ae3515c5d80bdd2de2c27646db339931c519d6394db90 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes17.dex 1013340 1f6a823a1669a4cb51b09a3deca50eb014f20493c3b8d15bab1ebbd6f88eee13 da1f939ffdec1b7d5d9da1b7fe3079e3efad19dc38011b937c03964e7a503c45 23 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes18.dex 499420 0e4c10c378a34985e04a15e5da1c32923a67b35b150a77b48465091b6a23cf60 a61aa408567a245318e3cae2dd3a9aa0deecf98211d284650291043896331e45 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes19.dex 680364 824460c298785a08db194c829848f4f9fc888fd5595d18f9830c44365d734427 11b2a800299c53eab0954b228241e824a49182c3103a520f091860c4ef61f5ee 22 0x08,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes20.dex 2832688 fca125bc2ab5b2ae0033e6e5fe78a2ef037c2888ba87fef81e90c1c84148e74f e964c9b07b77ca97b33de14c27acea5ab76e132e69cce685726f53795d820f8d 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes21.dex 614800 3945bab322e38cf48efcc05afe85c54b9cc70111db48116f6242d0274c0a3214 7dc497285ccd61b96afc7336bdf9038cbd8f15cb3bd6ee05bab903277b60e892 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes22.dex 5182212 e4049ec13d2c4d1e24c427fd0fdbfa4decfc1ef4fd52a72130d23f5e338843de 0dedac4e81f088ab42247bc06e26e3453a2e5cd248896df7f45a697b725706bd 23 0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes23.dex 1212220 a71d29054c5684147c7a20bd54d6401dcb38400d7038aafcc6815b1421eaf262 c379a0b066e919f3199be92b998e1afa3d6b96b14e9620298af27369c7e75ea8 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes24.dex 5269596 07d6659f6af1d8ea4eae517eb78bd410dd64d01d8d7af63ea8fac1a0d5b0cd19 b74c357754e22825f7f45454511c8fb2f1f3e2b98ce55eb9674bacff649db615 23 0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes25.dex 494576 21eecc327d31326c9dee3be96774fd30b5eb8b3a64f874649b6c5282fa32116d e43a29ff6a3924e8298650fe72bf9e8b4126cd69799759049e7b32bc01a6a945 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes26.dex 1477560 8d9df0ece076bc1d78dc9b4593b54d6ffdb99da0a24f6fb45444b16c5de7414c 190831053a69ee9222d9770a4f80b47fb459f529cc49f9c0601bd36768121507 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes27.dex 563660 9133534698f3e259fc793c9f32f8b841432773e7c92bd33efa3eda743909d0af 7ea255a01ddd2753dfa2f195dbde869c9289d41243a65c64dbdab4cfd6fb4823 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes28.dex 464136 5102f935d7846288a5be0955bc7db8d19267d793a6cd87e736999b6facb6712e bec5e57a68567db001837d0fa43aa1ae3bd94f1a89b5203522eb7638225e2036 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes29.dex 67888 f50faa6e925772e44cbf7db08af5d9b3f5a3c1595268bfad59c51495c9a7c1b0 4c0fd46d15ea7f30b764de44e5eec1afb6f9b1e226c7b44a0a7944b9db4f4c90 4 0x08,0x09,0x0a,0x0b True True True
classes30.dex 382516 627cd94768a6ea67890519345757c1590fb3cee8f7c25e7ae722c5c4cf603719 9d75ea3508a094310caa9f4592b2f79afd637df8691f81f489cbf0c33e36e371 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes31.dex 177444 b75232e68dd13c4dfc54405a30e0a21518a0ccee689be1e59f34843099928810 8fadb485fb67e5795b9bca655db186edb42784893aa51e83ee16cd0d7b0af55d 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes32.dex 65196 d15113dcdee8d56728405f8b28f87d1aeddce7c276769894f5859c67d60d0250 054b13875de8e068ddcdf418692a7ab962315a0facdd17c230641b99fc076d0f 23 0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes33.dex 74956 7629568ea42ceb6b1971c414d3b67ae7f17e0e073960c0235de323310c99a7af 2b0629d59dc51afecd79ee10552d8d92a3c574c83625014a019e7a5cba63c402 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes34.dex 141668 935cc98e5b5af5c6d2ebf89ee874a33fb966bfcb9f341dde449a5aee0409582d ee6a418fabd77868e6e692837b533c7d083db0329a06273c2ac8bbed42c97bda 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes35.dex 75320 e0d40be4e0e209669ff10886077c80ace1cc17152721a10be8eee85307d201a7 3b54393cd9a96c9c001af589e494478ea6ca58d1de27ba1d77f3fdd9edb6e330 23 0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes36.dex 12284 b73507572610552bbcf41ac135f652c8359ee0622675e07e692347e93640e977 4703ca8ba530166547dc9bb07afec7930a4e311d43c74da148d34e5a6b7c3352 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes37.dex 25948 167b1ac6e3c9a2bbbcd97722a8db81fb7e48d2aa843eb9689e508c5269f1626f f5d0fd877459a3ba6496f06f58dcf2493a32658b1e3c907c68ba06b4abefd4a8 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes38.dex 612 b2d310dc1ab2794bff723bc9d2e79cbb928318295cc03cd7d93491aeadb7ebad 8c5217e754c4133b427b87a534934f45da1f3f6201a720e604d531cb5126a119 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes39.dex 9160 2cd61316d09bb5bd7201bf50fad84d3f663575fb5ce5ce359f741872ae0f00ac a073700d4f74f63f0b719304b1fba729da440ca7e48a02aaf18bb55c8c5b03f9 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes40.dex 11976 524d516a12ee7ba854c1920dc3f51165c2e1ff7c070b18d11a8e440f5b1351f2 026af4e41d5845bc4f474609facb4b382b6c7535d3e0a0cff86fb7967ef03286 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes41.dex 408516 dece29d831d4ba640f158f130a4ed0339e1c505e781e5053f9fd324b5e7c3a88 4ca121c27082a6f45665a7b9901f04b844f78b7e71331a11b06534a7b69f5158 23 0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True
classes42.dex 6064 1e2db216cc49ec42da32f8ff3d31eb0f19a7732c5cf0612b885c0d56e401825f 1e2cb8aebd677153b15239bf19bb282ba42211333fdc03326dfc63377164c017 24 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f True True True

附录 H:本次审计的 frida-dexdump 2.0.1 主程序源码

第三方工具许可:
frida-dexdump 2.0.1 作者为 hluwa,项目以 GPL-3.0 发布。下列代码保留作者与项目来源;复制、修改或再分发时应继续遵守 GPLv3。项目地址:https://github.com/hluwa/frida-dexdump
# Author: hluwa <hluwa888@gmail.com>
# HomePage: https://github.com/hluwa
# CreateTime: 2021/6/3
import hashlib
import json
import logging
import os.path
import re
import time
from frida_tools.application import ConsoleApplication
from wallbreaker.connection import Connection

from frida_dexdump.agent import DexDumpAgent
from frida_dexdump.banner import show_banner

logger = logging.getLogger("frida-dexdump")
md5 = lambda bs: hashlib.md5(bs).hexdigest()


class SessionConnection(Connection):

    def __init__(self, device, session):
        self.device = device
        self.session = session
        self.process = str(self.session)


class DexDumpApplication(ConsoleApplication):
    agent = None

    def _needs_target(self):
        return True

    def _usage(self):
        return "Usage see: frida-dexdump -h"

    def _add_options(self, parser):
        # fixup frida-tools#75 47d020ad1e51a1a5037c630e2de7136b867e86aa
        if not hasattr(parser, "add_argument") and hasattr(parser, "add_option"):
            setattr(parser, "add_argument", getattr(parser, "add_option"))
        parser.add_argument("-o", "--output", help="Output folder path, default is './<appname>/'.",
                            type=str, action='store')
        parser.add_argument("-d", "--deep-search", help="Enable deep search mode.",
                            action='store_true', dest="enable_deep", default=False)
        parser.add_argument("--sleep", help="Waiting times for start, spawn mode default is 5s.",
                            type=int, action='store', default=None)

    def _initialize(self, parser, options, args):
        self.mds = set()
        self.output = options.output
        self.enable_deep = options.enable_deep
        self.sleep = options.sleep
        # spawn mode
        if self.sleep is None and self._target[0] == "file":
            self.sleep = 5

    def _start(self):
        self.connection = SessionConnection(self._device, self._session)
        self.agent = DexDumpAgent(self.connection)
        self.package_name = self.get_package_name()
        if not self.output:
            self.output = os.path.join(os.getcwd(), self.package_name.replace(":", "-"))
            os.makedirs(self.output, exist_ok=True)
        self._resume()
        if self.sleep:
            logger.info("Waiting {}s...".format(self.sleep))
            time.sleep(self.sleep)
        self.dump()
        self._exit(0)

    def dump(self):
        logger.info("[+] Searching...")
        st = time.time()
        ranges = self.agent.search_dex(enable_deep_search=self.enable_deep)
        et = time.time()
        logger.info("[*] Successful found {} dex, used {} time.".format(len(ranges), int(et - st)))
        logger.info("[+] Starting dump to '{}'...".format(self.output))
        idx = 1
        for dex in ranges:
            try:
                bs = self.agent.memory_dump(dex['addr'], dex['size'])
                md = md5(bs)
                if md in self.mds:
                    continue
                self.mds.add(md)
                bs = fix_header(bs)
                out_path = os.path.join(self.output, "classes{}.dex".format('%02d' % idx if idx != 1 else ''))
                with open(out_path, 'wb') as out:
                    out.write(bs)
                logger.info("[+] DexMd5={}, SavePath={}, DexSize={}"
                            .format(md, out_path, hex(dex['size'])))
                idx += 1
            except Exception as e:
                logger.exception("[-] {}: {}".format(e, dex))
        logger.info("[*] All done...")

    def get_package_name(self):
        try:
            pid = self._session._impl.pid
            for process in self._device.enumerate_processes():
                if process.pid == pid:
                    return process.name
            return "dexdump.unnamed.{}".format(pid)
        except:
            return "dexdump.unnamed"


def fix_header(dex_bytes):
    import struct
    dex_size = len(dex_bytes)

    if dex_bytes[:4] != b"dex\n":
        dex_bytes = b"dex\n035\x00" + dex_bytes[8:]

    if dex_size >= 0x24:
        dex_bytes = dex_bytes[:0x20] + struct.Struct("<I").pack(dex_size) + dex_bytes[0x24:]

    if dex_size >= 0x28:
        dex_bytes = dex_bytes[:0x24] + struct.Struct("<I").pack(0x70) + dex_bytes[0x28:]

    if dex_size >= 0x2C and dex_bytes[0x28:0x2C] not in [b'\x78\x56\x34\x12', b'\x12\x34\x56\x78']:
        dex_bytes = dex_bytes[:0x28] + b'\x78\x56\x34\x12' + dex_bytes[0x2C:]

    return dex_bytes


def main():
    show_banner()
    logging.basicConfig(level=logging.INFO)
    DexDumpApplication().run()


if __name__ == "__main__":
    main()

附录 I:第一次成功转储日志公开脱敏版

公开版把真实包名替换为 YOUR_AUTHORIZED_PACKAGE,并把主机目录规范化为 ./work/raw_dex 与 ./.venv-frida16;49、42、4、3、PID、内存地址、文件大小、MD5、异常类型与行序均未改动。该段不是未经修改的原始日志。


-----------------------------------------------------------------------------
     __      _     _                 _              _                         
   / _|_ __(_) __| | __ _        __| | _____  ____| |_   _ _ __ ___  _ __    
  | |_| '__| |/ _` |/ _` |_____ / _` |/ _ \ \/ / _` | | | | '_ ` _ \| '_ \   
  |  _| |  | | (_| | (_| |_____| (_| |  __/>  < (_| | |_| | | | | | | |_) |  
  |_| |_|  |_|\__,_|\__,_|      \__,_|\___/_/\_\__,_|\__,_|_| |_| |_| .__/   
                                                                    |_|      
                    https://github.com/hluwa/frida-dexdump                   
-----------------------------------------------------------------------------

Spawning `YOUR_AUTHORIZED_PACKAGE`...
INFO:Agent:DexDumpAgent<Connection(pid=Session(pid=23347), connected:True), attached=True>: Attach.
INFO:frida-dexdump:Waiting 8s...
INFO:frida-dexdump:[+] Searching...
INFO:frida-dexdump:[*] Successful found 49 dex, used 3 time.
INFO:frida-dexdump:[+] Starting dump to './work/raw_dex'...
INFO:frida-dexdump:[+] DexMd5=9cf6c991b4ff82e5206875a4780437f2, SavePath=./work/raw_dex/classes.dex, DexSize=0x526784
INFO:frida-dexdump:[+] DexMd5=63ec8a22f4cb5794d2b0441552bc3d65, SavePath=./work/raw_dex/classes02.dex, DexSize=0x2befc4
INFO:frida-dexdump:[+] DexMd5=8df4ba9a0ecf9791e253eba7e83aabe1, SavePath=./work/raw_dex/classes03.dex, DexSize=0x1b2294
INFO:frida-dexdump:[+] DexMd5=19d4ea49140d1b9e42f41532cd6ef256, SavePath=./work/raw_dex/classes04.dex, DexSize=0x653f50
INFO:frida-dexdump:[+] DexMd5=59468cbe96edf8765d953b2be683dc0a, SavePath=./work/raw_dex/classes05.dex, DexSize=0x69410c
INFO:frida-dexdump:[+] DexMd5=f12e61dcd3c6e72758dc4ce1900fd7c1, SavePath=./work/raw_dex/classes06.dex, DexSize=0x5de378
INFO:frida-dexdump:[+] DexMd5=20ec37aa89701ee1e1bd5c55622abc32, SavePath=./work/raw_dex/classes07.dex, DexSize=0x25d180
INFO:frida-dexdump:[+] DexMd5=3f5efe431556eba45b0470db6894ce9e, SavePath=./work/raw_dex/classes08.dex, DexSize=0x5f50
INFO:frida-dexdump:[+] DexMd5=f1771b68f5f9b168b79ff59ae2daabe4, SavePath=./work/raw_dex/classes09.dex, DexSize=0x11c
INFO:frida-dexdump:[+] DexMd5=2132326755e690cd4729e89d3ecc5555, SavePath=./work/raw_dex/classes10.dex, DexSize=0x8d034
ERROR:frida-dexdump:[-] Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23): {'addr': '0x762d7db620', 'size': 6923808}
Traceback (most recent call last):
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/__main__.py", line 81, in dump
    bs = self.agent.memory_dump(dex['addr'], dex['size'])
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/agent/__init__.py", line 24, in memory_dump
    return self._rpc.memorydump(base, size)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 180, in method
    return script._rpc_request(request, data, **kwargs)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 86, in wrapper
    return f(*args, **kwargs)
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 497, in _rpc_request
    raise result.error
frida.core.RPCException: Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23)
ERROR:frida-dexdump:[-] Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23): {'addr': '0x762d7db700', 'size': 6660980}
Traceback (most recent call last):
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/__main__.py", line 81, in dump
    bs = self.agent.memory_dump(dex['addr'], dex['size'])
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/agent/__init__.py", line 24, in memory_dump
    return self._rpc.memorydump(base, size)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 180, in method
    return script._rpc_request(request, data, **kwargs)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 86, in wrapper
    return f(*args, **kwargs)
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 497, in _rpc_request
    raise result.error
frida.core.RPCException: Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23)
ERROR:frida-dexdump:[-] Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23): {'addr': '0x762d7dbfc0', 'size': 5426448}
Traceback (most recent call last):
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/__main__.py", line 81, in dump
    bs = self.agent.memory_dump(dex['addr'], dex['size'])
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/agent/__init__.py", line 24, in memory_dump
    return self._rpc.memorydump(base, size)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 180, in method
    return script._rpc_request(request, data, **kwargs)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 86, in wrapper
    return f(*args, **kwargs)
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 497, in _rpc_request
    raise result.error
frida.core.RPCException: Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23)
INFO:frida-dexdump:[+] DexMd5=77dc553d1e0111391054c418ffa7a101, SavePath=./work/raw_dex/classes11.dex, DexSize=0x2c6108
INFO:frida-dexdump:[+] DexMd5=df0f44584b671b49d45069b471457c88, SavePath=./work/raw_dex/classes12.dex, DexSize=0x26361c
INFO:frida-dexdump:[+] DexMd5=35186e725af35abf9475c15fb7cae9cc, SavePath=./work/raw_dex/classes13.dex, DexSize=0x1b86f4
ERROR:frida-dexdump:[-] Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23): {'addr': '0x762d7e17b0', 'size': 6179036}
Traceback (most recent call last):
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/__main__.py", line 81, in dump
    bs = self.agent.memory_dump(dex['addr'], dex['size'])
  File "./.venv-frida16/lib/python3.13/site-packages/frida_dexdump/agent/__init__.py", line 24, in memory_dump
    return self._rpc.memorydump(base, size)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 180, in method
    return script._rpc_request(request, data, **kwargs)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 86, in wrapper
    return f(*args, **kwargs)
  File "./.venv-frida16/lib/python3.13/site-packages/frida/core.py", line 497, in _rpc_request
    raise result.error
frida.core.RPCException: Error: access violation accessing 0x762dc5e000
    at <anonymous> (frida/runtime/core.js:145)
    at memorydump (src/search.ts:41)
    at call (native)
    at <anonymous> (frida/runtime/message-dispatcher.js:11)
    at o (frida/runtime/message-dispatcher.js:23)
INFO:frida-dexdump:[+] DexMd5=c7f2571de2257af0a1336d04336781d0, SavePath=./work/raw_dex/classes14.dex, DexSize=0x16d40
INFO:frida-dexdump:[+] DexMd5=d9d7cc39a091c08cc354f0c92177e919, SavePath=./work/raw_dex/classes15.dex, DexSize=0x3e618
INFO:frida-dexdump:[+] DexMd5=44084e6878cbb31f2ca70c0bd8ddd26b, SavePath=./work/raw_dex/classes16.dex, DexSize=0x11c
INFO:frida-dexdump:[+] DexMd5=9340a52ffa4ec1fc93ee99b14ca429e6, SavePath=./work/raw_dex/classes17.dex, DexSize=0xf765c
INFO:frida-dexdump:[+] DexMd5=5b7ff8a6157b776643b396df4734570f, SavePath=./work/raw_dex/classes18.dex, DexSize=0x79edc
INFO:frida-dexdump:[+] DexMd5=d0385abed2fd7f2c1bd8c2dcdf9f5966, SavePath=./work/raw_dex/classes19.dex, DexSize=0xa61ac
INFO:frida-dexdump:[+] DexMd5=000e3b8b1bcb10f3c85f982fbbf018ea, SavePath=./work/raw_dex/classes20.dex, DexSize=0x2b3930
INFO:frida-dexdump:[+] DexMd5=685328b2411b5406a94df6cb1116b963, SavePath=./work/raw_dex/classes21.dex, DexSize=0x96190
INFO:frida-dexdump:[+] DexMd5=5db6db3feb9f37ec3acf82c63918c3a8, SavePath=./work/raw_dex/classes22.dex, DexSize=0x4f1304
INFO:frida-dexdump:[+] DexMd5=9c579e4ebd6b165c9b330eb5c1132a53, SavePath=./work/raw_dex/classes23.dex, DexSize=0x127f3c
INFO:frida-dexdump:[+] DexMd5=16322f1041c3ce8b9266f53efd5298a9, SavePath=./work/raw_dex/classes24.dex, DexSize=0x50685c
INFO:frida-dexdump:[+] DexMd5=8e9228435eb9bd695e87af29735241f5, SavePath=./work/raw_dex/classes25.dex, DexSize=0x78bf0
INFO:frida-dexdump:[+] DexMd5=4a582f161d121ec02bdc55a0af6b36d7, SavePath=./work/raw_dex/classes26.dex, DexSize=0x168bb8
INFO:frida-dexdump:[+] DexMd5=267ebbddfcc88da5a55e524c07562ed4, SavePath=./work/raw_dex/classes27.dex, DexSize=0x899cc
INFO:frida-dexdump:[+] DexMd5=828ac28b03147eda52e265863705e4a6, SavePath=./work/raw_dex/classes28.dex, DexSize=0x71508
INFO:frida-dexdump:[+] DexMd5=20cba490ad8f1d764c2d087459e77a42, SavePath=./work/raw_dex/classes29.dex, DexSize=0x10930
INFO:frida-dexdump:[+] DexMd5=2313656b960affe9cdb07d062ee2cd21, SavePath=./work/raw_dex/classes30.dex, DexSize=0x5d634
INFO:frida-dexdump:[+] DexMd5=9c519a9ca23b8c843959c0b761ff3dff, SavePath=./work/raw_dex/classes31.dex, DexSize=0x2b524
INFO:frida-dexdump:[+] DexMd5=cb40c7107cc3bca30ff03e236ecea9cf, SavePath=./work/raw_dex/classes32.dex, DexSize=0xfeac
INFO:frida-dexdump:[+] DexMd5=198255ad5c1b84959d85114d5ca879ad, SavePath=./work/raw_dex/classes33.dex, DexSize=0x124cc
INFO:frida-dexdump:[+] DexMd5=ae88554cf19ecaea2079e4880375d6ca, SavePath=./work/raw_dex/classes34.dex, DexSize=0x22964
INFO:frida-dexdump:[+] DexMd5=4d8db8d5b46c13abf0b5b2971fe44de2, SavePath=./work/raw_dex/classes35.dex, DexSize=0x12638
INFO:frida-dexdump:[+] DexMd5=3b87770b069461c1cd3c2ffa3b93db99, SavePath=./work/raw_dex/classes36.dex, DexSize=0x2ffc
INFO:frida-dexdump:[+] DexMd5=4d33839be9bafcb9f0856641d20de47f, SavePath=./work/raw_dex/classes37.dex, DexSize=0x655c
INFO:frida-dexdump:[+] DexMd5=37307f9265761a236d7444d6405bcf71, SavePath=./work/raw_dex/classes38.dex, DexSize=0x264
INFO:frida-dexdump:[+] DexMd5=e785555870cc3d0301cee34741bc7ee9, SavePath=./work/raw_dex/classes39.dex, DexSize=0x23c8
INFO:frida-dexdump:[+] DexMd5=1e29d1936a49ccf21a1c6975c33777b8, SavePath=./work/raw_dex/classes40.dex, DexSize=0x2ec8
INFO:frida-dexdump:[+] DexMd5=fa7e49bcd3b28de8440f9c7e80ce0e80, SavePath=./work/raw_dex/classes41.dex, DexSize=0x63bc4
INFO:frida-dexdump:[+] DexMd5=32122b7e7c550aac7ba2d98913c2bff1, SavePath=./work/raw_dex/classes42.dex, DexSize=0x17b0
INFO:frida-dexdump:[*] All done...
复现实验边界:这些命令、源码、哈希和解析记录只对应当前输入。换用另一份 APK 或另一轮内存转储时,必须重新生成完整哈希、文件数量与逐文件解析结果。
0x0D

下一篇:17 个能解析,为什么最终只选 7 个交给 JADX?

修复完成后,新的问题不是“能不能打开”,而是“哪些 DEX 真正属于有分析价值的集合”。17 个文件里有零类 DEX、单类 DEX、系统或公共依赖,也存在重复命名空间。直接把全部文件扔给 JADX,会让数量看起来更大,却不代表分析更准确。

AI自动化脱壳①:以前我不会 APK 脱壳,直到 AI 帮我导出 42 个运行时 DEX

AI 自动化脱壳 / 003恢复出 14,275 个 Java 文件后,真正该看哪一些?
0xSec笔记本 · AI × ANDROID · 自动化脱壳实验 02
隔离环境 · 原始转储保留 · 结果由本轮 TSV/JSON 确定性复算

转载声明:本文转载自原发布平台 (作者:0xSec笔记本), 原文标题《AI自动化脱壳②:42 个 DEX 已经 Dump 出来,为什么只有 5 个能打开?》, 查看原文。 版权归原作者及原发布平台所有,本站仅作收录与展示,未对正文内容作实质性修改; 若涉及侵权请联系本站处理。