10、资源文件分析:resources.arsc结构、图片/布局/字符串资源的提取与修改、AndroidManifest.xml解析
资源文件分析,说白了就是逆向工程的“拆快递”环节。你拿到一个APK,里面藏着各种图片、布局、字符串,还有那个至关重要的清单文件。这些东西怎么取出来?怎么改?今天我就带你走一遍。
10.1 resources.arsc:资源索引的“总账本”
resources.arsc 这个文件,我习惯叫它“资源索引表”。它不存图片本身,也不存字符串原文,它存的是——资源ID和实际资源之间的映射关系。
举个例子,你在代码里写 R.string.app_name,编译后变成了一个十六进制数,比如 0x7f010000。这个数怎么找到真正的字符串?就是靠 resources.arsc 来查。
核心结构(简化版)
- 资源包(Package):每个包有一个包名和ID,比如
0x7f通常是应用自己的资源包。 - 资源类型(Type):比如 string、layout、drawable、color 等。
- 资源项(Entry):每个资源的具体条目,包含资源ID和对应的数据(比如字符串值、文件路径等)。
我记得有一次分析一个混淆过的APK,resources.arsc 里居然有几千个资源项,但大部分都是空的。嗯,那是对抗工具在故意制造噪音。你想想看,如果每个资源ID都指向一个无意义的值,逆向分析的人得多头疼。
10.2 图片资源的提取与修改
图片资源通常放在 res/drawable-* 或 res/mipmap-* 目录下。提取很简单,用 apktool d 解包后,直接复制出来就行。
修改呢?我建议你遵循一个原则:保持文件名和目录结构不变。比如你替换一张启动图,原文件是 res/mipmap-hdpi/ic_launcher.png,那你新文件也得叫这个名字,放在同一个目录下。
我的小技巧:替换图片时,尽量保持原图的尺寸和格式。如果原图是 PNG,你换成 JPG,虽然也能用,但有些系统会报错。我曾经因为把一张 9-patch 图片换成了普通 PNG,导致界面拉伸变形,排查了半天。
另外,有些 APK 会把图片资源打包进 resources.arsc 里(比如某些游戏引擎)。这时候你就得用专门的工具,比如 AssetStudio 或 UnityEX 来提取。
10.3 布局文件的解析与修改
布局文件是 XML 格式,存放在 res/layout/ 目录下。用 apktool 解包后,直接打开就能看到。
举个例子,一个典型的布局文件长这样:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World" />
<Button
android:id="@+id/btn_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击我" />
</LinearLayout>
修改布局文件,最常见的是改 android:text 属性,或者调整控件的 android:layout_width 和 android:layout_height。但要注意,有些 APK 用了 AAPT2 编译,布局文件里会多出一些奇怪的属性,比如 android:theme 或 android:style,这些不要乱删。
警告:修改布局文件后,一定要用 apktool b 重新打包,并且签名。如果你只是改了 XML 文件,直接塞回 APK 里,安装时会报“解析错误”。
10.4 字符串资源的提取与修改
字符串资源通常放在 res/values/strings.xml 里。提取很简单,解包后直接复制。修改呢?我建议你注意两点:
- 不要改变字符串的 name 属性:比如
<string name="app_name">原名称</string>,你只能改标签里的内容,不能改name。 - 注意转义字符:比如单引号、双引号、换行符等。如果你直接写
It's a test,编译会报错,得写成It\'s a test。
我曾经遇到过一个 APK,它的字符串资源里藏了加密的密钥。嗯,你没听错,开发者把 AES 密钥直接写在了 strings.xml 里,还自以为很安全。我提取出来后,直接解密了它的网络通信数据。
10.5 AndroidManifest.xml 解析
AndroidManifest.xml 是 APK 的“身份证”。它记录了应用的包名、组件(Activity、Service、BroadcastReceiver、ContentProvider)、权限、版本号等信息。
解析它,我一般用 apktool 或 AXMLPrinter2。解包后,你会得到一个可读的 XML 文件。比如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我重点关注几个地方:
- 包名:决定了应用的唯一标识。
- 权限:看看它申请了哪些敏感权限,比如读取联系人、定位等。
- 组件:特别是
exported="true"的组件,这些是外部可调用的,容易成为攻击入口。 - 版本号:有时候开发者会通过版本号来区分不同渠道包。
避坑指南:我曾经分析过一个 APK,它的 AndroidManifest.xml 里声明了 android:debuggable="true"。这意味着这个应用可以在调试模式下运行,攻击者可以直接用 adb 连接并注入代码。嗯,这种低级错误,我在很多商业应用里都见过。
10.6 知识体系图
下面这张图,帮你理清资源文件分析的核心逻辑:
10.7 实战建议
最后,给你几个实战中的小建议:
- 先看 AndroidManifest.xml:了解应用的整体结构,再去看具体资源。
- 用 apktool 解包:这是最常用的工具,支持反编译和重新打包。
- 修改后一定要签名:否则安装不了。我习惯用
jarsigner或apksigner。 - 注意资源混淆:有些 APK 用了资源混淆工具,比如
AndResGuard,资源名会被改成a、b、c之类的。这时候你得靠资源ID来定位。
我的习惯:每次分析一个 APK,我都会先解包,然后快速浏览 AndroidManifest.xml 和 strings.xml。这两个文件能告诉我这个应用大概在做什么,有没有敏感权限,有没有硬编码的密钥。嗯,很多“安全”应用,其实第一步就栽在了这里。