Smali代码补丁入门:不反编译直接改APK逻辑
有时候不想反编译重打包 APK,只想改一小处逻辑。Smali 代码补丁是比 apktool recompile 更轻量的方案。一、Smali 是什么
APK 里的 classes.dex 反编译后得到 Smali 代码——一种类似汇编的中间语言。每行 Smali 对应一条 Dalvik 字节码。改 Smai 就是改字节码,不需要 Java 源码。
二、最小补丁流程
[*]用 apktool d app.apk 反编译,得到 smali/ 目录
[*]在 smali/ 里找到目标类的 .smali 文件
[*]直接编辑 Smali 代码改逻辑
[*]apktool b 重新打包
[*]签名后安装
三、常见补丁模式
1. 绕过条件检查
把 if-eqz 改成 if-nez,或者反过来。比如验证逻辑:
# 原始
if-eqz v0, :cond_fail
# 改成
if-nez v0, :cond_fail
一个字之差,验证从"相等才失败"变成"不等才失败",直接跳过验证。
2. 强制返回 true
把方法体改成直接返回 true:
.method public isVip()Z
const/4 v0, 0x1
return v0
.end method
不管实际逻辑是什么,isVip 永远返回 true。
3. 替换字符串常量
直接在 Smali 里改字符串。比如把 "trial" 改成 "pro":
const-string v0, "trial"
# 改成
const-string v0, "pro"
注意新字符串长度不能超过原字符串(UTF-8 字节数),否则要改 const-string 指令为 const-string/jumbo。
四、调试技巧
[*]在关键方法入口插 log:const-string v0, "ENTER: xxx" 然后 invoke-static 调 Log.i
[*]用 Frida 动态测试补丁效果,再改 Smali 做静态固化
[*]多dex应用注意:可能有 classes2.dex、classes3.dex,目标类可能在任一 dex 里
五、注意事项
[*]改完要重新签名,原签名会失效
[*]部分 App 有签名校验,需要在 Smali 里禁用 PackageManager 的签名获取
[*]加固应用(360 加固、腾讯乐固)的 Smali 是脱壳后才能改的,加固壳把真实 dex 隐藏了
https://www.metk.cn/img/posts/smali_patch.jpg 我只是路过,不发表意见 难得看到这么具体的分析,比泛泛而谈强多了。 静态分析搞不定的部分,动态跑一遍基本就清楚了。 遇到卡住的地方,换个思路往往比死磕更快。 这类校验现在很多是服务端下发的,光改本地没用。 签名校验放在 Native 层确实麻烦不少,但也不是无解。 这类技术更新的频率很高,老教程参考价值有限。 这类壳本质就是给分析加成本,真下定决心还是能扒出来。 之前分析过类似的,混淆还原完逻辑其实不复杂。