有时候我们会被系统层诡异的Bug绊翻了车,不得已的情况下,需要更改Android代码。有些类我们能拿到源码,一切好说,但更多情况下,是引擎内或SDK中的jar文件,我们无法获得源码。面对这种情况,我的思路是:
- 解开Apk文件
- 找到对应到.class文件
- 定位更改代码位置
- 更改smali文件或代码
- 编回Apk
- 签名文件
流程中规中矩,具体操作如下:
ApkTool解包
首先在ApkTool的官网上下载安装工具,地址为https://ibotpeaches.github.io/Apktool/。安装完成后运行命令:
apktool d xxx.apk
运行后,会在apk的同级目录创建名称相同的文件夹,里面有解包之后的文件。目录结构如下:
其中smali为对应的可更改文件,build/apk/classes.dex为所有的代码文件。
dex2jar转换代码
由于smali代码没有可读性,我们需要将dex文件转换成jar文件。在官网https://sourceforge.net/projects/dex2jar/上下载工具,解压后,将上面提到的classes.dex复制到dex2jar的目录下,进入到这个路径下,运行命令行:
d2j-dex2jar.bat classes.dex
会生成名为calsses-dex2jar.jar的文件。
jd-gui分析代码
在jd-gui的官网http://jd.benow.ca/下载这个工具,双击运行后,将刚刚生成的jar文件拖动进去,即可看到java文件。
在分析过代码之后,我们希望更改内容或者输出日志,就需要找到smali文件夹中的对应文件。
更改smali
手动改smali就是硬功夫了,大家可以在网上搜搜smali的语法,然后直接去改文件。如果做过破解相信大家很熟悉这种手改汇编的痛苦。这里就不展开吐槽了。举个小栗子:
Log.e("FSY",obj.toString());
这行代码转到smali代码,就是下面这一坨:
invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;
move-result-object v1
const-string v2, "FSY"
invoke-static {v2, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
具体语法可以参考这篇文章http://blog.csdn.net/wdaming1986/article/details/8299996以及它后面的引用链接。
如果你实在想直接改Java代码,可以创建一个Java工程,把jar包扔进去,改了代码之后,再把对应的smali文件检出来。理论上是可行,不过我不建议尝试,因为通常都会缺少依赖项编译失败。
编译回Apk
改过smali文件之后,运行apktool的命令可以把包打回去
apktool b path/to/unzip/file -o songyangApp.apk
运行之后,就可以生成新包了。
签名
最后如果希望包可以运行还需要重新签名。运行命令
jarsigner -verbose -keystore yourKey.keystore -storepass yourPassword path/to/apk /path/to/keystore/file
即可完成签名。
总结
如果看了上面的这套复杂的流程,你还是要坚持这样查问题,那你可能和我一样走投无路,希望上面的文字对你有帮助,祝你好运。
关注我的微信公众号,获取更多优质内容