Android 反编译并增加自定义函数
今天我们来反编译java,并修改内部函数,大部分博客基本都没有详细的说法,今天实际操作一下。本文章只是以学习为出发点,若做触摸法律底线的事,作者概不负责。
Start
首先请上我们今天的主角,一个用Unity编译成功apk,以及 apktool.jar 工具
然后我们开始反编译,命令:
java -jar apktool.jar d test.apk
反编译后我们将得到一个目录,而我们源码都在Smali目录里面。
我们看看里面的源码是什么东西,我也算是第一次接触java的反编译。
… … … … … … … … … …
不知道怎么形容内心的 “草泥马”。不过幸好作者平时开发都是C#, 也接触过CLR中间语言,SO,在C#遍地 “抄” 的代码中,我看到了CLR的影子。
Smali 语法我就不过多的介绍了,不过需要注意的是当注册一个函数的时候,需要规定注册好寄存器,至于一个函数需要多少个寄存器,java我没太了解,有可能根据代码域的变量或者函数来决定。
下面我们尝试自定一个自己的函数,然后输出一段警告。
这是一个public 的函数,我们可以看到,它的locals会和其他函数不一样,这里应该就是寄存器的数量,也可能不是,若有大佬写java的,在博客地下留言告诉我这是啥玩意。
然后就是两个字符串的常量,我们可以看到java的字符串多是常量,不像CLR,或许这就是java某些原因会比C#要好的原因。
invoke-XXXX 这是调用某个函数, {参数}
XXX 有 static 静态 virtual 虚,direct 直接,
需要注意的是 private 标识的函数无法用 invoke-virtual 来调用!。
上面便是函数的调用。至于放哪儿,自便即可。
当我们改完后,我们把工程编译回去。
java -jar apktool.jar b test.apk
然后我们拿到目录下的dist的apk安装下。
安装不上,别急,用签名工具签名就可以了,怎么签名自己去看其他博客吧。
然后用logcat 去查看,我们的输出是一个警告
运行apk
成功了,但是有个问题就是,我们的修改是基于一个包的,若后面有多个包怎么办?一个一个改?答案肯定是否定的。
接下来,我们从apk拿出classes.dex文件(修改过的)
使用dex-tools 把它反编译成jar包。
接下来我们就可以把我们修改过的类copy进去未修改的jar包中,覆盖。(注意,相关的类都要copy过去,因为会混淆成xxxxx&1, xxxxx&2)
上面是提取出来的,为了方便,我是整个目录直接替换掉。
这就替换完了,我们对比下jar包,n是原始包,p是替换的包
应该是没问题了。
这个时候我们用修改过的jar替换unity导出的工程包中libs中对应的jar包,然后编译一下就好了,切记不可放在unity->assets->plugins->android->libs,这样是不行的,最终出来的包还是会被替换,至于这步怎么解决相信不用我说你也知道了。
我们把工程目录下的libs的对应jar包替换后,重新出包。
不过我们先用as看下源码
没问题,那么出包后,用as调试下。
完美,现在jar以及被修改了,这样就可以基于第三方包自定义自己的java包了。为了自定义jar包,作者也用了两天左右的时间去查相关文档,才发现这方面的知识很少,google也找到不多。