逆向工程
逆向工程(又称逆向技术),是一种产品设计技术再现过程,即对一项目标产品进行逆向分析及研究,从而演绎并得出该产品的处理流程、组织结构、功能特性及技术规格等设计要素,以制作出功能相近,但又不完全一样的产品。逆向工程源于商业及军事领域中的硬件分析。其主要目的是在不能轻易获得必要的生产信息的情况下,直接从成品分析,推导出产品的设计原理。
逆向工程可能会被误认为是对知识产权的严重侵害,但是在实际应用上,反而可能会保护知识产权所有者。例如在集成电路领域,如果怀疑某公司侵犯知识产权,可以用逆向工程技术来寻找证据。
这里我们以安卓项目开始探索逆向工程之路
逆向工具
工欲善其身,必先利其器。
反编译代码的工具下载:
- dex2jar: 把dex文件转成jar文件下载地址:https://sourceforge.net/projects/dex2jar/files/
- jd-gui: 这个工具用于将jar文件转换成java代码下载地址:http://jd.benow.ca/
反编译资源的工具:
- APKTool: 本文重要工具,APK逆向工具,使用简单下载地址: http://ibotpeaches.github.io/Apktool/install/
这里简单介绍下大概流程,首先把后缀为.apk的文件改为.zip的一个压缩文件,方便解压。dex2jar和jd-gui配套使用,用于逆向代码部分,APKTool用于逆向res文件夹下的图片布局等部分。
新建一个简单的项目
新建一个项目,名字是 Androidrefirst,实现的逻辑是在输入框内填写 2019之后 点击按钮跳转到成功页面。
主要代码如下
1 | package com.example.androidrefirst; |
生成 apk安装包 app-release.apk
逆向 apk
解压apk得到 classes.dex 文件
需要用到的是dex2jar包里面的三个文件(当前是在windows环境下,Mac环境用对应的.sh文件):
d2j_invoke.bat
d2j-dex2jar.bat
lib
将这三个文件复制到一个空的文件夹内,将刚才.apk解压后的classes.dex文件也一起复制到这里
使用命令 d2j-dex2jar.bat classes.dex 得到 jar文件
使用 jd-gui.exe 打开jar文件看到代码
可以看到我们的代码
1 | package com.example.androidrefirst; |
对照着自己的手写的代码,已经差不离十了,对于想要代码思路的我们来说,到这里已经基本可以摸透他的逻辑。
反编译res资源部分
apktool下载后会有两个文件,一个.jar(例如apktool_2.3.3.jar 需要把名字改成apktool.jar) 一个apktool.bat 。
apktool d
同刚才一样在cmd命令下进入刚才文件夹(同样可以新建一个),连同我们刚才那个后缀为apk的安装包一起放入,输入如下命令
1 | apktool d app-release.apk # 此处app-release为apk名称 |
得到一个新的app-release(对应apk名称)文件夹
这个app-release文件夹下会得到若干文件,主要内容介绍如下:
- AndroidManifest.xml:描述文件
- res:资源文件
- smail:反编译出来的所有代码,语法与java不同,类似汇编,是Android虚拟机所使用的寄存器语言
到此我们想要的都有了。下一步就是实现我们想法的时候了。
修改原代码逻辑
我们只需要修改if后面的判断条件,设置为否即可if (!MainActivity.this.code.…),这样就成功绕过了条件约束。
接下来还有一部很重要那就是修改smali文件,找到MainActivity$1.smali这个文件用代码查看工具打开
找到这个if-eqz 修改成if-nez (nez对应为非,符号“!”),到这里要修改的部分都成功了,最后一步要做的就是重新打包了。当然对smali语法感兴趣的可以一起探讨学习。
重新打包
在apktool文件夹路径的cmd下输入:
1 | apktool b [文件夹] -o test2.apk #(test2为新apk名称,[文件夹]为对应的有修改需要打包的文件夹) |
至此,我们的目标apk文件已经生成,当然如果你想装到你自己手机上还需要重新签名一下。
重新签名
首先我们需要一个用于签名的.keystore文件,生成命令如下(这里我们假设生成的是demo.keystore)。
1 | keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore |
这里我们利用Java JDK提供的一个jarsigner进行签名,在刚才的cmd下继续操作,输入:
1 | jarsigner -verbose -keystore demo.keystore test2.apk demo.keystore |
以上。我们目的apk已经可以投入使用,如果需要更快更好的体验还需要进行一次字节对齐的操作(后续分析)。
参考: