3、静态分析入门:APK解包、反编译工具(jadx、apktool)、AndroidManifest.xml分析。
好,咱们进入正题。静态分析,说白了就是不动手跑代码,直接看源码和配置文件来找漏洞。我刚开始做安全那会儿,觉得动态调试才酷,后来发现——静态分析才是基本功,而且效率极高。你想想看,一个APK扔进来,几分钟就能摸清它的“底裤”颜色,多痛快。
3.1 为什么要做静态分析?
静态分析的目的很简单:在不执行代码的情况下,发现应用的安全缺陷。它就像医生看X光片,不用开刀就能知道骨头有没有裂。
我个人习惯,拿到一个APK后,先做三件事:
- 解包:把APK当成一个压缩包,拆开看看里面有什么文件。
- 反编译:把DEX字节码转成可读的Java代码或Smali代码。
- 分析清单:重点看AndroidManifest.xml,这里藏着大量信息。
这三步走完,这个应用的基本面就清楚了。我在项目中遇到过好几次,光靠分析Manifest文件就发现了组件暴露、权限滥用等问题,根本不需要跑代码。
3.2 APK解包:拆开看看里面有什么
APK其实就是一个ZIP压缩包,改个后缀名就能解压。但专业的做法是用工具。
3.2.1 手动解包(了解原理)
你可以直接把APK后缀改成.zip,然后用解压软件打开。里面大概有这些东西:
classes.dex:核心代码,Dalvik字节码。AndroidManifest.xml:应用配置文件,二进制格式。resources.arsc:编译后的资源文件。lib/:原生库(.so文件)。META-INF/:签名信息。
嗯,这里要注意:直接解压出来的AndroidManifest.xml是二进制格式,人眼是看不懂的。所以我们需要专业的解包工具。
3.2.2 使用apktool解包(推荐)
apktool 是我最常用的工具之一。它能把APK解包成可读的Smali代码和资源文件,还能把二进制Manifest转成文本格式。
基本用法:
# 解包
apktool d target.apk -o output_dir
# 回编(重新打包)
apktool b output_dir -o new.apk
解包后,你会得到一个文件夹,里面包含:
smali/:反编译后的Smali代码。AndroidManifest.xml:已经转成可读的XML格式。res/:资源文件。original/:原始文件备份。
-r 参数跳过资源反编译,或者用 --no-res 加快速度。
3.3 反编译工具:jadx vs apktool
解包只是第一步,真正的重头戏是反编译——把字节码还原成Java代码。这里有两个主流工具:jadx 和 apktool。它们各有千秋,我一般搭配使用。
| 工具 | 输出格式 | 优点 | 缺点 |
|---|---|---|---|
| jadx | Java源码(.java) | 可读性高,接近原始代码;支持GUI和命令行 | 对混淆代码还原度一般;大项目可能卡顿 |
| apktool | Smali汇编(.smali) | 还原度高,支持修改后回编;适合做二次开发 | Smali代码可读性差,需要学习成本 |
3.3.1 jadx:快速看源码
jadx 是我个人最推荐的反编译工具。它能把DEX文件直接转成可读的Java代码,而且支持GUI界面,点一点就能看。
命令行用法:
# 直接反编译APK
jadx target.apk -d output_dir
# 只反编译classes.dex
jadx classes.dex -d output_dir
# 带GUI启动
jadx-gui target.apk
我在项目中遇到过很多次,用jadx打开APK后,直接搜索关键词(比如“password”、“secret”、“key”)就能找到硬编码的敏感信息。有一次,我甚至在一个金融类应用里找到了数据库明文密码……嗯,那场面,挺尴尬的。
a.a.b())。这时候就需要结合Smali代码来看了。
3.3.2 apktool + Smali:深入底层
当jadx搞不定的时候,就该apktool上场了。Smali代码虽然难读,但它是最接近原始字节码的表示形式。你想想看,混淆器再怎么混淆,Smali代码里的指令顺序和寄存器使用是骗不了人的。
举个例子,jadx反编译出来的代码可能是:
String str = "hello";
if (str.equals("world")) {
// do something
}
但Smali代码里,你能看到具体的寄存器分配和指令:
const-string v0, "hello"
const-string v1, "world"
invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
if-eqz v2, :cond_0
为什么要看Smali?因为有些恶意代码会通过动态加载、反射调用等方式隐藏行为,jadx可能直接跳过了,但Smali里能看得一清二楚。
3.4 AndroidManifest.xml分析:信息量巨大
AndroidManifest.xml 是应用的“身份证”。它声明了应用的所有组件、权限、硬件要求等。我每次拿到APK,第一件事就是打开这个文件,从头到尾扫一遍。
3.4.1 关键节点速查表
| 节点 | 作用 | 安全关注点 |
|---|---|---|
<uses-permission> |
声明应用需要的权限 | 权限是否合理?有没有过度申请? |
<application> |
应用全局配置 | android:debuggable="true"?android:allowBackup="true"? |
<activity> |
声明Activity组件 | 是否导出?有没有配置 |
<service> |
声明Service组件 | 是否导出?有没有权限保护? |
<receiver> |
声明BroadcastReceiver | 是否导出?接收的Action是否敏感? |
<provider> |
声明ContentProvider | 是否导出?android:readPermission和android:writePermission是否设置? |
3.4.2 常见安全风险点
我总结了几条“一眼就能看出问题”的检查项:
- debuggable 为 true:应用可调试。这意味着攻击者可以附加调试器,窃取数据或修改逻辑。我曾经在某个银行App里发现这个标志没关,直接就能用adb调试……
- allowBackup 为 true:允许备份。攻击者可以通过adb backup导出应用数据,包括SharedPreferences、数据库等。
- 组件导出但未设置权限:比如一个Activity设置了
android:exported="true",但没有android:permission保护,那任何应用都可以启动它。 - 滥用
android:protectionLevel:自定义权限如果设为normal或dangerous,其他应用可以轻易申请。
<provider> 都会多看一眼。
3.5 知识体系图:静态分析核心流程
下面这张图概括了静态分析的完整流程,从拿到APK到发现漏洞,每一步都离不开这些工具和技巧。
3.6 实战小贴士
最后,分享几个我自己的实战习惯:
- 先看Manifest,再看代码:Manifest能告诉你这个应用有哪些组件、用了什么权限,心里有个谱。
- 搜索敏感关键词:在jadx里直接搜
password、secret、key、token、api_key,往往有惊喜。 - 关注
WebView相关代码:搜索setJavaScriptEnabled、addJavascriptInterface,这些是WebView漏洞的高发区。 - 别忽略
res/values/strings.xml:有些开发者会把API密钥、URL硬编码在字符串资源里。
好了,静态分析入门就讲到这里。记住,工具只是手段,思路才是核心。你拿到一个APK,先想清楚“我要找什么”,然后再动手。下一节我们会深入动态分析,到时候再聊。