ARTICLE DETAIL

资讯详情

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

apk-reverse重打包与签名避坑清单:10个最常见安装失败及解法

apk-reverse重打包与签名避坑清单:10个最常见安装失败及解法 apk-reverse重打包与签名避坑清单10个最常见安装失败及解法【免费下载链接】apk-reverseSuitable for Android APK reverse engineering analysis项目地址: https://gitcode.com/gh_mirrors/ap/apk-reverse做 Android APK 逆向的人都遇到过这种绝望补丁明明打对了重打包、重签名之后却怎么都装不上甚至装上了也是坏的。这篇文章基于apk-reverse项目一个面向 Android APK 逆向工程的 Agent 技能库dex 外科式修补、重打包、重签名、运行时与服务器行为分析中记录的真实踩坑案例整理出重打包 重签名后 10 个最常见的安装失败现象每条都给出根本原因和快速解法帮你把构建一次装到位。所有案例均可在 pitfalls.md 与 repack-and-sign.md 中查到原始记录。先看清流程重打包与重签名的正确姿势装失败大多不是因为改错了代码而是重建和签名环节破坏了 Android 对 APK 的硬性要求。正确顺序只有五步外科式修补dex只改目标方法/字节尽量不动其他条目重打包保留各条目的压缩方式只删签名产物MANIFEST.MF、*.SF、*.RSA、*.DSA、*.EC绝不删整个META-INF/对齐resources.arsc与lib/*.so必须未压缩STORED且 4 字节对齐签名用apksigner打 v1v2v3不用jarsigner安装并验证不只是装上还要看版本真的变了、界面真的对了repack.py 已把第 2~4 步全部实现写归档时直接对齐签名用 apksigner新手可以直接用它替代手工流程。坑 1安装报[-124]提示 resources.arsc 对齐问题症状Android 11 / targetSdk 30 上必现Failure [-124: ...requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary]原因一句话里藏了两个独立要求——resources.arsc必须STORED不压缩且它的数据偏移量必须能被 4 整除。用 Pythonzipfile之类重打包时压缩方式满足了偏移量却完全不可控。解法不要用先压好再事后 zipalign的偷懒路线直接写的时候就对齐repack.py 自己输出 local header 并填充对齐。写完再读回档案逐条验证compress_type 0且offset % 4 0。详见 pitfalls.md P38。坑 2用 jarsigner 签名后对齐被悄悄破坏症状构建上一分钟还能装换成jarsigner签完之后突然[-124]。原因jarsigner在写入 v1 JAR 签名时会重压缩整个档案作为副作用把第 1 条的对齐全部打乱——而且jarsigner -verify还报成功看起来一切正常。解法签名一律用apksignerv1v2v3它只在末尾追加签名块、不动 zip 布局。apksigner不可用时zipalign -c -v 4留作独立检查。规则原文见 repack-and-sign.md 第 7 条。坑 3apksigner verify 显示 v1/v2 为 false别急着重签症状明明显式启用了 v1v2v3验证输出却是Verified using v1 scheme (JAR signing): false Verified using v2 scheme: false Verified using v3 scheme: true原因apksigner verify会按 APK 自己的 minSdkVersion 决定检查哪些方案。minSdk 24时它按设计把 v1/v2 报成false——签名其实真实存在META-INF/*.SF就在包里这不是失败。解法永远带显式 SDK 区间再验证apksigner verify --print-certs --verbose --min-sdk-version 21 --max-sdk-version 34 apk只看这次运行的结果。千万别拿默认参数的输出来判断构建。详见 pitfalls.md P13。坑 4删掉整个 META-INF/ 目录应用启动即崩症状APK 装得上一启动就闪退日志是IllegalStateException: Module with the Main dispatcher is missing. Add dependency providing the Main dispatcher, e.g. kotlinx-coroutines-android原因为了清干净再签名删掉整个META-INF/却连里面的ServiceLoader 注册文件META-INF/services/*一起删了——Android 运行时真的会读它们。报错指名 Kotlin 协程让人误以为是 dex 出了问题排查一两个小时全白费。解法只删META-INF/顶层的签名产物MANIFEST.MF和.SF/.RSA/.DSA/.EC后缀文件services/、androidx/等子目录全部保留。repack.py 内置了这个判断逻辑。验证方式新包与原始包的META-INF/services/*数量必须一致。完整案例见 pitfalls.md P1。坑 5dex 头两个校验字段顺序错了 → Bad checksum 莫名类找不到症状改完 dex 重打包启动失败日志里先出现Failure to verify dex file ...: Bad checksum (computed, expected) ClassNotFoundException: Didnt find class Application 类原因每个 dex 头部有两个覆盖整个文件的完整性字段且必须按固定顺序重算先算bytes 12..32 sha1(data[32:])signature再算bytes 8..12 adler32(data[12:])checksum因为它覆盖 signature。顺序反了头部就永远校验不过。更阴险的是 Android 会回退到解释执行进程照样起来只是类解析随机失败——症状指向APK 结构坏了而不是两个字段过期。另外日志里真实值显示在 expected 位读起来是反的容易看错数字。解法动了 dex 就必须重算这两个字段并断言结果。dexutil.py 提供fix_dex_header()顺序正确verify_dex_header()dex_patch_bytes.py 写入前自动执行并拒绝不通过自检的文件。原理见 byte-level-patching.md。坑 6等长字符串补丁打乱了 dex 的排序要求症状把 dex 里一个字符串换成等长的新值比如改接口路径校验和、签名全部通过baksmali也能正常解析——但运行时整个 dex 被拒绝Application 类直接ClassNotFoundException。原因dex 要求string_ids表有序。等长替换虽然保住了偏移量但新字符串可能在排序中越过了相邻项加载器因此拒绝整个 dex。真实案例/app/adverts换成/app/noadver越界被拒换成/app/blocked就通过。解法替换值必须落在原字符串前后邻居构成的区间内。dex_strpatch.py 会查邻居并拒绝越界替换。想改成长度不同的值那根本不是字节补丁的活了应走方法重写dex-patching.md。详见 pitfalls.md P2。坑 7只报数字错误码如[-99]APK 其实没毛病症状adb: failed to install app.apk: Failure [-99]没有INSTALL_FAILED_*这样的符号常量可查但同一个 APK 用设备自带文件管理器装得好好的换台设备也正常。原因部分厂商 ROM 会把adb install路由到自己的安全中心/安装拦截服务真正拒绝你的不是 APK而是设备上的拦截进程。设备日志会暴露真凶例如...InterceptManager: XXX_ADB_INSTALL_CANCEL ... packageName包名。解法识别特征——纯数字错误码 无符号常量 UI 路径可装。然后走 root 的pm install绕过 adb 安装路径不要回头重建 APK 或删权限凑安装。详见 pitfalls.md P39 与 repack-and-sign.md 厂商拦截一节。坑 8安装成功了跑的还是旧版本症状安装命令返回Success启动也没问题——但截图里 UI 一点没变多轮测量全是无效结果。原因很多 ROM 的安装器会插一层确认窗口密码、账号确认。安装命令返回的是请求成功真正的安装卡在没人点的确认框上应用停留在旧版本。这是本项目记录中代价最高的失败因为成功信号是真的只是回答了另一个问题。解法两条都做安装后证明制品真的变了对比dumpsys package pkg的versionName/lastUpdateTime或对设备上的 APK 做哈希比对版本没变就中止实验而不是继续测量安装后检查前台窗口dumpsys activity activities | grep -m1 ResumedActivity如果不是你的包常见是厂商安装器还占着屏幕先am force-stop那个安装器再重截屏完整案例见 pitfalls.md P18 与 P40coldstart.py 会自动做前台检查。坑 9重装后打不开数据库——数据目录 uid 不匹配症状重装尤其升级/覆盖安装后应用崩在数据库初始化路径Cannot open database ... doesnt exist但目录明明在。原因重新安装后应用 uid 递增而保留下来的/data/user/0/pkg目录还是旧 uid 所有新进程读不了。从旧备份恢复数据也会触发这个问题。解法从dumpsys package pkg | grep userId查到新 uid然后chown -R uid:uid /data/user/0/pkgrestorecon。备份恢复时优先用cp -f覆盖现有文件保留属主不要删掉再解压。详见 repack-and-sign.md 安装后风险一节。顺带一个进阶建议全程使用同一个 keystore迭代配合pm install -r覆盖安装能保住登录态——测试需要鉴权的功能时特别有用。坑 10应用一切正常但所有签名请求都失败症状重建的 APK 装上、启动、界面全正常logcat一条错误没有——但所有依赖 API 的页面都是通用网络错误请求参数sign/_p算出来是-1、空或 null。原因这不是服务器检查签名而是客户端把自己的 APK 签名证书当密钥材料用读PackageInfo.signatures[0]喂给 native 的 HMAC/DES 例程生成请求签名。你重签后证书变了派生密钥就变了服务端自然拒绝一切。构建完全合法、补丁完全正确最容易被误判成此应用无法客户端补丁。解法四步重打包前先花 15 分钟排查在反编译源码里搜toCharsString()、getPackageInfo(..., 64)、signatures[0]若值流进了带 HMAC/AES/DES 的 native 方法本坑适用从运行中的设备上读真实值sig_probe.py 的--live模式离线提取只作交叉核对——signatures[0].toByteArray()在现代 Android 上是证书链里单个 DER 证书不等于META-INF/*.RSA文件的整个内容实测有 777 vs 1199 字节的差异在每个读取点硬编码原始证书值然后断言剩余读取点数量为 0差分证明同一启动请求对比原版与重签版的签名参数形状-1/空说明密钥还是错的完整处理见 signature-derived-keys.md 与 pitfalls.md P27。动手前的 3 分钟自检清单把上面 10 个坑压缩成三条习惯覆盖其中 80% 的失败#习惯防住哪些坑1先跑环境体检python skills/apk-reverse/scripts/doctor.py --json确认 zipalign/apksigner 真的可用工具缺失导致的误判2建一次零修改对照组同一条流水线、零补丁。对照组也失败 → 是流水线/设备的问题不是你的补丁坑 7、坑 9 及一切环境误判3装完先验证制品真的变了版本号/哈希再看行为坑 8doctor.py 会逐项报告能力闭包缺什么、装什么、大概多久并允许自己报 BLOCKED只有 JVM 没有 apksigner 的机器无法重签名它直接说而不是靠有 JVM推断能签名。工具链细节见 toolchain.md。延伸阅读项目内的完整资料SKILL.md —— 主流程与症状索引表每条症状对应该先读哪个文件repack-and-sign.md —— 重打包 7 条规则、两条签名路线、安装覆盖矩阵pitfalls.md —— 40 条失败目录症状 → 根因 → 为什么看不见 → 该怎么做dex-patching.md / byte-level-patching.md —— 选对补丁手法减少进入重打包环节的风险verification.md —— 装上了不等于做完了的六项完成标准 最后记住项目的一条铁律能装不是能用。签名校验只证明文件格式合法不证明应用工作正常——装上、启动、操作你改过的那个功能、亲眼看到结果才算闭环。【免费下载链接】apk-reverseSuitable for Android APK reverse engineering analysis项目地址: https://gitcode.com/gh_mirrors/ap/apk-reverse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表