原文参考链接:https://crifan.github.io/android_app_security_crack/website/
上述网址讲解的非常详细,这里只粗略的整理用到的比较多的工具以及一些安卓逆向工程的知识点。
全文中提到的各种工具都可以csdn下载https://download.csdn.net/download/wozaipermanent/11958306在中下载得到,但是现在csdn下载不能自己设置积分了,积分会动态改变,所以下文对于每一种工具都提供了一个下载网址,或者自行搜索下载。
APK = android Application PacKage
内容入口 | 含义解释 |
---|---|
AndroidManifest.xml | 二进制xml文件,提供设备运行应用程序所需的各种信息 |
classes.dex | 以dex格式编译的应用程序代码 |
resources.arsc | 包含预编译应用程序资源的二进制XML文件 |
res/ | 此文件夹中包含未编译到resources.arsc文件中的资源 |
assets/ | 此文件夹包含应用程序的原始资源,由AssetManager提供对这些资产文件的访问 |
META-INF/ | 它包含MANIFEST.MF文件,该文件存储有关JAR内容的元数据。APK签名也存储在此文件夹中 |
lib/ | 此文件夹包含已编译的代码,例如本地代码库 |
dex = Dalvik Executable format
dex文件:逻辑类似于java
的class
文件。
注:
最常用的做法是,用ProGuard去实现代码混淆。
dump.txt
:说明APK中所有类文件的内部结构mapping.txt
:提供原始与混淆过的类、方法和字段名称之间的转换和对应关系seeds.txt
:列出未进行混淆的类和成员usage.txt
:列出从APK移除的代码市面上有很多公司和厂商提供免费或收费的加固方案。
使用反编译工具只能看到混淆之后的代码结构,看不到混淆之前的原始代码。
不是所有加固的安卓apk都可以成功脱壳的。
总结:
没有加固的:直接用jadx即可导出源码
部分加密不强的:可以脱壳
腾讯乐固,新一代的360加固保等:没法脱壳(或许未来可以使用art+dex2oat相关机制去破解)
通过反编译工具后,从dex或jar包的目录结构,以及相关的文件(比如AndroidManifest.xml)的内容,往往可以看出是哪家的加密方案。
腾讯乐固legu加密加壳后的apk,用apktool反编译后,得到的jar包目录结构是:
com.tencent.bugly
com.tencent.bugly.legu
crashreport
proguard
com.tencent.StubShell
TxAppEntry
截图举例:
另外反编译出的AndroidManifest.xml内容:
<application android:allowBackup="true" android:icon="@drawable/app_logo" android:label="@string/app_name" android:name="com.tencent.StubShell.TxAppEntry" android:supportsRtl="true" android:theme="@style/AppTheme">
<meta-data android:name="TxAppEntry" android:value="com.huili.readingclub.MyApplication"/>
中有:
android:name="com.tencent.StubShell.TxAppEntry"
也是典型的腾讯乐固的内容。
360加固后的apk经过dex2jar反编译后的目录结构是:
com.qihoo.util
com.qihoo360.replugin
com.stub
这种结构就说明是360加固保加固的。
安卓中有个AndroidManifest.xml文件,是保存了相关项目的类,资源等配置信息。
而对于apk文件:
apktool下载:apktool下载官网
命令apktool d -f inputFile.apk -o outputFile
注:即使apk加固了,也可以用apktool反编译
比如,网上随便找了一个机器人塔防的apk(robotDefense.apk),用apktool对其进行反编译,得到AndroidManifest.xml文件信息如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.magicwach.rdefense">
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application android:configChanges="keyboardHidden|orientation" android:icon="@drawable/icon" android:label="@string/app_name" android:launchMode="singleTask" android:multiprocess="false" android:sharedUserId="com.magicwach.rdefense_free" android:stateNotNeeded="true" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<activity android:label="@string/app_name" android:name=".TitleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
<activity android:label="@string/app_name" android:name=".GameActivity"/>
<activity android:name=".RewardActivity"/>
<activity android:name=".AchievementActivity"/>
<activity android:name=".CreditsActivity"/>
<activity android:name=".LevelSelectActivity"/>
<activity android:name=".MixerSelectActivity"/>
<activity android:name=".DebugActivity"/>
<activity android:name=".OptionsActivity"/>
<receiver android:name="com.xxx.yyy.MyBoolService">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
intent-filter>
receiver>
<receiver android:name="com.xxx.yyy.MyAlarmReceiver">
<intent-filter>
<action android:name="com.lz.myservicestart"/>
intent-filter>
receiver>
<service android:enabled="true" android:name="com.xxx.yyy.MyService"/>
<receiver android:name="com.xxx.yyy.NetWorkReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
intent-filter>
receiver>
<receiver android:name="com.xxx.yyy.CustomBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
intent-filter>
receiver>
application>
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
manifest>
从xml文件中可以得到permission feature、component feature等特征信息。
前提: apk没有被加固。用jadx等工具打开看到的进而导出的代码和目录结构都是qihoo奇虎、360、tencent腾讯乐固legu等字样的就说明是被加固了的,这样导出的代码也只是加固后的代码,不是app自已业务逻辑的java代码。
思路: 用jadx等工具,直接从apk转换出java源代码
准备: 下载jadx,从首页下载最新版本,如jadx-1.0.0.zip,解压;或使用如下安装命令:
git clone https://github.com/skylot/jadx.git
cd jadx
./gradlew dist
详细步骤:
用jadx-gui打开没有加固的apk文件:
可以看到源码,想要导出全部源码,则可以去文件->全部保存
或文件->另存为Gradle项目
即可导出全部代码。
前提: apk虽然被加固,但(后续)用FDex2等工具能够导出我们要的dex文件
思路:
详细步骤:
准备:
Android 5.1.1,夜神模拟器已自带root
详细步骤:
激活FDex2,Xposed模块列表会更新,重启之后生效。
此处内部FDex2已经去导出app的所有文件对应的目录
没有看到我们要导出的dex文件:
思路:已经从前面的app导出dex文件,然后用dex2jar等工具从dex转换出jar文件。
准备: 从下载网址:官网:https://tools.kali.org/reverse-engineering/dex2jar,下载最新版本的dex2jar并解压
用法:
从dex中转换出jar:
d2j-dex2jar.bat -f classes.dex
;Linux:d2j-dex2jar.sh -f classes.dex
从apk中转换出jar:
d2j-dex2jar.bat -f test.apk
;Linux:d2j-dex2jar.sh -f test.apk
说明和提示:
选择合适的反编译器,如jadx或JD-GUI等,打开上一步从dex转换得到的jar文件。
jadx网址: https://github.com/skylot/jadx
详见 4.3 反编译器内容
下面整理关于从运行中的安卓app导出dex文件的一些hook工具。
利用FDex2等工具,从运行的app导出dex文件时,看到很多文件名都类似于:com.huili.readingclub8825612.dex
这些hook工具生成的dex代码中,对应的命名规则应该是:
packageName + fileSize.dex
所以上面的文件名对应:
packageName
:com.huili.readingclub
fileSize
:8825612
,即dex文件本身的大小用来从运行中的安卓app中导出dex文件的工具。下载地址:百度网盘 提取码:3e3t。
用来从运行中的安卓app中导出dex文件的工具。下载地址:https://github.com/WrBug/dumpDex/releases
$ adb push F:\drizzleDumper /data/local/tmp
$ chmod 755 drizzleDumper
$ ./drizzleDumper xyz.sysorem.crakme
下载网址:官网:https://tools.kali.org/reverse-engineering/dex2jar、github: https://github.com/pxb1988/dex2jar
功能: 用于处理安卓的dex文件和java的class文件的一系列的工具
用法:
从dex中转换出jar:
d2j-dex2jar.bat -f classes.dex
;Linux:d2j-dex2jar.sh -f classes.dex
从apk中转换出jar:
d2j-dex2jar.bat -f test.apk
;Linux:d2j-dex2jar.sh -f test.apk
网址: https://github.com/Storyyeller/enjarify
功能:把安卓的Dalvik字节码转化为Java字节码,和dex2jar类似
特点:google官方开源、用python3编写、比dex2jar更新且更好
用法:
python -o -m enjarify.main yourapp.apk
enjarify yourapp.apk
enjarify classes2.dex
enjarify yourapp.apk -o yourapp.jar
dex2jar:
Enjarify
下载地址: https://sourceforge.net/projects/dedexer/files/
作用: 把dex转换为类似于汇编的格式,从dex文件创建类似于Jasmin的源代码
用法:
java -jar ddx.jar -o -D -d <destination directory> <source>
java -jar ddx1.5.jar -o -D -d c:\dex\gen c:\dex\classes.dex
此处主要讨论java反编译器,更主要的是和安卓相关的java的反编译器,其中尤其涉及到dex转出jar包后的,如何从jar包反编译出java源代码的相关反编译器。
作用: 从jar包转换出java源代码,用于在GUI图形界面工具中查看java代码;命令行工具中直接导出整个项目所有的java代码文件
常用反编译器:
apktool:一个用来逆向工程第三方的二进制的安卓app工具。
输入:apk文件
输出:各种安卓资源文件
安装: https://ibotpeaches.github.io/Apktool/install/
用法:apktool d -f inputFile.apk -o outputFile
利用上述命令可以得到项目目录文件:
用apktool转换apk得到smali源码是有前提的:apk没有加固。加固了的apk反编译后只能看到被加固的目录结构,看不到app业务逻辑代码和结构,如下图:
下载: https://code.google.com/archive/p/android4me/downloads
作用: 将安卓二进制的AXML转换成可读的xml文件
提示: 最佳更新都是2008年,看起来是很老旧的工具
用法:
java -jar AXMLPrinter2.jar xxx.xml output.xml
java -jar AXMLPrinter2.jar AndroidManifest.xml > main.xml
这部分详见文档开头第一个参考链接,下面只罗列一些工具名称
下面介绍的工具详见文档开头第一个参考链接,下面只罗列这些工具的名称
这部分详见文档开头第一个参考链接
Xposed框架是用于安装相关插件FDex2,配合破解安卓,导出运行时app的dex文件。
主页: http://www.cydiasubstrate.com
功能: 和Xposed类似的框架,用来安装各种插件,实现各种功能,比如可以安装绕过ssl检测的插件,用来破解ssl pinning
特点: hook底层方法非常方便,对so中的方法hook操作非常便捷
官网:https://www.frida.re
简介:
使用夜神安卓模拟器,来配合破解安卓:
想要把安卓中(导出的dex等)文件拷贝(导)出来,一般需要借助于好用的安卓浏览器。
ES文件浏览器: 功能很强,比较流行的安卓的文件浏览器。
特点:
应用简介:
MT管理器是⼀款强⼤的⽂件管理⼯具和APK逆向修改神器。
主要功能: