安卓应用(APK)逆向工程

看一看 6个月前 admin
12 0
广告也精彩 广告也精彩

原文参考链接:

上述网址讲解的非常详细,这里只粗略的整理用到的比较多的工具以及一些安卓逆向工程的知识点。

全文中提到的各种工具都可以csdn下载在中下载得到,但是现在csdn下载不能自己设置积分了,积分会动态改变,所以下文对于每一种工具都提供了一个下载网址,或者自行搜索下载。

1 APK文件 1.1 APK内容结构 内容入口含义解释

AndroidManifest.xml

二进制xml文件,提供设备运行应用程序所需的各种信息

classes.dex

以dex格式编译的应用程序代码

resources.arsc

包含预编译应用程序资源的二进制XML文件

res/

此文件夹中包含未编译到resources.arsc文件中的资源

assets/

此文件夹包含应用程序的原始资源,由AssetManager提供对这些资产文件的访问

META-INF/

它包含MANIFEST.MF文件,该文件存储有关JAR内容的元数据。APK签名也存储在此文件夹中

lib/

此文件夹包含已编译的代码,例如本地代码库

1.2 dex文件

注:

java的class文件内部是java的字节码(Java ByteCode)安卓系统中,用**Dalvik虚拟机(DVM = Dalvik Virtual Machine)**去把java源代码编译为dex可执行文件(Dalvik Executable) 2 安卓加密技术 2.1 代码混淆

最常用的做法是,用ProGuard去实现代码混淆。

2.1.1 ProGuard的作用 2.1.2 ProGuard的输出文件说明 2.2 加固

市面上有很多公司和厂商提供免费或收费的加固方案。

3 安卓破解技术 3.1 反混淆

使用反编译工具只能看到混淆之后的代码结构,看不到混淆之前的原始代码。

3.1.1 反混淆工具 3.2 去壳脱壳

不是所有加固的安卓apk都可以成功脱壳的。

总结:

腾讯乐固,新一代的360加固保等:没法脱壳(或许未来可以使用art+dex2oat相关机制去破解)

3.2.1 如何判断是哪家加固方案

通过反编译工具后,从dex或jar包的目录结构,以及相关的文件(比如AndroidManifest.xml)的内容,往往可以看出是哪家的加密方案。

腾讯乐固加密后的目录

腾讯乐固legu加密加壳后的apk,用apktool反编译后,得到的jar包目录结构是:

com.tencent.StubShell

截图举例:

安卓应用(APK)逆向工程 安卓应用(APK)逆向工程

另外反编译出的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"/>

中有:

也是典型的腾讯乐固的内容。

360加固保加固的目录结构

360加固后的apk经过dex2jar反编译后的目录结构是:

安卓应用(APK)逆向工程 安卓应用(APK)逆向工程

这种结构就说明是360加固保加固的。

3.3 从apk破解出java源码 3.3.1 AndroidManifest.xml

安卓中有个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等特征信息。

3.3.2 一步:apk->java

前提: 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文件:

安卓应用(APK)逆向工程

可以看到源码,想要导出全部源码,则可以去文件->全部保存或文件->另存为Gradle项目即可导出全部代码。

3.3.3 三步:app->dex->jar->java

前提: apk虽然被加固,但(后续)用FDex2等工具能够导出我们要的dex文件

思路:

从运行中的安卓app导出dex文件 用dex2jar等工具从dex文件中导出jar文件用反编译器(jadx/CFR/Procyon/JD-GUI)把jar转换出java源代码

详细步骤:

1. app导出dex

准备:

安卓应用(APK)逆向工程

Android 5.1.1,夜神模拟器已自带root

安卓应用(APK)逆向工程 安卓应用(APK)逆向工程

详细步骤:

安卓应用(APK)逆向工程 安卓应用(APK)逆向工程

激活FDex2,Xposed模块列表会更新,重启之后生效。

安卓应用(APK)逆向工程 安卓应用(APK)逆向工程

此处内部FDex2已经去导出app的所有文件对应的目录

没有看到我们要导出的dex文件:

有时候没有看到导出文件,则可以重新多试几次即可。有些app,打破沉寂的文件中,没有我们希望的(多个dex文件中的某个)包含了app业务逻辑的dex文件。说明该app采用了更加高级的加固,无法导出我们要的dex文件。 2. dex转换出jar

思路:已经从前面的app导出dex文件,然后用dex2jar等工具从dex转换出jar文件。

准备: 从下载网址:官网:,下载最新版本的dex2jar并解压

