APK静态与动态分析实战:从aapt到Frida的完整路径 简介面向 Android 安全分析、渗透测试与逆向初学者的 Python 辅助工具包围绕 APK 的静态与动态分析展开可帮助使用者提取 manifest、DEX 字节码、敏感 API、权限与导出组件等信息理解应用内部结构与潜在风险。压缩包共 46 个文件以 20 个 py 脚本为主辅以 20 个 dlist 配置列表、shell 启动脚本、敏感方法字典及 README 说明整体仅 280KB轻量易用。脚本分工清晰例如 parseManifest.py、parseDex.py、get_sensitive_apis.py、exported_components.py、static.py 等分别覆盖清单解析、DEX 反编译结果读取、敏感 API 匹配、组件暴露检测与静态分析流程runapp.py、pullfile.py 等则贴近动态运行与文件拉取场景工具模块之间边界较清晰方便单独复用或改造。对希望系统理解 Androguard、Frida、MobSF 等分析思路、并动手搭建 Python 自动化分析链路的读者很有帮助实测中可结合真实样本按阶段复现整个分析过程。已有 770 人学习该资源适合作为 APK 安全分析入门与脚本参考也适合在此基础上做二次开发。1. apkanalysis 到底在做什么静态与动态分析的分工拿到一个 APK是先拖进反编译器看代码还是直接装进模拟器跑起来多数人会选前者因为快、省事但只做静态分析你会漏掉运行时才发生的行为。只做动态分析也不行应用一启动就闪退、或者跑得干干净净你根本不知道问题出在哪。apkanalysis 的思路是把两端串起来静态负责画骨架——manifest 权限、组件暴露、代码里的敏感 API 和可疑调用链动态负责验真——实际运行中这些点是否触发、参数去了哪里、流量是否出网。这套方法适合做移动安全评估、隐私合规检测、应用行为审计的从业者。接下来不聊理论框架直接给一条能照做的分析路径。2. 静态分析的三条主线manifest、字节码与签名2.1 从 AndroidManifest.xml 下手用 aapt 拿第一手情报静态分析的第一步不是急着反编译整个 APK而是先把 AndroidManifest.xml 读透。这个文件里藏着应用最核心的声明信息包名、版本号、minSdk 与 targetSdk、权限申请、四大组件的暴露情况以及自定义权限的 protectionLevel。我一般用 Android SDK build-tools 自带的 aapt 来解包命令很简单aapt dump badging app.apk这条命令会输出包名、版本号、SDK 版本、入口 Activity 以及权限列表。核心信息一目了然适合快速建档。想看得更细用 xmltree 模式把 manifest 按树形结构完整打出来aapt dump xmltree app.apk AndroidManifest.xml输出结果类似E: uses-permission (line5) A: android:name(0x01010003)android.permission.READ_CONTACTS E: application (line8) A: android:debuggable(0x0101000f)0x0 A: android:label(0x01010001)Demo逻辑说明aapt 读的是编译后的二进制 XML直接输出结构化字段比用文本工具从解包后的文件里翻更准确也更快。拿到这些信息后我重点看三个组合targetSdk 与权限的匹配。targetSdk 大于 23 时运行时权限必须动态申请安装时不会一次性授权targetSdk 小于 23 时安装即授权风险面明显更大。exported 组件。MainActivity 常是 exportedtrue但如果一个 Service 或 BroadcastReceiver 也 exported 且没有权限限制外部应用可以直接拉起它这就是组件暴露风险。debuggable 标志。生产包里出现 debuggable1 基本可以直接判定异常要么是打包配置失误要么是定向测试包流入了外部渠道。参数选择上aapt dump badging --include-meta-data app.apk会把 meta-data 也输出能看到声明的渠道号、API Key、统计平台标识之类的配置项。虽然 meta-data 的值不一定可信但可以作为后续动态验证的线索。2.2 字节码反编译用 jadx 定位敏感 API 与调用链manifest 给的是骨架真正的逻辑在字节码里。jadx 是目前最顺手的反编译工具能把 APK 里的 dex 直接还原成 Java 源码操作路径也简单jadx -d output_dir app.apk常用参数-d指定输出目录缺省会在当前目录生成一个与 APK 同名的文件夹。--no-res跳过资源解码只出代码速度能快一倍以上。--deobf开启反混淆变量名可读性有提升但耗时明显增加。反编译完成后我会直接在源码目录里做关键词检索grep -r getDeviceId\|getImei\|getSimSerialNumber output_dir/sources/ grep -r http://\|https:// output_dir/sources/ | head -50关键词检索能帮我们快速定位敏感点但只看关键词还不够必须顺着调用往上翻。举个例子如果getDeviceId()的调用点是Application.onCreate()那就意味着应用一启动就会读取设备标识且调用栈里没有用户操作触发。审查隐私合规时这一条基本跑不掉。注意反编译结果只代表静态视图加壳应用会把真实逻辑藏起来源码目录里可能只有壳的入口类。这个问题放到避坑章节专门处理。2.3 签名校验与证书指纹判断来源可信度签名是 APK 的身份凭证第三方渠道流传的安装包经常被重打包签名就是识别重打包最直接的依据。用 apksigner 验证apksigner verify --print-certs app.apk输出示例Signer #1 certificate DN: CNAndroid Debug, OAndroid, CUS Signer #1 certificate SHA-256 digest: 7f6c9a0e2b3d4c5f...看到 CNAndroid Debug 基本不用犹豫这是本地调试签名正常情况下不应该出现在对外分发的包里。再看完整性验证apksigner verify --verbose app.apk重点关注 v1、v2、v3 签名方案的覆盖情况。v2/v3 方案签名后的 APK 在安装时会做更严格的校验重打包很容易暴露。如果某份 APK 只有 v1 签名低版本 Android 上也可以安装代表它的安全基线偏低。静态分析做完应该能回答三个问题这个 APK 申请了什么权限、暴露了哪些组件代码里的高危 API 集中在哪条路径上签名信息是否可信这三条就是后续动态验证的怀疑清单。3. 动态分析开箱模拟器沙箱、Frida Hook 与行为捕获动态分析的目标不是把所有行为都看一遍而是带着静态分析留下的怀疑清单逐项验证。验证分为三条线环境是否干净可控、关键函数是否被实际调用、流量与文件是否有对应动作。3.1 沙箱准备搭一个干扰最小的分析环境动态分析需要一个可控的 Android 运行环境。我一般选模拟器起步理由很直接重置成本低适合反复尝试。优先使用不带 Google 服务框架的镜像GMS 会引入大量后台流量干扰行为判断。用 avdmanager 创建 AVDavdmanager create avd -n analysis_avd -k system-images;android-30;default;x86_64启动模拟器我常用的参数组合是emulator -avd analysis_avd -no-snapshot -no-audio -no-window参数说明-no-snapshot跳过上次的保存状态保证每次启动都是干净环境。-no-audio关掉音频减少模拟器崩溃概率。-no-window无头模式适合批量分析。手动观察 UI 时去掉这个参数。模拟器起来后把 HTTP 代理指到本地抓包服务让应用所有网络请求都能被记录adb shell settings put global http_proxy 127.0.0.1:8080这个设置对整个系统生效。抓包服务需要安装 CA 证书后面证书校验的坑会单独讲。3.2 用 Frida 在运行时验证关键函数Frida 是动态分析的主力工具它能把 JavaScript 注入目标进程在函数执行前后做拦截和修改。attach 到已在运行的应用frida -U -l hook.js com.example.target或者用 spawn 模式从应用启动那一刻就开始跟踪frida -U -f com.example.target -l hook.js --no-pause两种模式的使用场景有差别attach 适合观察已经启动的应用spawn 适合分析应用启动阶段的行为比如 Application 里的初始化逻辑。一个基础 hook 脚本长这样// hook.js拦截两个敏感点 Java.perform(function () { // 拦截 TelephonyManager.getDeviceId var TelephonyManager Java.use(android.telephony.TelephonyManager); TelephonyManager.getDeviceId.overload().implementation function () { var imei this.getDeviceId(); console.log([hook] getDeviceId - imei); return imei; }; // 拦截 Log.d 输出方便跟踪调试日志 var Log Java.use(android.util.Log); Log.d.overload(java.lang.String, java.lang.String).implementation function (tag, msg) { console.log([log.d] tag : msg); return this.d(tag, msg); }; });逻辑说明Java.perform确保脚本在 ART 虚拟机绑定完成后执行避免时机错误。overload()用来匹配 Java 方法的重载版本getDeviceId 在部分 Android 版本上没有参数直接用默认签名即可。这种 hook 方式不修改 APK 文件本身不容易触发应用的完整性校验。参数说明-U连接 USB 设备模拟器也走这条-f指定包名并以 spawn 方式启动--no-pause去掉启动暂停应用不会卡在首屏。3.3 流量抓包与文件行为把证据链补完整函数被 hook 只是第一步网络层和文件层的证据能让结论站得住脚。文件层面的观察走 adbadb shell ps -A | grep com.example.target adb shell ls -la /data/data/com.example.target/提示模拟器镜像默认允许 adb 以 root 访问 /data/data/物理机则需要先 root或者使用 run-as 命令配合 debuggable 应用。日志同时跟起来adb logcat | grep -i com.example.target\|http\|ssl抓包工具负责记录外联请求的域名、路径和请求体。静态分析发现应用里有可疑 URL 时动态分析重点看这个 URL 是否真的被请求、请求里带了什么参数。这一步能把“代码里存在敏感调用”升级成“运行时实际发生敏感数据出网”风险等级完全不同。4. 静态与动态联动一份 APK 从安装到输出分析报告分开做静态和动态彼此都有盲区。静态可能漏掉运行时行为动态如果目标不明确会浪费大量时间看无关流量。把两者串成一条工作线效率反而最高。4.1 完整流程静态打前站动态做确认我常用的分析路径分五步走aapt 解包读 manifest记录权限、SDK 版本、组件暴露面和签名信息。jadx 反编译按敏感 API 关键词检索定位可疑调用点并截取调用栈。把可疑点整理成清单启动模拟器安装 APK。用 Frida 按清单逐个 hook确认这些点是否真的触发。同步抓包和文件行为确认数据是否出网、出到了哪里。安装与启动的命令adb install app.apk adb shell am start -n com.example.target/.MainActivity安装和启动只是进入分析场真正的难点在于应用是否配合——它可能检测模拟器闪退可能校验证书拒绝通信也可能加壳让 hook 无从下手。这些问题会在下一章展开。4.2 分析结论怎么组织证据链与风险分级一份合格的分析结论不是罗列发现而是回答“这个应用能不能用”“要不要上会复审”。我习惯按三块组织结论静态发现权限、组件、签名、代码可疑点。动态验证每个可疑点在运行时的实际表现包括调用栈、抓包结果、文件变化。风险结论高危、中危、低危每一项必须带证据。简化的结论表格编号静态发现动态验证结果风险级别S-01申请 READ_CONTACTS启动后第 3 秒读取通讯录并发送至某域名高危S-02使用 Debug 签名运行无异常行为中危S-03申请 CAMERA未触发调用低危这个表格可以直接作为分析报告的骨架。注意表格里“未触发调用”不等于“安全”可能只是没走到对应的逻辑分支需要在结论里标注验证覆盖范围避免误导后续决策。5. 实战避坑模拟器指纹、加壳与证书校验的五个真问题这个领域靠踩坑成长每一条都是真实分析现场换来的经验。按“现象 → 原因 → 解决”的方式整理出来可以少走很多弯路。5.1 应用检测模拟器导致闪退现象APK 安装后打开闪一下就没影了logcat 显示进程被主动终止。原因应用检测到模拟器特征比如ro.kernel.qemu1、Build.FINGERPRINT 含 generic然后主动退出。解决最简单的尝试是从镜像层面调整 build.prop改成真机指纹。但现在的应用检测维度很广还会看传感器列表、通话记录、电池状态。只改 build.prop 不够稳。更有效的方式是用 Frida 把检测函数直接 hook 掉Java.perform(function () { var Build Java.use(android.os.Build); Build.FINGERPRINT.value google/sdk_gphone64_x86_64/emu64_x:14/UE1A.230829.036/11131835:userdebug/dev-keys; Build.MODEL.value Pixel 7; Build.HARDWARE.value goldfish; });这条方案能绕过部分只在启动时检测一次的 app。如果应用把检测逻辑埋在多个关键调用点建议直接用物理机分析别在模拟器上死磕。5.2 加壳应用反编译后找不到真实逻辑现象jadx 打开源码只有壳入口和几个类搜索高危 API 完全没有结果。原因应用经过加固真实 dex 到运行时才被解密加载静态层只能看到壳。解决两条路一条是运行时脱壳。先启动应用再用脚本把内存里已解密的 dex dump 出来frida -U -f com.example.target -l dump_dex.js --no-pausedump_dex.js 通过遍历 ClassLoader 拿到 dex 的内存地址写入文件后就能用 jadx 重新分析。另一条是直接放弃完全逆向转用动态 hook 观察壳加载后的行为抓到什么看什么。两条路可以同时走互相补盲区。5.3 HTTPS 抓包大量 TLS 握手失败现象代理配置正确证书也装了但抓包工具的流量列表里全是握手失败应用本身功能正常。原因应用做了证书固定只信任自己打包的证书代理证书被拒绝。解决用 Frida 绕过常见网络库的证书校验层。OkHttp 是使用最广的库固定校验入口通常是 CertificatePinnerJava.perform(function () { var CertificatePinner Java.use(okhttp3.CertificatePinner); CertificatePinner.check.overload(java.lang.String, java.util.List).implementation function (hostname, peerCerts) { console.log([bypass] CertificatePinner.check - hostname); return; }; });参数说明check方法接收两个参数第一个是目标 hostname第二个是证书列表。直接空实现等于跳过校验。非 OkHttp 的应用需要定位到 SSLContext 初始化入口那条路工作量更大。5.4 targetSdk 越高静态权限和动态行为越对不上现象静态分析列了一堆权限动态验证时手动点遍主界面权限弹窗一个都没出现结论不好写。原因Android 6.0 之后的运行时权限机制要求应用在运行时申请targetSdk 越高越严格。如果操作路径没走到申请点权限自然不会弹窗。解决动态验证时要覆盖关键操作路径而不是只看主界面。注册流程、登录流程、导入文件、分享功能这些路径才最容易触发权限申请。把操作路径做成用例清单每一条都走一遍再下结论。5.5 低危报警习惯性忽略埋下大隐患现象分析报告里几十条“允许备份”“Log 输出”之类的低危项时间一长就习惯性跳过结果某次把一个在日志里打明文支付参数的应用漏掉了。原因低危项批量堆积掩盖了真正的高风险组合。解决构建分级规则库。把“允许备份”这类常识级问题降为提示项把“日志输出敏感字段 数据出网”这种组合升为高危组合。结论以组合风险为准而不是单点清单。这样报告的可信度和可执行性都会明显提升。6. 把 apkanalysis 沉淀成日常流程批量、规则与快照最后一章不谈新概念聊三个能让你长期受益的工作习惯。第一个习惯是批量。分析任务很少只有一个 APK更多时候是一整个目录的 APK。把静态分析的命令串进循环脚本先自动产出一份摘要再人工跟进可疑点for apk in ./apks/*.apk; do echo $apk aapt dump badging $apk | grep -E package|sdkVersion|targetSdkVersion apksigner verify --print-certs $apk | head -5 done这份摘要可以作为筛选漏斗把明显低风险的样本过滤掉把精力集中在需要深挖的包上。第二个习惯是规则沉淀。每一轮分析都会遇到新的敏感 API、新的可疑字符串、新的组合模式。把这些补充进自己的检索模板里日积月累就是独家的分析武器库。我常用的几条固定检索命令包括读写短信相关类、采集手机号相关类、明文 HTTP 通信串每补齐一条就更新到模板。第三个习惯是快照也是我认为最重要的一条。动态分析每走一个关键步骤就保存一份快照无论是模拟器层面的快照还是应用痕量日志都能让你在触发反检测或跑崩之后一键回滚。回滚成本越低越敢放开手做尝试。这是我每次重搭分析环境时最先装的工具带来的安全感比任何技巧都实际。希望帮到你。本文还有配套的精品资源点击获取