《吐血整理》高级系列教程-吃透Fiddler抓包教程(31)-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不通,出现网络问题。如下图所示:

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

2.宏哥没有启动Fiddler,然后启动应用某鱼APP,正常访问网络,因为不走代理的网络,Fiddler启动不启动对其没有影响,不会出现网络问题。如下图所示:

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

通过以上对比,我们确认了这款某鱼APP不走我们手机设置的代理,因此我们就不可能抓到它的包了。

3.为什么http请求没有通过wifi走代理?

为什么http请求没有通过wifi走代理呢,因为之前安卓原生使用的一些http框架都是正常走代理的啊,那是不是有可能代码中有api方法可以设置请求不走代理,于是乎就研读了一下Flutter中http相关的源码,最终找到了答案。

3.1http请求源码跟踪

http.dart中的HttpClient是一个抽象类,成员方法的具体实现在http_impl.dart中,http的get请求实现如下:

Future getUrl(Uri url) => _openUrl("get", url);

Future _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 _getConnection(String uriHost, int uriPort,

 _ProxyConfiguration proxyConf, bool isSecure) {

 Iterator proxies = proxyConf.proxies.iterator;

 Future 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变量和配置的代理信息有关。

http__impl.dart文件中的_HttpClient类中定义了_findProxy的默认值

Function _findProxy = HttpClient.findProxyFromEnvironment;

HttpClient类中findProxyFromEnvironment方法的实现

static String findProxyFromEnvironment(Uri url,

 {Map environment}) {

 HttpOverrides overrides = HttpOverrides.current;

 if (overrides == null) {

 return _HttpClient._findProxyFromEnvironment(url, environment);

 }

 return overrides.findProxyFromEnvironment(url, environment);

}

_HttpClient类中_findProxyFromEnvironment方法的实现

static String _findProxyFromEnvironment(

 Uri url, Map environment) {

 checkNoProxy(String option) {

 if (option == null) return null;

 Iterator names = option.split(",").map((s) => s.trim()).iterator;

 while (names.moveNext()) {

 var name = names.current;

 if ((name.startsWith("[") &&

 name.endsWith("]") &&

 "[${url.host}]" == name) ||

 (name.isNotEmpty && url.host.endsWith(name))) {

 return "DIRECT";

 }

 }

 return null;

 }

 checkProxy(String option) {

 if (option == null) return null;

 option = option.trim();

 if (option.isEmpty) return null;

 int pos = option.indexOf("://");

 if (pos >= 0) {

 option = option.substring(pos + 3);

 }

 pos = option.indexOf("/");

 if (pos >= 0) {

 option = option.substring(0, pos);

 }

 // Add default port if no port configured.

 if (option.indexOf("[") == 0) {

 var pos = option.lastIndexOf(":");

 if (option.indexOf("]") > pos) option = "$option:1080";

 } else {

 if (option.indexOf(":") == -1) option = "$option:1080";

 }

 return "PROXY $option";

 }

 // Default to using the process current environment.

 if (environment == null) environment = _platformEnvironmentCache;

 String proxyCfg;

 String noProxy = environment["no_proxy"];

 if (noProxy == null) noProxy = environment["NO_PROXY"];

 if ((proxyCfg = checkNoProxy(noProxy)) != null) {

 return proxyCfg;

 }

 if (url.scheme == "http") {

 String proxy = environment["http_proxy"];

 if (proxy == null) proxy = environment["HTTP_PROXY"];

 if ((proxyCfg = checkProxy(proxy)) != null) {

 return proxyCfg;

 }

 } else if (url.scheme == "https") {

 String proxy = environment["https_proxy"];

 if (proxy == null) proxy = environment["HTTPS_PROXY"];

 if ((proxyCfg = checkProxy(proxy)) != null) {

 return proxyCfg;

 }

 }

 return "DIRECT";

}

从以上代码中可以发现代理配置从environment中读取,设置代理时必须指定http_proxy或https_proxy等。而从_openUrl方法实现中proxyConf = new _ProxyConfiguration(_findProxy(uri));得出默认情况下environment是为空的,所以要想在Flutter的http请求中使用代理,则要指定相应的代理配置,即设置httpClient.findProxy的值。示例代码:

_getHttpData() async {

 var httpClient = new HttpClient();

 httpClient.findProxy = (url) {

 return HttpClient.findProxyFromEnvironment(url, environment: {"http_proxy": 'http://192.168.124.7:8888',});

 };

 var uri =

 new Uri.http('t.weather.sojson.com', '/api/weather/city/101210101');

 var request = await httpClient.getUrl(uri);

 var response = await request.close();

 if (response.statusCode == 200) {

 print('请求成功');

 var responseBody = await response.transform(Utf8Decoder()).join();

 print('responseBody = $responseBody');

 } else {

 print('请求失败');

 }

}

以上代码设置后即可使用Fiddler或Charles抓包了。

敲黑板!!!代码中已设置代理,手机wifi不再需要进行代理设置;192.168.124.7该IP为我们需要抓包的Charles所在电脑IP。

查了好多资料绝大多数是在代码中设置代理,或者是代码设置了,然后让其走手机代理,或许这对于开发很容易但是对于测试,或者别人家的APP或许就不是很容易了。下面我们看看下边的方案。

4.使用VPN

使用VPN将终端设备的流量转发到代理服务器。说的好听点就是使用VPN,难听点就是使用Drony工具强行使APP走代理。

优势:使用VPN软件不用添加其他测试。

劣势:终端上的VPN默认会直接对所有流量进行转发,要进行合理的配置可能需要额外的学习成本。

因为我们的测试对象是手机移动APP,因为我们的测试对象是手机移动APP,所以我们首先要在手机上安装一个VPN,这里使用一个十分方便的VPN软件drony (介绍在这里https://github.com/SuppSandroB/sandrop/wiki/Drony-FAQ),drony会在你的手机上创建一个VPN,将手机上的所有流量都重定向到drony自身(不是流向vpn服务器) ,这样drony就可以管理所有手机上的网络流量,甚至可以对手机上不同APP的流量进行单独配置。

4.1下载安装Drony

1.下载对应的安装包到手机上安装好,宏哥这里还是用夜神模拟器做演示,访问其下载地址:https://drony.soft112.com/ 翻不了墙的,用这个地址下载:https://www.appsapk.com/drony-1-3-155/,如下图所示:

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

2.下载安装包并安装好。安装完成后打开软件,如下图所示:

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

4.2配置drony转发

1.打开Drony(处于OFF状态),切换到SETTINGS(无法点击,试试左右滑动切换到SETTING),如下图所示:

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

2.选择Networks,点击Wi-Fi,如下图所示:

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

3.点击Wi-Fi,进入配置界面,如果是真机或者你有多个热点可以连接都可以在这里显示,这个就和我们手机连接WiFi一样。在网络列表中选择点击当前手机wifi连接的网络 (需要确保该网络与Fiddler代理服务器网络是联通的)。如下图所示:

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

4.由于宏哥这里是模拟器,因此需要宏哥编辑一下,在这界面选中那个VirtWifi(虚拟WiFi)长按,弹出Edit和Delete。如下图所示:

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

5.点击”Edit”。进入网络详情设置(Network details),如下图所示:

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

6.设置代理hosetname,默认是电脑局域网ip,也就是Fiddler安装电脑的IP,如下图所示:

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

7.设置代理Port,fiddler 默认是 8888,如下图所示:

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

8.设置 Proxy type,注意Proxy type代理方式要选择 Plain http proxy。如下图所示:

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

敲黑板!!!!最上边的Proxy type,选择代理模式为手动(Manual),如下图所示:

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

9.设置Filter default value为Direct all,如下图所示:

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

10.设置Rules,点击下面的Rule设置应用规则。如下图所示:

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

11.点击”Edit filter Rules”,。进入添加规则页面,如下图所示:

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

12.默认您的规则里应该是空的,这里直接点击上面的加号添加一个规则(符合规则要求的才会被转发),点击右上角的加号图标,如下图所示:

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

13.点击右上角的加号图标后,进入过滤规则添加界面,如下图所示:

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

(1)在Network id处 选择当前wifi的SSID

(2)Action 选择 Local proxy chain

(3)Application 选择需要强制代理的APP

(4)Hostname 及 Port 不填 表示所有的都会被强制代理,因为APP可能会使用其他的网络协议不一定都是http,可能不希望把所有流量都引流到http代理服务器,这个时候就会使用这个配置指定ip及端口才转发

14.添加好以后,点击右上角的保存图标,如下图所示:

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

15.点击”保存”后,跳转到规则界面,如下图所示:

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

16.启动Drony:返回到SETTING主页,滑动到LOG页,点击下面”OFF”按钮,

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

17.点击”确定”,使其处于ON的状态(表示启用),如下图所示:

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

4.3开启代理抓包软件

宏哥这里代理抓包软件使用的是Fiddler。Fiddler的使用这里不再介绍,需要打开远程代理,并在手机中安装Fiddler根证书。这里宏哥就不做赘述,前边都有详细的介绍

经过上面到配置,这些APP的HTTP流量我们就可以通过代理抓包软件获取,https流量也可能正常解码。

5.小结

宏哥这里只是提供一种思路供你学习和实践。 好了,今天时间也不早了,宏哥就讲解和分享到这里,感谢你耐心地阅读!!!

6.拓展

6.1如何下载google play上的apk安装包

之前一直没有从Google Play上下载过apk文件,也不知道怎么下载,带来过不便,今天下载查了一下资料,并亲自实践,发现很简单。

前提:能FQ访问Google。

共分两个步骤:

1,访问Google play

https://play.google.com/store/apps

搜索你想要的应用。

打开应用详情页,复制URL地址到步骤2。

2,访问

https://apps.evozi.com/apk-downloader/

将步骤1中的链接粘贴到这个URL中的输入框,点击按钮(蓝色)解析出下载apk的链接,再点击下载链接(绿色)就下载到你的电脑了。

Original: https://www.cnblogs.com/du-hong/p/16619657.html
Author: 北京-宏哥
Title: 《吐血整理》高级系列教程-吃透Fiddler抓包教程(31)-Fiddler如何抓取Android系统中Flutter应用程序的包

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/800008/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [selenium]等待

    selenium显式等待、隐式等待和期望条件 前言 当网络不稳定或应用页面加载有问题,可以设置等待,避免网络问题导致找不到元素等异常。 隐式等待 隐式等待设置的是最长等待时间,如果…

    Python 2023年11月2日
    037
  • python scrapy框架详解_初学者必看的scrapy框架简介

    一、安装scrapy框架pip install scrapy 二、创建一个scrapy项目 安装完成后,python会自动将 scrapy命令添加到环境变量中去,这时我们就可以使用…

    Python 2023年10月5日
    075
  • Python库安装之requirements.txt, environment.yml

    目录 1. 前言 2. requirements.txt 2.1 生成和使用命令 2.2 内容 3. environment.yml 3.1 常见问题 4. 总结 4.1 yml …

    Python 2023年8月2日
    063
  • 双系统配置ubuntu22.04以及深度学习环境配置

    为了学习计算机视觉,特意安装了ubuntu22.04(原来是win11),简单记录自己的一个过程,毕竟也是重装好几次系统的人了… 在完成ubuntu22.04的安装后,…

    Python 2023年9月9日
    042
  • 基于PyTorch的YOLOv5介绍

    在PyTorch中使用YOLOv5YOLO是 “You only look once “的首字母缩写,是一个开源软件工具,它具有实时检测特定图像中物体的高效…

    Python 2023年10月29日
    043
  • 爬虫日记(14):scrapy的命令行工具

    由于编写爬虫,一般情况下不会从头写一个,因为那样做效率低下,需要重复地写相同的内容,并且还容易出错,所以scrapy提供了一个快速开发的环境,就是通过命令行就可以生成一个爬虫的框架…

    Python 2023年10月6日
    040
  • 数据分析 第四周 (pandas 一维 series 和 二维 DaTaFrame)笔记

    为什么要用pandas? numpy 虽然有强大的功能 , 但是只能处理数值数据 而 pandas 就很好的解决了这个问题 pandas 一维 Serier 类似于 C++ 中的 …

    Python 2023年8月21日
    059
  • Python实例:小游戏20148

    本节教程通过 2048 的小游戏快速、完整地呈现了使用 Python 语言编程的过程,将之前介绍的内容有机地结合在了一起 。2048是一款流行于手机、平板等终端设备上的益智小游戏,…

    Python 2023年9月25日
    049
  • python通过指定excel模板导出_Python(openpyxl):将数据从一个excel文件放到另一个(模板文件),并用另一个名称保存,同时保留temp…

    实际上不需要使用shutil模块,因为您可以使用openpyxl.load_工作簿加载模板,然后用其他名称保存。在 此外,for循环中的ws.append(r)将附加到现有的数据中…

    Python 2023年8月19日
    042
  • matlab机械臂建模运动学仿真+轨迹规划

    Matlab机械臂仿真 1.内容参考B站视频:https://www.bilibili.com/video/BV1q44y1x7WC?spm_id_from=333.337.sea…

    Python 2023年9月15日
    049
  • 情感计算——多模态情感识别

    一、 背景和意义 情感是通过多种模态的形式进行表达的 情感涉及主观经历、生理反应和行为反应; 每个人都有自己的主观感受,身体会出现一系列的生理反应,并且通过表情、言语和肢体动作等行…

    Python 2023年10月7日
    072
  • DAY10需求分析

    pane pro需求的描述 存在四个对象:我方飞机、敌方飞机、我方子弹、敌方子弹 功能: 背景音乐的添加我方飞机可以移动【根据按键来控制的】敌方飞机也可以移动【随机的自我移动】 双…

    Python 2023年9月25日
    038
  • web前端期末大作业【足球网页】学生网页设计作业源码

    🎉精彩专栏推荐 💭文末获取联系✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主💂 作者主页: 【主页——🚀获取更多优质源码】🎓 web前端期末大作业: 【📚毕设项目精品实战…

    Python 2023年10月8日
    068
  • 方法的多种调用方式

    方法调用确实我们每个人都会,但是我觉得大家可能用的最多的就是那种常规的方式,这里呢,我要记录一下另外几种方式 1 from operator import attrgetter 2…

    Python 2023年10月31日
    052
  • Yolov3算法详解

    在本文开题处我们就说过,Yolo系列算法时一种典型的”一阶段”目标检测算法,这是Yolo最为出彩的设计,一次性即可完成对目标的定位和识别——这是RCNN等其…

    Python 2023年6月12日
    075
  • NumPy遍历数组

    NumPy 提供了一个 nditer 迭代器对象,它可以配合 for 循环完成对数组元素的遍历。 下面看一组示例,使用 arange() 函数创建一个 3*4 数组,并使用 ndi…

    Python 2023年8月24日
    042
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球