ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

MuMu模拟器ADB安装APK与HTTPS抓包全流程实战

MuMu模拟器ADB安装APK与HTTPS抓包全流程实战 用过Android模拟器的人都清楚MuMu模拟器配上ADB基本就是一套免费的Android调试环境。无论是安装APK、跑自动化脚本、还是排查App的HTTPS请求MuMu加ADB加抓包工具这三件套能覆盖日常开发和测试里一大半的需求。这篇文章围绕“mumu模拟器adb安装apk以及抓https包”这条主线把我实际踩过的坑和验证有效的流程一次讲清楚适合刚接触Android调试、或者一直被HTTPS抓包证书问题卡住的小伙伴参考。我会先用一段篇幅讲清楚为什么选MuMu而不是其他模拟器然后进入ADB连接和APK安装的实操接着讲HTTPS抓包的原理与证书配置最后给出完整抓包流程和常见问题的排查方案。整个过程的每一步都是我实打实验证过的不绕弯子。1. 为什么要选MuMu模拟器做调试和抓包1.1 MuMu模拟器在Android调试里的优势在Windows上做Android应用调试方案其实不少真机、Genymotion、夜神、雷电、蓝叠、MuMu。我为什么一直把MuMu留在一线首先它对ADB的兼容性非常友好本身就是一款国内团队维护的安卓模拟器开发活跃很多国产App在MuMu里跑起来的兼容性明显比老牌模拟器好尤其是需要用到国内账号登录、支付SDK这类场景。其次它默认自带root开关这一点对抓HTTPS包特别重要后面讲系统证书安装的时候会详细展开。再次MuMu在资源占用和稳定性之间的平衡做得不错老机器也能跑得动长时间挂代理抓包不容易崩。另外一个很实际的原因成本。真机调试当然更接近线上环境但在没有测试机或者需要多版本Android环境并行的时候模拟器的效率远高于真机。MuMu支持多开可以同时开几个不同Android版本实例配合ADB连接不同端口能一次性覆盖不同系统版本的兼容性测试。这一点比反复切换真机方便太多。1.2 调试环境清单要把这套环境搭起来不需要太多东西但每一样都要选对。第一是模拟器本体。MuMu有多个版本比如MuMu 6和MuMu 12对应的Android版本和ADB端口不一样。无论哪个版本安装后先到“设置”里找到“开发者选项”确认“USB调试”已经打开。如果找不到开发者选项就连续点击“关于平板电脑/关于手机”里的版本号一般点击5到7次就会解锁。第二是ADB工具。ADB的全称是Android Debug Bridge是Android官方提供的调试桥接工具。它不在模拟器里是装在电脑上的。最简单的获取方式是从Android SDK Platform Tools里下载也可以用MuMu安装目录自带的adb。这里有个坑如果你电脑里同时装了多个模拟器它们的adb版本可能不一致混用很容易出现连接不上的情况。建议统一用一个版本我习惯用最新版Platform Tools里的adb然后把它加到系统PATH里这样不管哪个模拟器都能用同一份工具。第三是抓包工具。Windows上我用得最多的是Charles和Fiddler这两个都属于代理型抓包工具能解密HTTPS流量Wireshark属于网卡层抓包适合分析底层协议但不适合直接看App的明文HTTPS请求内容。新手建议先用Fiddler安装配置相对少证书处理也方便如果需要跨平台或者习惯看树形请求结构就选Charles。文章后续的实操部分会以Charles为主思路同样适用于Fiddler。这三样准备好就已经具备开始动手的条件了。下面先解决ADB连接和APK安装这个最基础的问题。2. ADB连接模拟器与APK安装实操2.1 先让模拟器老老实实连上ADBADB连接MuMu和连接真机的思路一样本质上都是通过adb connect建立一条调试通道。但模拟器没有USB线所以走的不是USB驱动而是网络端口。MuMu模拟器的ADB调试端口通常在启动时固定下来大部分版本默认是127.0.0.1:7555也有部分版本使用16384或别的端口。具体端口怎么看打开MuMu的安装目录找到配置文件一般在config或者vm目录下里面会写adb端口更简单的方法是直接看MuMu设置里的“网络设置”或“ADB调试”入口有些版本会直接显示端口号。如果你用的是MuMu多开器每个实例的端口会不同连接时要注意区分。拿到端口后在电脑上执行ADB连接命令adb connect 127.0.0.1:7555如果返回connected to 127.0.0.1:7555表示连接成功。这时再执行adb devices能看到类似下面的输出List of devices attached 127.0.0.1:7555 device注意状态一栏必须是“device”字样如果显示的是“unauthorized”说明模拟器弹了授权窗口而你还没点允许。重新看一眼模拟器屏幕很多新手都会栽在这一步以为命令卡住了其实只是忘了点屏幕上的“允许USB调试”按钮。这里多说一句最常见的原因是授权弹窗没点、授权被误点成拒绝、或者连接端口连到了其他设备的ADB服务。解决方法是先杀掉ADB进程再重新连接adb kill-server adb connect 127.0.0.1:7555再次确认模拟器屏幕上的弹窗选择允许并在权限提示里勾选“始终允许”。2.2 APK安装的几种方式哪一种最稳ADB连上以后安装APK就顺理成章了。常规命令是adb install xxx.apk但在实际操作中直接一根命令装APK经常会因为版本冲突、签名不一致、或者APK包本身是测试包而报错。所以我按优先级整理了几种方式你可以根据实际情况选择。第一个是普通安装。适用于从应用市场或官方渠道下载的APK包名没有在系统里出现过直接执行adb install加APK路径即可。第二个是覆盖安装。如果App已经存在并且你只是想把新包替换上去用adb install -r xxx.apk-r参数表示replace保留应用数据的前提下替换安装。我们在日常开发里经常用这个命令比如自测新版本时不想重新登录账号或者不想重新配置一遍App内部的数据。第三个是允许测试包安装。有些APK在AndroidManifest里设置了android:testOnlytrue直接adb install会报INSTALL_FAILED_TEST_ONLY错误。解决办法是加-t参数adb install -t xxx.apk我最早碰到这个错误是在解一个游戏APK的时候当时以为包坏了折腾半天才发现是testOnly标志的问题。第四个是降级安装。App当前版本比你要装的版本高普通覆盖装是装不上去的这时候要加-d参数adb install -d -r xxx.apk-d表示downgrade允许降级。这个场景常见于从新版回滚到旧版比如最新版App某个功能出了问题想临时装回上一个稳定的版本。第五种路径适合所有方式都不灵的情况先卸载后安装。adb uninstall 包名 adb install xxx.apk包名不是应用名而是类似com.example.app这样的唯一标识。可以用adb shell pm list packages来查看当前模拟器里所有包名再配合grep筛选。比如想在MuMu里找到微信的包名可以执行adb shell pm list packages | grep wechat。这种方式虽然多了一步但对于签名冲突、数据残留导致安装失败的情况是最省心的。2.3 安装失败的典型场景与处理安装APK最常遇到的坑集中在三类。第一类是版本不兼容。APK要求的Android版本比模拟器的系统版本高或者CPU架构不匹配比如当前模拟器是x86架构却装了armeabi变体的包安装过程会直接报INSTALL_FAILED_NO_MATCHING_ABIS。解决办法是下载对应架构的APK。这也能解释为什么大家在热词里搜“x86”相关的内容MuMu在Intel平台上的版本对x86应用支持更好ARM转译也做了很多优化但如果包本身只放了ARM的so库还是可能有问题。第二类是签名问题。报错信息通常是INSTALL_FAILED_UPDATE_INCOMPATIBLE意思是系统里已经存在同包名但签名不同的应用。这种情况最常见于安装了市场版又想覆盖安装一个签名不同的开发版。最好先卸载再安装。卸载前注意备份App数据因为卸载会把数据一起清掉。第三类是提示“device offline”或者“device not found”。这多半不是APK的问题而是ADB连接已经断了。模拟器如果在安装过程中被关闭、切后台太久被系统回收、或者网络代理设置把ADB端口干扰了都会导致这个结果。处理方式是重新执行adb connect再跑一次安装命令。还有一个不太起眼但很常见的错误APK路径带了中文名或空格。Windows命令行对路径解析有历史遗留的毛病建议把APK改名为纯英文和数字比如app_v1.0.3.apk放在一个没有空格的目录下能少踩很多坑。3. HTTPS抓包原理与证书信任机制3.1 代理抓包是怎么运作的为什么抓HTTP包很简单抓HTTPS就各种头疼因为HTTP是明文协议数据从App发到服务器途中任何一层代理都能直接看到内容。而HTTPS在HTTP外面加了一层TLS加密数据在发送前就已经被加密了抓包工具如果只是把流量截下来看到的是一堆无法解读的密文。那抓包工具是怎么解密HTTPS的核心思路是中间人代理。以Charles为例它会在电脑上启动一个代理服务然后模拟器或手机里的流量通过这个代理转发。当App请求一个HTTPS地址时Charles不会直接转发而是把自己伪装成目标服务器与App完成一次TLS握手然后Charles再作为客户端去和真正的服务器建立连接。这样Charles就掌握了通信的两边服务器返回的响应它可以解密后重新加密发给AppApp发送的请求它也能解密后重新加密发给服务器。要实现这一步关键是让App信任Charles的证书。Charles会生成一个自己的CA根证书只要把这份根证书安装到模拟器或手机的系统信任列表里App在验证服务器证书时就会信任Charles伪造的那个证书。反过来如果有人不安装这份证书就试图抓包App会立刻报证书校验失败。这也是为什么很多人抓到的是乱码或者直接断网。这里面有一个容易被忽略的细节代理抓包只能抓到走代理的流量。如果App在代码里强制不走系统代理比如使用了OkHttp的proxy(Proxy.NO_PROXY)或者Socket层直连IP那么即便你在系统里配好了代理这些请求也不会经过抓包工具看起来就是“抓不到包”。这种情况就需要用透明代理或者网卡抓包来配合处理后面我会讲一点思路。3.2 抓包工具怎么选经常有人问Charles、Fiddler、Wireshark到底选哪个我按自己的实际感受说一下。Charles主打跨平台和易用性macOS和Windows上都有。它的请求列表按树形结构组织域名层级一目了然还能直接对请求做断点、修改参数、设置弱网对日常调试App非常友好。缺点是界面交互有些老派新版更新不算激进正版价格也不算便宜。对于只想偶尔抓包试一试的人试用版会有启动延迟但核心抓包功能基本不受影响。Fiddler是Windows平台上的老牌工具免费且功能很全。它的请求列表是平面表格结构过滤和FiddlerScript做自动化能力强社区资料也丰富。缺点是跨平台支持一般界面比较密集新手第一次打开会有点懵。我个人在Windows上跑自动化弱网测试时倾向于用Fiddler因为它可以写脚本批量修改请求。Wireshark是另一条赛道的工具它工作在网卡层能抓到经过本机网络接口的所有数据包但默认不解密HTTPS内容。如果你想分析TCP握手、看DNS解析过程、或者排查“明明代理配了但流量压根没走代理”这类问题Wireshark是逃不掉的选择。如果只想看App的HTTP请求和响应体用Charles或Fiddler效率更高。还有一个偏命令行的工具是tcpdump在模拟器或真机里用root权限跑可以抓本机网络接口的流量适合在没有电脑端抓包工具可用的场景比如在Android设备上临时抓包保存成pcap文件再拉回电脑用Wireshark分析。3.3 绕过Android7以上证书限制的方案证书安装是HTTPS抓包里最麻烦的一道坎。在Android 7及以下的系统里App默认信任用户证书和系统证书所以只要把抓包工具的证书通过模拟器设置安装到“用户证书”里就能顺利抓包。但Android 7以上系统做了收紧默认只信任系统证书对用户证书一律不信任。这就导致很多人在老版本上抓包正常换到新版本模拟器后HTTPS全变成红叉或乱码。针对这个限制有几条路可以走。第一条路是修改App的networkSecurityConfig。如果App的开发方是你自己可以在AndroidManifest.xml里配置networkSecurityConfig并在配置文件里把user证书加进trust-anchorsnetwork-security-config base-config cleartextTrafficPermittedtrue trust-anchors certificates srcsystem / certificates srcuser / /trust-anchors /base-config /network-security-config这样App就会信任用户证书抓包工具装的证书就能正常工作了。这个方案对调试自己的App最干净但抓第三方App时没法改它的Manifest。第二条路是把抓包工具证书复制到系统证书目录。Android系统信任的系统证书存放在/system/etc/security/cacerts/目录下文件命名规则是“证书主题哈希值.0”。只要用root权限把用户证书转成系统证书放进去并给足权限手机里所有App都会默认信任它。MuMu模拟器的好处就在这里它能够一键开启root省去了刷机的麻烦。第三条路是让抓包工具直接用系统级方式接管流量比如用Frida hook掉SSL证书校验逻辑这属于进阶玩法适合App做了双向校验或者强证书锁定的场景。这一块涉及的东西很多新手不必一上来就碰先把前两条路吃透再说。4. 完整实操从连接模拟器到扒下HTTPS请求4.1 配置模拟器代理并安装抓包证书理论讲完下面把抓包的完整流程串一遍。我用的是MuMu模拟器加CharlesWin10系统理论上这套流程在Fiddler上也成立。启动Charles之后先确认代理端口。菜单路径是Proxy - Proxy Settings勾选HTTP Proxy端口默认8888记下这个端口。然后在模拟器上设置网络代理打开模拟器的WiFi设置长按当前连接的网络选择“修改网络”展开高级选项把代理设置为“手动”主机名填电脑的局域网IP端口填8888。如果你用的模拟器版本不方便在WiFi设置里改代理也可以直接用ADB命令设置全局代理adb shell settings put global http_proxy 192.168.x.x:8888这里192.168.x.x必须填电脑在局域网中的IP不能填127.0.0.1因为模拟器内部的127.0.0.1指向的是模拟器自己。改完后用下面命令可以确认代理是否生效adb shell settings get global http_proxy然后安装Charles证书。Charles的证书下载地址是固定的在手机或模拟器浏览器里访问chls.pro/sslCharles官网提供的证书下载地址会下载一个crt文件。MuMu里直接用浏览器打开这个地址下载完成后在“设置 - 安全 - 加密与凭据 - 安装证书 - CA证书”里选择该文件完成安装。这个步骤安装的是用户证书Android 7以下的App会直接信任它Android 7以上的App还需要做系统证书迁移。证书装好后先在模拟器里随便打开几个HTTPS网页看Charles里是否出现了hostname和请求列表。如果看到了说明代理和证书已经通了如果看不到先检查代理设置是否正确再检查证书有没有装成功。4.2 处理Android7以上证书信任问题这一步默认你已经打开了MuMu的root权限。用adb连接模拟器后先确认root是否可用adb root如果返回restarting adbd as root就说明已经拿到root权限了。接着需要把系统目录挂载为可写adb remount有些版本的MuMu执行remount会提示不能remount这时可以改用adb shell su mount -o rw,remount /system之后把用户证书从系统里导出来再转换为系统证书格式。用openssl生成主题哈希值openssl x509 -inform PEM -subject_hash_old -in charles-cert.pem | head -1假设生成的哈希值是abcdefab就把证书重命名为abcdefab.0然后推送到模拟器adb push abcdefab.0 /system/etc/security/cacerts/再把权限设置成644adb shell chmod 644 /system/etc/security/cacerts/abcdefab.0重启模拟器证书就变成系统级信任了。之后那些在做测试时经常抓取的目标App即使没有开启网络安全配置也会用系统证书做信任链校验HTTPS流量就能被正常解密。如果不想动命令行MuMu设置里也有一个可视化的共享目录可以把文件直接拖进模拟器里操作但核心的证书转换步骤还是绕不开openssl那步。我这里写的是Linux/mac下的存量办法Windows用户可以用Git Bash或者WSL跑openssl效果一致。4.3 用Charles抓到一条真实HTTPS请求证书和代理都配置好之后真正的抓包体验就顺滑了。我以抓一个普通资讯类App为例在MuMu里冷启动App滑动几个页面然后切回Charles在Structure标签下能看到按域名分组的请求列表。点开一个HTTPS请求能看到三块核心信息。第一块是Overview展示请求URL、响应状态、耗时、大小等概要信息。第二块是Request里面有请求头、请求参数、请求体对于排查接口传参错位非常关键。第三块是Response显示服务器返回的JSON或HTML内容。我经常用这个来判断App弹窗提示是否来自后端还是客户端本地写死的文案。实际操作中要注意很多App在启动时会并发发出大量请求如果不设置过滤列表会被撑得很难看。我通常在Filter输入框里填目标域名比如只需要看api.example.com就把其他域名隐藏掉。如果只想看某几个接口还可以右键选择Focus让这些域名固定在列表顶部。另外还要注意分页和分片。某些视频类App的接口会返回M3U8或分片地址直接在HTTPS抓包里看到的只是索引文件真正的切片走的是另一个CDN域名。如果发现抓到的请求里没有视频内容别急着怀疑抓包姿势先把所有域名过滤一遍。4.4 验证代理解除和授权清理抓包结束后如果直接关掉Charles模拟器还保持着全局代理会导致App无法访问网络。这个大部分人都会踩到。解除代理有两种方式。第一种是模拟器WiFi设置里把代理改回“无”。第二种用ADB命令更快adb shell settings put global http_proxy :0这行命令会把全局代理清零。执行后再用adb shell settings get global http_proxy确认返回是null就表示代理已经解除了。同时还有一个容易被忽略的坑系统证书目录里已经多了一个自定义证书如果不想长期保留把模拟器还原或删掉那个重命名后的.0文件就行以免之后正式测试时因为证书信任导致结果偏差。我是建议抓包完成后顺手清理掉保持模拟器环境干净。5. 踩坑实录与常用命令速查5.1 ADB与连接高频报错先整理几个我见过最多的连接类报错。第一个是adb connect时提示unable to connect to 127.0.0.1:7555。这类问题多半是模拟器还没启动完成或者端口写错了。先去MuMu设置确认端口再确认模拟器进程没有崩。如果端口没错但连不上检查是不是本机有其他ADB服务占用执行adb kill-server后再试。第二个是adb devices显示unauthorized。前面提过去模拟器屏幕点授权弹窗。如果点了允许还是unauthorized试试重启模拟器的ADB服务或者干脆重启模拟器问题通常能解决。第三个是命令行里经常见到的“device offline”。这通常意味着ADB连接还在但设备端没响应比如模拟器卡死、后台应用把系统拖垮。我遇到这种情况会先执行adb reconnect offline不行就直接重启模拟器别在一个进程上死磕。第四个是“unexpected status 404 not found”这类报错。这个报错经常出现在某些服务端接口返回404时不一定是你本地配置错了。你需要检查请求的完整URL是不是多了代理前缀或者Charles里的Map Remote设置是否把请求重定向错了位置。如果电脑端用代理访问某个地址出现404先在正常浏览器里不带代理访问一次确认是服务端问题还是代理改写问题。5.2 APK安装与证书常见错误安装APK时常见的INSTALL_FAILED_TEST_ONLY、INSTALL_FAILED_NO_MATCHING_ABIS我在第二章说过处理办法这里再补充一个容易混淆的INSTALL_FAILED_VERSION_DOWNGRADE。这个不是所有模拟器都会报和系统设置有关。如果系统禁用了降级安装加-d参数也可能不生效最稳妥还是先卸载旧版本。证书相关的问题里最常见的是明明装了证书抓包还是显示证书错误。这时候先去模拟器的“加密与凭据”里看证书是否真的出现在“用户证书”列表中。有些浏览器下载的crt文件默认会被识别成媒体文件需要使用“设置 - 安全 - 从存储设备安装证书”的路径手动选择文件而不是直接点击下载的crt。MuMu的Android版本不同菜单名称可能略有差异大致路径是类似的。另一个证书问题是模拟器时间不准确证书有效期校验会直接失败。模拟器经常因为快照恢复导致系统时间漂移抓包前先在模拟器设置里把日期时间改成自动同步能避免很多莫名其妙的证书信任问题。5.3 常用ADB命令速查表下面列一份常用的ADB命令几乎覆盖了日常调试的80%操作。功能命令查看已连接设备adb devices连接模拟器adb connect 127.0.0.1:7555断开设备adb disconnect重启adbadb kill-server adb start-server安装APKadb install -r xxx.apk允许测试包adb install -t xxx.apk降级安装adb install -d -r xxx.apk卸载Appadb uninstall 包名列出所有包名adb shell pm list packages查看当前Activityadb shell dumpsys activity top模拟点击adb shell input tap x y模拟滑动adb shell input swipe x1 y1 x2 y2截图adb exec-out screencap -p screen.png推送文件adb push 本地路径 设备路径拉取文件adb pull 设备路径 本地路径设置代理adb shell settings put global http_proxy ip:port清除代理adb shell settings put global http_proxy :0开启rootadb rootremount系统分区adb remount这张表值得收藏。尤其是设置和清除代理这两条命令在调试网络问题时几乎每天都会用到。5.4 让抓包数据更清晰的几条经验最后聊几个提升效率的经验。第一个是善用Charles的SSL Proxying设置。默认情况下Charles不会解密所有SSL请求需要到Proxy - SSL Proxying Settings里勾选Enable SSL Proxying并把需要解密的域名加进去。如果想省事可以直接填*表示解密所有域名但这样会消耗更多资源也会看到大量无关的加密流量。建议在定位问题前先明确目标域名减少干扰。第二个是区分不同App的请求域。很多App虽然界面不同底层用的都是同一家统计SDK或广告SDK抓包时会发现来自不同应用的大量相同域名请求。看到这种请求不要慌这不是bug而是SDK共用导致的。要想只看某个App的请求尽可能在启动该App前先清空Charles的会话记录或者用模拟器的多开功能让不同测试场景分开。第三个是配合ADB命令做流量筛选。用adb shell settings put global http_proxy设置代理后如果发现某个App不走代理可以用adb shell dumpsys package 包名查看App进程中是否有显式的代理绕过逻辑。再用Wireshark走tcpdump抓本机流量作为兜底方案可以判断流量到底是不是没走系统代理。第四个是抓包修改请求内容的技巧。Charles和Fiddler都支持断点模式。打开断点后请求会停在工具里你可以先看原始内容再手动修改请求头或请求体后放行。我在排查接口传参错误时经常用这个功能验证后端对异常的响应方式能快速定位是客户端还是服务端的问题。做Android调试和抓包这条路我走过不少弯路。最早用模拟器装APK总以为下载个APK直接拖进模拟器就行直到遇到签名冲突和架构不匹配才意识到ADB这套命令行工具才是真正兜底的手段。后来做HTTPS抓包又被Android 7以上的证书机制折磨了好几天最后靠MuMu的root权限把证书变成系统证书才彻底解决。现在回头看真正值钱的其实是一套完整清晰的流程和排查思路先确保ADB连接稳定再解决APK安装再配置代理和证书最后才是分析数据。最后一个技巧抓包环境尽量保持干净代理和证书用完就清理别让测试环境反过来影响你对真实线上行为的判断。这些经验如果对你有帮助那就是这篇文章最有意义的地方。
返回列表