smali修改实操:从改返回值到回编译重签名
逆向到最后绕不开改代码——去掉广告、绕过签名校验、改接口地址,都得改 smali。一、smali 是什么
smali 是 Dalvik 字节码的人类可读形式。apktool 反编译后,每个 .class 对应一个 .smali 文件。它类似汇编,但比汇编好读。
基本语法:
# 定义方法
.method public encrypt(Ljava/lang/String;)Ljava/lang/String;
.registers 3# 使用的寄存器数
# 寄存器:v0,v1,v2... 局部变量;p0,p1... 参数(this是p0)
const-string v0, "AES"# 把字符串"AES"加载到v0
invoke-static {v0}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;
move-result-object v1# 把返回值存到v1
return-object v1# 返回v1
.end method
二、常见修改场景
[*]去掉签名校验:找到校验方法,直接让它返回 true
[*]去掉广告:找到加载广告的代码,注释掉调用
[*]改接口地址:找到 API URL,const-string 改成你的
[*]绕过 root 检测:让检测方法返回 false
三、实际操作:让方法直接返回 true
原始代码:
.method public isVip()Z
.registers 2
# 一堆校验逻辑...
const/4 v0, 0x0
return v0
.end method
改成:
.method public isVip()Z
.registers 1
const/4 v0, 0x1
return v0
.end method
registers 减到 1(只需要一个寄存器),直接返回 1(true)。中间的校验逻辑全部删掉。
四、回编译和签名
# 回编译
apktool b output_dir -o modified.apk
# 对齐
zipalign -v 4 modified.apk aligned.apk
# 签名(用 debug keystore)
jarsigner -keystore debug.keystore -storepass android -keypass android aligned.apk androiddebugkey
# 或者用 apksigner(推荐)
apksigner sign --ks debug.keystore --ks-pass pass:android aligned.apk
五、踩坑经验
[*]改完 smali 一定检查寄存器数量够不够,不够会崩
[*]如果 App 有加固(壳),先脱壳再改 smali,否则你看到的 smali 是壳的
[*]修改后安装如果闪退,看 logcat 报什么错,一般是寄存器或类型不对
[*]别贪多,一次改一个方法,改完测一次,出问题好定位
https://www.metk.cn/img/posts/reverse_smali.jpg
smali 修改的核心:理解寄存器模型,能看懂 invoke/move-return 这几个指令,大部分修改就是改返回值或注释掉调用。看着像汇编其实逻辑很简单。 我这边环境是Mac,有些步骤要调整,回头补个差异说明。 收藏了,最近正好要搞这块,省了不少翻文档的时间。 我用的另一条路线,效果差不多,但工具链更轻一些,回头整理下发出来。 照着试了一下,第一遍没成功,发现是权限问题,建议楼主补充个提示。 感谢,正需要这个,之前找的资料都太老了。 同求后续,想知道绕过之后怎么稳定保持,重签名这块一直搞不定。 这个思路让我想到另一个场景,回头试试能不能套用。 同意楼主的判断,现在加固手段越来越多,纯手工成本太高了。 这个技术本身是中性工具,关键看用途,楼主的态度挺正的。