31 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android系统中Flutter应用程序的包

1.简介Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面 。Flutter应用程序是用Dart编写的,这是一种由Google在7年多前创建的语言 。Flutter是Google使用Dart语言开发的移动应用开发框架,使用一套Dart代码就能快速构建高性能、高保真的iOS和Android应用程序 。
HTTP应用层的抓包已经成为日常工作测试与调试中的重要一环,最近接触新项目突然之间发现之前的抓包手段都不好使了 , 顿时模块与模块之间的前端与服务之间的交互都变成了不可见,整个人都好像被蒙住了眼睛 。
2.验证是否走代理Flutter 应用的网络请求是不走手机的系统代理的,也就是说你在系统设置中设置了代理地址和端口号后 Flutter 也不会走你的代理,而抓包是必须要设置代理的,然后走代理我们才可以成功的抓到包,现在人家都不从你这里走 , 累死你都抓不到 。
方法一:首先我们使用正常的抓包流程:通过fiddler进行抓包,可以看到,只抓到一些图片和一些没有用处的乱七八糟的文件,那么很有可能他不走代理 。
还有一种方法可以判断APP是否为无代理请求模式:以fiddler为例,当我们配置好fiddler证书、模拟器wifi配置好ip和端口后,客户端关闭fiddler抓包工具,如果该APP还可以正常运行说明请求为无代理模式 。
宏哥查了一下现在使用Flutter的应用程序,发现好多程序都用它 , 宏哥就选择了某鱼这一款APP 。
按照之前的宏哥配置,模拟器配置了代理而且这个代理是走Fiddler的,如果宏哥没有启动Fiddler如果是走代理的应用程序,就会出现网络问题,如果是不走代理的应用程序,就可以正常访问网络 。具体操作步骤如下:
1.宏哥没有启动Fiddler,然后用浏览器访问百度,出现网络问题,因为代理的网络走到Fiddler这里 , Fiddler不通,出现网络问题 。如下图所示:

31 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android系统中Flutter应用程序的包

文章插图
2.宏哥没有启动Fiddler,然后启动应用某鱼APP , 正常访问网络,因为不走代理的网络,Fiddler启动不启动对其没有影响,不会出现网络问题 。如下图所示:
31 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android系统中Flutter应用程序的包

文章插图
通过以上对比 , 我们确认了这款某鱼APP不走我们手机设置的代理,因此我们就不可能抓到它的包了 。
3.为什么http请求没有通过wifi走代理?为什么http请求没有通过wifi走代理呢,因为之前安卓原生使用的一些http框架都是正常走代理的?。鞘遣皇怯锌赡艽胫杏衋pi方法可以设置请求不走代理 , 于是乎就研读了一下Flutter中http相关的源码,最终找到了答案 。
3.1http请求源码跟踪http.dart中的HttpClient是一个抽象类,成员方法的具体实现在http_impl.dart中,http的get请求实现如下:
Future<HttpClientRequest> getUrl(Uri url) => _openUrl("get", url);Future<_HttpClientRequest> _openUrl(String method, Uri uri) { . . . // Check to see if a proxy server should be used for this connection. var proxyConf = const _ProxyConfiguration.direct(); if (_findProxy != null) { // TODO(sgjesse): Keep a map of these as normally only a few // configuration strings will be used. try { proxyConf = new _ProxyConfiguration(_findProxy(uri)); } catch (error, stackTrace) { return new Future.error(error, stackTrace); } } return _getConnection(uri.host, port, proxyConf, isSecure) .then((_ConnectionInfo info) { . . . });}首先,我们可以发现方法中有一行注释// Check to see if a proxy server should be used for this connection.,意思是“检查是否应该使用代理服务器进行此连接”;
然后,有一个proxyConf对象初始化和根据_findProxy来创建新的proxyConf对象的语句,然后通过_getConnection(uri.host, port, proxyConf, isSecure)来创建连接 , _getConnection的源码如下:
Future<_ConnectionInfo> _getConnection(String uriHost, int uriPort, _ProxyConfiguration proxyConf, bool isSecure) { Iterator<_Proxy> proxies = proxyConf.proxies.iterator; Future<_ConnectionInfo> connect(error) { if (!proxies.moveNext()) return new Future.error(error); _Proxy proxy = proxies.current; String host = proxy.isDirect ? uriHost : proxy.host; int port = proxy.isDirect ? uriPort : proxy.port; return _getConnectionTarget(host, port, isSecure) .connect(uriHost, uriPort, proxy, this) // On error, continue with next proxy. .catchError(connect); } return connect(new HttpException("No proxies given"));}从代码中我们可以看到根据代理配置信息来将请求的host和port进行重置,然后创建真实的连接 。
跟踪以上源码我们发现dart中http请求是否走代理是需要配置的,而_findProxy变量和配置的代理信息有关 。

推荐阅读