最近在小密圈中,有同学咨询到如何快速的将 java 文件转化成 smali 文件,因为我们知道在反编译之后都是 smali 代码,如果我们想进行代码插入,需要将 java 代码弄成 smali 代码,然后放进去,但是在这个过程中,比较麻烦,一般都是新建一个 Android 工程,然后编写需要插入的功能代码,然后在反编译得到 smali 代码。直接复制过去即可。
而在这个过程中,发现操作有点繁琐,比如我只想插入两个类,结果还得搞一个工程,自己纯手写 smali 代码也是不理智的,所以本文就来开发一款直接将 java 文件转化成 smali 代码的工具,主要原理思路也很简单:
这里可以看到,其实没什么难度这个工具,但是对于后续操作是必须的。其中 javac 命令是 java 环境的,所有这个工具是必须依赖于 java 虚拟机环境的。dx 命令其实是 Android SDK 自带的工具,但是为了方便,这里把 dx 命令的核心 jar 拷贝过来,直接运行 dx.jar 即可。baksmali 工具是开源的,直接将 dex 文件转化成 smali 文件的。
上面说了大致的步骤,但是在每一步有一些问题需要解决,下面就来一一分析:
第一个问题:javac 编译 java 文件的时候,有可能依赖于第三方 jar 包,而这里最为基础的就是系统包 android.jar,所以这个必须可少,又因为可能有多个 java 文件,每个 java 文件之间会相互引用,为了避免编译错误,所以直接一次性编译所有的 java 文件,命令大致如下:javac -classpath android.jar \java\*.java 这个就是表示依赖 android.jar 包,来编译 java 目录下所有的 java 文件了。
所以我们可以把需要编译的 java 文件都放在一个指定目录下,然后使用这个命令编译出 class 文件即可。但是还需要注意一个问题,就是编译出来的 class 文件必须要在指定包名对应的目录下,不然后面使用 dx 命令编译会出问题,所以这里还需要解读每个 java 文件获取其对应的包名,然后根据包名新建对应的文件目录,最后再把对应的 class 文件拷贝过去即可。
第二个问题:dx 命令转化 dex 文件的时候,因为我们直接引用了 dx.jar 文件的,而 dx 命令支持多个 class 文件编译成 dex 文件的,所以命令如下:java -jar dx.jar --dex --output=D:\classes.dex classes 这个表示编译出的 dex 文件保存在 D 盘的 classes.dex,然后需要编译的所有 class 文件放在 classes 目录下。
第三个问题:baksmali 命令转化 smali 文件,因为直接引用 baksmali.jar 文件的,所以命令很简单如下:java -jar baksmali.jar smalidir D:\classes.dex 这个就是把 D 盘的 classes.dex 文件反编译成 smali 文件放在 smalidir 目录中。
解决了这三个问题,那么工具代码就比较简单了,我们需要引用 android.jar,dx.jar,baksmali.jar,可以把这三个 jar 工具包放在工具的 lib 目录下,然后所有的 java 源码保存在 java 目录下。下面来看一下大致代码实现:
第一步:编译 java 文件,然后进行拷贝
第二步:将 class 文件变成 dex 文件
第三步:将 dex 文件变成 smali 文件
工具真的非常简单,就是这三步即可,然后我们把工具打包成 java2smali.jar 放到指定目录下:
然后查看运行结果:
这个是对应的 class 文件目录结构,必须是其包名,而转化之后的 smali 目录结构也是如此:
这样我们就很轻松的获取到 Utils.java 对应的 smali 代码了,然后直接把这个 smali 代码拷贝到需要插入代码的 app 中即可,注意这里拷贝过去一定要包含包名目录,这里已经生成好了,所以直接从 smali 这级目录拷贝即可。
工具源码下载地址: https://github.com/fourbrother/java2smali
到这里我们的工具就开发完成了,是不是很简单,但是对于我们后面再进行插桩代码就很简单了,还记得之前我们使用静态方式破解 app 的时候,需要插入日志信息,那个时候我们需要新加几个类信息,当时的操作还是挺麻烦的,现在有了这个工具就非常简单了。
更多内容: 点击这里
关注 微信 公众号,最新技术干货实时推送
来源: http://blog.csdn.net/jiangwei0910410003/article/details/78251427