如何在Genymotion/Android模拟器中嗅探非HTTP(Socket)流量?
在Genymotion/Android模拟器中嗅探Socket类非HTTP流量的可行方案
我来分享几个我在逆向Android非HTTP(比如Socket、XMPP)流量时常用的方案,完全适配Genymotion的x86架构场景:
一、底层抓包:tcpdump + Wireshark(最通用)
这个方法直接抓取模拟器的所有网络数据包,不管什么协议都能捕获,适合需要完整分析流量链路的场景:
- 步骤1:给模拟器安装x86版tcpdump
下载对应x86架构的tcpdump二进制文件,通过adb推送到模拟器:adb push tcpdump-x86 /data/local/tmp/ adb shell chmod 755 /data/local/tmp/tcpdump - 步骤2:启动抓包
进入模拟器shell,执行抓包命令(保存到SD卡方便导出):
其中adb shell /data/local/tmp/tcpdump -i any -w /sdcard/socket_traffic.pcap-i any表示抓取所有网络接口的流量,-w指定保存路径。 - 步骤3:导出并分析数据包
抓完需要的流量后(按Ctrl+C停止),把pcap文件拉到本地:
用Wireshark打开文件,你可以通过协议过滤(比如输入adb pull /sdcard/socket_traffic.pcap ~/Desktop/xmpp过滤XMPP流量)、端口过滤(比如tcp port 5222)或者IP过滤(比如ip.addr == 192.168.xxx.xxx)快速定位目标流量。
二、应用层Hook:Frida拦截Socket收发数据
如果需要直接查看应用层的明文数据(哪怕是Socket传输的),Frida Hook是更高效的选择,不用处理底层数据包的解析:
- 步骤1:准备Frida环境
下载对应x86架构的Frida Server,推送到模拟器并启动:adb push frida-server-x86 /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frida-server-x86 adb shell /data/local/tmp/frida-server-x86 & - 步骤2:编写Hook脚本
新建一个socket_hook.js文件,Hook Socket的连接、发送、接收方法:Java.perform(function() { // Hook Socket连接方法 var Socket = Java.use("java.net.Socket"); Socket.connect.overload("java.net.SocketAddress").implementation = function(addr) { console.log("[+] Socket连接到: " + addr.toString()); return this.connect(addr); }; // Hook OutputStream发送数据 var OutputStream = Java.use("java.io.OutputStream"); OutputStream.write.overload("[B").implementation = function(buffer) { try { console.log("[SEND] 数据: " + new TextDecoder().decode(buffer)); } catch (e) { console.log("[SEND] 二进制数据,长度: " + buffer.length); } return this.write(buffer); }; // Hook InputStream接收数据 var InputStream = Java.use("java.io.InputStream"); InputStream.read.overload("[B").implementation = function(buffer) { var readLen = this.read(buffer); if (readLen > 0) { try { console.log("[RECV] 数据: " + new TextDecoder().decode(buffer.slice(0, readLen))); } catch (e) { console.log("[RECV] 二进制数据,长度: " + readLen); } } return readLen; }; }); - 步骤3:运行脚本拦截流量
替换目标应用的包名,执行命令:
启动应用后,所有Socket的收发数据会实时打印在控制台。frida -U -f com.your.target.app -l socket_hook.js --no-pause
三、全局流量转发:通过iptables + SOCKS代理
如果需要把模拟器的所有Socket流量转发到主机的代理工具(比如Wireshark、Proxifier),可以用iptables实现:
- 步骤1:在主机启动SOCKS代理
可以用SSH临时开启一个SOCKS5代理:
或者用专门的代理工具(比如Shadowsocks、Squid)。ssh -D 1080 localhost - 步骤2:在模拟器配置iptables转发
进入模拟器shell,先找到主机的IP(一般是Genymotion的网关,比如192.168.56.1),然后执行:
之后模拟器的所有TCP流量都会转发到主机的SOCKS代理,你可以在主机用Wireshark抓对应端口的流量。# 安装redsocks(如果模拟器没有的话,需要先刷入带busybox的镜像或者手动安装) iptables -t nat -N REDSOCKS iptables -t nat -A REDSOCKS -d 0.0.0.0/0 -p tcp -j REDIRECT --to-ports 12345 # 配置redsocks指向主机的SOCKS代理 echo 'base { log_debug = off; log_info = off; redirector = iptables; } redsocks { local_ip = 0.0.0.0; local_port = 12345; ip = 192.168.56.1; port = 1080; type = socks5; }' > /data/local/tmp/redsocks.conf redsocks -c /data/local/tmp/redsocks.conf & # 把所有TCP流量转到redsocks iptables -t nat -A OUTPUT -p tcp -j REDSOCKS
额外注意事项
- 如果目标流量是加密的(比如XMPP over TLS),tcpdump抓到的是加密数据,这时候可以结合Frida Hook
SSLSocket的getInputStream/getOutputStream方法,直接获取明文;或者导出应用的SSL证书,导入Wireshark进行解密。 - Genymotion的x86架构一定要用对应版本的工具(tcpdump、Frida Server、redsocks都要x86版),否则会出现运行崩溃或无法执行的问题。
- 之前用Drony崩溃的话,可以试试换Android 7.0/8.0的x86镜像,新版本Android可能和Drony兼容性不好。
内容的提问来源于stack exchange,提问作者Gintas_
相关产品推荐
相关产品推荐

