一条命令核对 app.asar 是否被篡改:REA ASAR 完整性校验完整指南
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
拿到一份来路不明的 Electron 安装包,怎么确认里面的app.asar没被动手脚?REA 的 ASAR 完整性校验会把包里每个文件的声明 SHA-256 与实际读到的字节逐条比对,全程纯静态、不执行任何应用代码,一条rea analyze就能出结论,快速、免费、离线可跑。
先判断这份包值不值得验
篡改app.asar的成本极低:ASAR 本质是「文件清单 + 拼接字节流」,攻击者改掉其中某个 JS 文件的几个字节就能注入逻辑,用户肉眼完全看不出。真正需要跑校验的是这几类场景:
- 从非官方渠道(网盘、第三方镜像)下载的安装包;
- 你维护的安装脚本里要锁定应用完整性、想拒绝任何字节级改动;
- 一份已解包再重打包过的
app.asar,想确认归档头部和文件偏移没被重写过。
如果包是从官方渠道、带签名校验下载的,跑一次留下基线即可,之后每次更新对照基线。
校验机制:只认「声明值 vs 实际值」
REA 不猜、不执行,只做三件确定性的事:
- 清单阶段抓声明值:ASAR 头部每个文件条目可携带
integrity字段(SHA256),REA 在扫描清单时逐条提取声明哈希,算法不是 SHA256 或格式不合法的直接记为无声明。 - 按声明范围读取再算哈希:打开任意文件前,先校验它的偏移和长度是否越界,再按字节范围流式读出并现算 SHA-256,最后与声明值比对;读出字节数和头部声明不一致也会被拦下。
- unpacked 伴生文件同样受检:标为
unpacked的原生插件字节存在<archive>.unpacked旁,REA 会把这些伴生字节也拿来和归档声明的完整性值对哈希,读取时防符号链接逃逸——unpacked只是存放方式,不是免检通行证。
任何一处对不上,结果里就会带出逻辑路径、声明值、计算值三项,供你定位。
三条命令跑完全量校验
第一步:装好 REA。按 安装说明 配置环境,之后用rea命令;也可以不全局安装,直接npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app.asar --json。
第二步:对 ASAR 包跑分析。把目标应用的app.asar(或解包后的目录)直接喂给通用analyze:
rea analyze /absolute/path/to/apps/app.asar --jsonrea analyze在没有指定--provider/--snapshot时,会自己对.asar和目录选中 JavaScript 应用静态分析工作流,返回应用图、Electron 边界摘要和完整性校验结果,全程不启动浏览器或 Electron 进程。想显式指定就用专用命令:
rea analyze-javascript-application /absolute/path/to/apps/app.asar --json第三步:保存并对比证据。完整 Evidence 可能达到数百 MB,落到文件里再投出摘要便于阅读和复用:
rea analyze-javascript-application /absolute/path/to/apps/app.asar --json > app-evidence.json之后可以用rea compare把「官方包」和「可疑包」两份结果并排比。
结果表格逐行这样读
拿到 JSON 后,主要看完整性相关字段。integrity_contradictions数组里每条记录都带contradiction_id、declared_sha256(声明值)、observed_sha256(实际算出值)、entry_kind和unpacked(是否为伴生条目):
| 输出状态 | 含义 | 对应动作 |
|---|---|---|
integrity_contradictions为空,全部文件通过 | 包体与声明的完整性元数据相符,无篡改证据 | 存档本次 SHA-256 作为基线 |
出现一条或多条integrity_contradictions | 声明哈希与实际字节矛盾,该文件被改过 | 用逻辑路径定位,回官方渠道重新获取安装包 |
某 unpacked 条目hash_status: unavailable | 声明了伴生文件但字节缺失 | 缺失字节记为 unknown 而非「已验证」,补齐文件再验 |
当某个文件声明值与实际值不符时,记录里会并列给出声明 SHA-256 与计算 SHA-256,让你能直接判断是清单没动内容被改,还是伴生文件被调包。
三个容易误判的边界
默认策略是 fail-closed:发现任何不一致立即返回失败。如果你希望「记录不一致但继续分析其余文件」,在请求里显式选record-and-continue(CLI 用--integrity-policy record-and-continue),已校验通过的文件仍可继续,篡改记录不丢失,只是应用图覆盖会被标为 partial,被篡改的路径写进 limitations:
rea analyze-javascript-application /absolute/path/to/apps/app.asar --integrity-policy record-and-continue --json- unpacked 哈希失败不一定是攻击。很多打包工具在写完归档头部后才签名或剥离
.asar.unpacked里的原生二进制,导致声明哈希与最终字节对不上;Electron 运行时本身不核对伴生文件。REA 会在结果里标明这个成因并提示用record-and-continue重跑,而不是默默放过。 - 伴生文件缺失不等于通过。缺了
.asar.unpacked里声明的字节,REA 会继续分析包内嵌入的 JavaScript,但把缺失的原生/资源字节如实记为 unknown,既不假装通过、也不假装文件不存在。 - 整个流程不执行代码。重建路径不用
eval、Function或 DOM,也不跑应用引导逻辑,对可疑样本安全,所以可以直接在隔离环境里跑未知来源的包。
想深入实现,看这四个文件
- src/artifacts/AsarArtifactReader.ts:ASAR 读取与哈希校验核心,处理清单提取、偏移越界判断与二次替换防护;
- src/artifacts/AsarEntryStream.ts:流式读取时核对字节数与头部声明,读超或读短都报 integrity 失败;
- src/artifacts/inventory/scanCanonical.ts:清单扫描阶段记录完整性矛盾,产出
integrity_contradictions; - docs/mcp-contracts.md:完整性处理契约,
record-and-continue的行为与 unpacked 缺失的处理都写在这一节。
从一份rea analyze ... --json的输出开始,先确认integrity_contradictions是否为空,再用rea compare把你的基线和当前包并排,就能把「这包到底动没动过」这个问题落到可归档的证据上。
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考