这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
前言
在开始之前先说说为什么我们要做反编译的工作。主要目的并不是为了破解别人的项目从中做非法的企图,而是抱着学习的态度了解别人在开发中如何具体实现某些功能点, 这才是我们去做反编译的真正目的。所以作为一名程序员我们是为了不断学习技术的心态去做反编译的事情,反过来做反编译同时也是更好的服务于应用的安全加密。
Apk文件组成
反编译我们最终想要的是Apk的源码,从Apk中获取源码前先知道它的文件结构从而知道具体从哪获取到源码资源。具体的Apk文件目录如下:
- META-INF:签名文件。
- res:资源文件,里面的 xml 格式文件在编译过程中由文本格式转化为二进制的 AXML 文件格式。
- AndroidManifest.xml:Android 配置文件,编译过程依然被转换为 AXML 格式。
- classes.dex:java 代码编译后产生的类似字节码的文件(dalvik 字节码)。
- resources.arsc:具有 id 值资源的索引表(asserts 文件夹中的资源不会生成索引)。
- 其他文件:可由开发者自己添加,诸如 assets 等,或者 lib(native so 代码)等目录。
Android程序是运行于Davlik VM,所以程序执行的是特定的dex格式的文件而非.class文件
Apk的java代码内容都在classe.dex中,所以对dex文件保护十分重要。
源码反编译
简单使用apktool,dex2jar,jd-gui反编译apk获取Java源码
apktool
使用apktool可以获取到Apk的res、smali、AndroidManifest等资源文件。
apktool.bat d (apk)
其中smali是什么呢,以前都没遇见过。
smali是Android的Dalvik虚拟机所使用的一种 dex 格式的中间语言。 好比C语言和汇编语言的编译与反编译,可以把 smali 理解为一种汇编语言。
打开smali文件我们也能大致看懂其中的一些逻辑内容。如果你知道如何对其进行修改,那么在修改之后可以将反编译的内容重新编译签名生成新的修改之后的apk。
关于smali的语法可以戳这里了解更多。
dex2jar和jd-gui
修改apk后缀改为rar或者zip,.apk -> .rar。解压缩之后拿出里面的classes dex文件。 使用dex2jar将dex转成jar包
dex2jar.bat classes.dex
成功之后再用jd-gui打开jar包就可以看到apk的java源码了。
以上就是简单的利用反编译工具的反编译过程,前提就是apk生成之前没有做任何加壳加固等安全加密的情况下。
SO文件反编译
可能Apk中有so文件,那就需要使用其他方法反编译获取源码。
我们可以使用IDA工具将so的代码逻辑反编译获取汇编代码,看到汇编指令就能够知道so文件代码具体所做的工作。即使汇编语言晦涩难理解,但汇编语言才是程序员最基本的语言啊。
加固Apk反编译
对于处理过的Apk使用简单反编译方法可能很难获取到源码信息,使用jd-gui打开classess dex转成的jar包可能获取不到java代码。
Apk被加固的方式有很多大致方案思路:把源Apk加密拆分处理,然后套一个外部壳Application做一些初始化操作。使用IDA给dvmDexFileOpenPartial函数下断点,
使用dump操作从内存中获取dex数据。不过一些加固有做反调式操作,对so文件进行混淆加密等,使得调试变得困难,这也是加固反编译的难点所在。