用法:

从apk中转换出jar:

说明和提示:

3. jar转换出java

选择合适的反编译器,如jadx或JD-GUI等,打开上一步从dex转换得到的jar文件。

jadx网址:

详见 4.3 反编译器内容

4 常见安卓破解工具 4.1 从app导出dex

下面整理关于从运行中的安卓app导出dex文件的一些hook工具。

4.1.1 导出dex文件的文件名

利用FDex2等工具,从运行的app导出dex文件时,看到很多文件名都类似于:com.huili.readingclub8825612.dex

这些hook工具生成的dex代码中,对应的命名规则应该是:

packageName + fileSize.dex

所以上面的文件名对应:

4.1.2 FDex2

用来从运行中的安卓app中导出dex文件的工具。下载地址:百度网盘 提取码:3e3t。

4.1.3 DumpDex

用来从运行中的安卓app中导出dex文件的工具。下载地址:

4.1.4 drizzleDumper

$ adb push F:drizzleDumper /data/local/tmp
$ chmod 755 drizzleDumper
$ ./drizzleDumper xyz.sysorem.crakme

4.2 dex转jar 4.2.1 dex2jar

下载网址:官网:、github:

功能: 用于处理安卓的dex文件和java的class文件的一系列的工具

用法:

从apk中转换出jar:

4.2.2 Enjarify

功能:把安卓的Dalvik字节码转化为Java字节码,和dex2jar类似

特点:google官方开源、用python3编写、比dex2jar更新且更好

用法:

与dex2jar比较

Enjarify

4.2.3 Dedexer

下载地址:

作用: 把dex转换为类似于汇编的格式,从dex文件创建类似于Jasmin的源代码

用法:

4.3 反编译器

此处主要讨论java反编译器,更主要的是和安卓相关的java的反编译器,其中尤其涉及到dex转出jar包后的,如何从jar包反编译出java源代码的相关反编译器。

作用: 从jar包转换出java源代码,用于在GUI图形界面工具中查看java代码;命令行工具中直接导出整个项目所有的java代码文件

常用反编译器:

jadx(个人觉得比较好用的) Procyon: 4.4 其他破解类工具 4.4.1 apktool

利用上述命令可以得到项目目录文件:

用apktool转换apk得到smali源码是有前提的:apk没有加固。加固了的apk反编译后只能看到被加固的目录结构,看不到app业务逻辑代码和结构,如下图:

安卓应用(APK)逆向工程

4.4.2 IDA 4.4.3 安卓XML破解 AXMLPrinter2

下载:

作用: 将安卓二进制的AXML转换成可读的xml文件

提示: 最佳更新都是2008年,看起来是很老旧的工具

用法:

java -jar AXMLPrinter2.jar xxx.xml output.xml
java -jar AXMLPrinter2.jar AndroidManifest.xml > main.xml

4.5 其他辅助类工具 4.5.1 安卓调试器 AndBug Android-OpenDebug 4.5.2 二进制编辑器

这部分详见文档开头第一个参考链接,下面只罗列一些工具名称

4.5.3 其他工具略叙

下面介绍的工具详见文档开头第一个参考链接,下面只罗列这些工具的名称

4.6 其他综合类工具

这部分详见文档开头第一个参考链接

4.7 其他相关工具 4.7.1 安卓Hook框架 Xposed框架

Xposed框架是用于安装相关插件FDex2,配合破解安卓,导出运行时app的dex文件。

Cydia Substrace

主页:

功能: 和Xposed类似的框架,用来安装各种插件,实现各种功能,比如可以安装绕过ssl检测的插件,用来破解ssl pinning

特点: hook底层方法非常方便,对so中的方法hook操作非常便捷

frida

官网:

简介:

5 安卓模拟器 5.1 夜神安卓模拟器

使用夜神安卓模拟器,来配合破解安卓:

5.2 文件浏览器

想要把安卓中(导出的dex等)文件拷贝(导)出来,一般需要借助于好用的安卓浏览器。

5.2.1 夜神模拟器中自带文件浏览器

ES文件浏览器: 功能很强,比较流行的安卓的文件浏览器。

5.2.2 MT管理器

特点:

应用简介:

MT管理器是⼀款强⼤的⽂件管理⼯具和APK逆向修改神器。

主要功能:

广告也精彩 广告也精彩
版权声明:admin 发表于 2023-08-28 9:09:10。
转载请注明:安卓应用(APK)逆向工程 | 嘿全导航
广告也精彩 广告也精彩

暂无评论

暂无评论...