自己动手写网络抓包工具
- 格式:doc
- 大小:39.00 KB
- 文档页数:17
Wireshark图解教程(简介、抓包、过滤器)配置Wireshark是世界上最流行的网络分析工具。
这个强大的工具可以捕捉网络中的数据,并为用户提供关于网络和上层协议的各种信息。
与很多其他网络工具一样,Wireshark也使用pcap network library来进行封包捕捉。
可破解局域网内QQ、邮箱、msn、账号等的密码!!Wireshark是世界上最流行的网络分析工具。
这个强大的工具可以捕捉网络中的数据,并为用户提供关于网络和上层协议的各种信息。
与很多其他网络工具一样,Wireshark也使用pcap network library来进行封包捕捉。
可破解局域网内QQ、邮箱、msn、账号等的密码!!wireshark的原名是Ethereal,新名字是2006年起用的。
当时Ethereal的主要开发者决定离开他原来供职的公司,并继续开发这个软件。
但由于Ethereal这个名称的使用权已经被原来那个公司注册,Wireshark这个新名字也就应运而生了。
在成功运行Wireshark之后,我们就可以进入下一步,更进一步了解这个强大的工具。
下面是一张地址为192.168.1.2的计算机正在访问“”网站时的截图。
1.MENUS(菜单)2.SHORTCUTS(快捷方式)3.DISPLAY FILTER(显示过滤器)4.PACKET LIST PANE(封包列表)5.PACKET DETAILS PANE(封包详细信息)6.DISSECTOR PANE(16进制数据)7.MISCELLANOUS(杂项)1.MENUS(菜单)程序上方的8个菜单项用于对Wireshark进行配置:-"File"(文件)-"Edit"(编辑)-"View"(查看)-"Go"(转到)-"Capture"(捕获)-"Analyze"(分析)-"Statistics"(统计)-"Help"(帮助)打开或保存捕获的信息。
wireshark抓包分析2篇第一篇:Wireshark抓包分析HTTP协议Wireshark是一款网络分析工具,可用于抓取网络传输过程中的数据包,方便分析瓶颈和故障。
本文将以抓取HTTP协议为例,演示Wireshark的使用方法,并分析数据包内容。
1. 抓取HTTP协议数据包启动Wireshark,选择网络接口和捕获过滤器。
为了抓取HTTP协议的数据包,可以输入"tcp port 80"作为过滤器,表示只抓取端口为80的TCP数据包,即HTTP协议的数据包。
2. 分析HTTP协议数据包抓取到的HTTP协议数据包可通过Wireshark的命令行界面或图形界面进行分析,下面分别介绍。
(1) 命令行界面在Wireshark的命令行界面中,可以查看每个数据包的详细信息,并按需提取关键信息。
例如,输入"frame.number"命令可显示数据包编号,输入"ip.src"命令可显示源IP地址,输入"http.request.full_uri"命令可显示请求的URL地址等。
(2) 图形界面在Wireshark的图形界面中,可以以树形结构或表格形式查看每个数据包的详细信息。
在HTTP协议的数据包中,关键信息如下:- HTTP Request:包括请求方法(GET/POST等)、请求头、请求正文等。
- HTTP Response:包括状态码、响应头、响应正文等。
- 源IP地址和目的IP地址:代表客户端和服务器的IP 地址。
- 源端口号和目的端口号:代表客户端和服务器的TCP 端口号。
通过分析HTTP协议数据包,可以查看请求和响应信息,了解应用程序和服务器的交互过程。
也可以检查请求/响应是否存在异常,例如请求头或响应正文长度异常、响应状态码为4xx或5xx等。
本文仅介绍了抓取和分析HTTP协议数据包的基本方法,Wireshark还可以用于分析其他协议的数据包,例如TCP、DHCP、DNS等。
易语⾔制作⽹截抓包⼯具的代码常量数据表.版本 2.常量编码常量, "<⽂本长度: 10797>", , 名称:编码_GB2312 英⽂名称:Encoding_GB2312 类型:⽂本型值:“GB2312” 列举各种编码类型全局变量表.版本 2.全局变量系统配置路径, ⽂本型⽹截抓包⼯具.版本 2.⽀持库 eNetIntercept.⽀持库 eGrid.⽀持库 iconv.⽀持库 iext.⽀持库 iext2.程序集主程序集.程序集变量服务安装, ⽹络服务安装.程序集变量临时句柄⽂件路径, ⽂本型.程序集变量临时进程⽂件路径, ⽂本型.⼦程序 __启动窗⼝_创建完毕初始化 ().⼦程序初始化.局部变量⽂本组, ⽂本型, , "0".局部变量临时整数变量, 整数型.局部变量加⼊位置, 整数型.局部变量取出值, ⽂本型.如果真 (服务安装.是否已安装 () =假).如果 (信息框 (“服务没有安装,是否现在安装?”, #询问图标+ #取消钮, “初始化”) = #确认钮).如果真 (⽂件是否存在 (取运⾏⽬录 () + “\ESPI11.dll”) =假).如果真 (写到⽂件 (取运⾏⽬录 () + “\ESPI11.dll”, #安装⽂件) =假)信息框 (“写出⽂件错误!”, #错误图标, “初始化”)结束 ().如果真结束.如果真结束.如果 (服务安装.安装 (取运⾏⽬录 () + “\ESPI11.dll”) =假)信息框 (“服务安装失败!”, #错误图标, “初始化”)结束 ().否则信息框 (“服务安装成功!”, #信息图标, “初始化”).如果结束.否则结束 ().如果结束.如果真结束临时句柄⽂件路径=取运⾏⽬录 () + “\” + “Ws_sock.dep”删除⽂件 (临时句柄⽂件路径)临时进程⽂件路径=取运⾏⽬录 () + “\” + “Ws_jinchen.dep”删除⽂件 (临时进程⽂件路径)⾼级表格.列数= 9⾼级表格.⾏数= 1⾼级表格.置数据 (0, 0, #表格常量.⽂本型, “PID”)⾼级表格.置数据 (0, 1, #表格常量.⽂本型, “进程名”)⾼级表格.置数据 (0, 2, #表格常量.⽂本型, “进程路径”)⾼级表格.置数据 (0, 3, #表格常量.⽂本型, “转IP”)⾼级表格.置数据 (0, 4, #表格常量.⽂本型, “转端⼝”)⾼级表格.置数据 (0, 5, #表格常量.⽂本型, “清空发送”)⾼级表格.置数据 (0, 6, #表格常量.⽂本型, “清空接收”)⾼级表格.置数据 (0, 7, #表格常量.⽂本型, “过滤1”)⾼级表格.置数据 (0, 8, #表格常量.⽂本型, “过滤2”)⾼级表格.置列类型 (5, #表格常量.选择型)⾼级表格.置列类型 (6, #表格常量.选择型)⾼级表格.置列类型 (7, #表格常量.选择型)⾼级表格.置列类型 (8, #表格常量.选择型)⾼级表格.置对齐⽅式 (0, 0, , 8, #表格常量.居中对齐)⽂本组=分割⽂本 (#编码常量, #换⾏符, ).计次循环⾸ (取数组成员数 (⽂本组), 临时整数变量).如果真 (寻找⽂本 (⽂本组 [临时整数变量], #左引号, , 假) ≠ -1)取出值=取⽂本之间 (⽂本组 [临时整数变量], #左引号, #右引号)加⼊位置=源编码组合框.加⼊项⽬ (取出值, ).如果真 (取出值= #编码_UTF_8)源编码组合框.现⾏选中项=加⼊位置.如果真结束加⼊位置=⽬编码组合框.加⼊项⽬ (取出值, ).如果真 (取出值= #编码_GB2312)⽬编码组合框.现⾏选中项=加⼊位置.如果真结束.如果真结束.计次循环尾 ()_启动窗⼝.宽度= 800_启动窗⼝.⾼度= 600__启动窗⼝_尺⼨被改变 ().⼦程序调整列宽.局部变量临时整数变量, 整数型.局部变量单格⼤⼩, 整数型单格⼤⼩=⾼级表格.宽度 ÷ 100.计次循环⾸ (9, 临时整数变量)⾼级表格.置列宽 (临时整数变量- 1, 多项选择 (临时整数变量, 单格⼤⼩ × 8, 单格⼤⼩ × 13, 单格⼤⼩ × 18, 单格⼤⼩ × 16, 单格⼤⼩ × 8, 单格⼤⼩ × 10, 单格⼤⼩ × 10, 单格⼤⼩ × 8, 单格⼤⼩ × 8)) .计次循环尾 ()发送数据列表框.置列宽 (6, 发送数据列表框.宽度- 500).⼦程序 __启动窗⼝_可否被关闭, 逻辑型⽹截.关闭 ().⼦程序 __启动窗⼝_尺⼨被改变.如果真 (_启动窗⼝.宽度< 800)_启动窗⼝.宽度= 800.如果真结束.如果真 (_启动窗⼝.⾼度< 600)_启动窗⼝.⾼度= 600.如果真结束数据分组框.宽度= _启动窗⼝.宽度- 12发送数据列表框.宽度=数据分组框.宽度- 15数据分组框.⾼度= _启动窗⼝.⾼度-过滤分组框.⾼度-详细分组框.⾼度- 95发送数据列表框.⾼度=数据分组框.⾼度- 25过滤分组框.顶边=数据分组框.顶边+数据分组框.⾼度详细分组框.顶边=过滤分组框.顶边+过滤分组框.⾼度详细分组框.宽度=数据分组框.宽度-全局分组框.宽度- 1过滤分组框.宽度=数据分组框.宽度⾼级表格.宽度=过滤分组框.宽度- 10编码转换编辑框.宽度=详细分组框.宽度 ÷ 2 - 7原始数据标签.左边=详细分组框.宽度- 5 -编码转换编辑框.宽度原始数据编辑框.左边=原始数据标签.左边原始数据编辑框.宽度=编码转换编辑框.宽度全局分组框.顶边=详细分组框.顶边全局分组框.左边=详细分组框.宽度+ 1调整列宽 ().⼦程序 _发送数据列表框_当前表项被改变.局部变量转换前, 字节集.局部变量转换后, 字节集转换前=到字节集 (发送数据列表框.取标题 (发送数据列表框.现⾏选中项, 6))原始数据编辑框.内容=发送数据列表框.取标题 (发送数据列表框.现⾏选中项, 6)转换后=编码转换 (转换前, 源编码组合框.取项⽬⽂本 (源编码组合框.现⾏选中项), ⽬编码组合框.取项⽬⽂本 (⽬编码组合框.现⾏选中项), )编码转换编辑框.内容=彗星URL解码 (到⽂本 (转换后)).⼦程序 _⼯具条_被单击.参数按钮索引, 整数型.判断开始 (按钮索引= 0).如果真 (⽹截.打开 () =假)信息框 (“启动失败!”, #错误图标, )返回 ().如果真结束⼯具条.加⼊状态 (0, #按下)⼯具条.去除状态 (2, #按下).判断 (按钮索引= 2).如果真 (⽹截.关闭 () =假)信息框 (“停⽌失败!”, #错误图标, )返回 ().如果真结束⼯具条.加⼊状态 (2, #按下)⼯具条.去除状态 (0, #按下).判断 (按钮索引= 4)发送数据列表框.全部删除 ().判断 (按钮索引= 6).判断 (按钮索引= 8).默认.判断结束.⼦程序 _⽹截_调绑定, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹址, ⽹址信息, 参考.局部变量 IP段1, 字节型.局部变量 IP段2, 字节型.局部变量 IP段3, 字节型.局部变量 IP段4, 字节型.局部变量端⼝号, 整数型⽹址.取IP端⼝ (IP段1, IP段2, IP段3, IP段4, 端⼝号)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “bdip”, 到⽂本 (IP段1) + “.” +到⽂本 (IP段2) + “.” +到⽂本 (IP段3) + “.” +到⽂本 (IP段4))写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “bddk”, 到⽂本 (端⼝号))返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调侦听, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数等待队列长度, 整数型, 参考返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调连接, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹址, ⽹址信息, 参考.局部变量 IP段1, 字节型.局部变量 IP段2, 字节型.局部变量 IP段3, 字节型.局部变量 IP段4, 字节型.局部变量端⼝号, 整数型.局部变量全_IP, ⽂本型.局部变量 IP段组, ⽂本型, , "0".局部变量新端⼝号, 整数型⽹址.取IP端⼝ (IP段1, IP段2, IP段3, IP段4, 端⼝号)全_IP =到⽂本 (IP段1) + “.” +到⽂本 (IP段2) + “.” +到⽂本 (IP段3) + “.” +到⽂本 (IP段4).如果真 (转IP选择框.选中=真)IP段组=分割⽂本 (IP编辑框.地址, “.”, ).如果真 (取数组成员数 (IP段组) ≠ 4)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (转端⼝选择框.选中=真)新端⼝号=到整数 (端⼝编辑框.内容).如果真结束.如果真 (取数组成员数 (IP段组) = 4 且新端⼝号 ≠ 0)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, “全转-” +到⽂本 (IP段组 [1]) + “.” +到⽂本 (IP段组 [2]) + “.” +到⽂本 (IP段组 [3]) + “.” +到⽂本 (IP段组 [4]))写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, “全转-” +到⽂本 (新端⼝号))⽹址.置IP端⼝ (到字节 (IP段组 [1]), 到字节 (IP段组 [2]), 到字节 (IP段组 [3]), 到字节 (IP段组 [4]), 新端⼝号)返回 (#拦截操作.更改调⽤).如果真结束.如果真 (取数组成员数 (IP段组) = 4)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, “全转-” +到⽂本 (IP段组 [1]) + “.” +到⽂本 (IP段组 [2]) + “.” +到⽂本 (IP段组 [3]) + “.” +到⽂本 (IP段组 [4]))写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, 到⽂本 (端⼝号))⽹址.置IP端⼝ (到字节 (IP段组 [1]), 到字节 (IP段组 [2]), 到字节 (IP段组 [3]), 到字节 (IP段组 [4]), 端⼝号)返回 (#拦截操作.更改调⽤).如果真结束.如果真 (新端⼝号 ≠ 0)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, 到⽂本 (IP段1) + “.” +到⽂本 (IP段2) + “.” +到⽂本 (IP段3) + “.” +到⽂本 (IP段4))写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, “全转-” +到⽂本 (新端⼝号))⽹址.置IP端⼝ (IP段1, IP段2, IP段3, IP段4, 新端⼝号)返回 (#拦截操作.更改调⽤).如果真结束.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “ip”, ) ≠ “”)IP段组=分割⽂本 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “ip”, ), “.”, ).如果真 (取数组成员数 (IP段组) ≠ 4)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “port”, ) ≠ “”)新端⼝号=到整数 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “port”, )).如果真结束.如果真 (取数组成员数 (IP段组) = 4 且新端⼝号 ≠ 0)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, “单转-” +到⽂本 (IP段组 [1]) + “.” +到⽂本 (IP段组 [2]) + “.” +到⽂本 (IP段组 [3]) + “.” +到⽂本 (IP段组 [4]))写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, “单转-” +到⽂本 (新端⼝号))⽹址.置IP端⼝ (到字节 (IP段组 [1]), 到字节 (IP段组 [2]), 到字节 (IP段组 [3]), 到字节 (IP段组 [4]), 新端⼝号)返回 (#拦截操作.更改调⽤).如果真结束.如果真 (取数组成员数 (IP段组) = 4)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, “单转-” +到⽂本 (IP段组 [1]) + “.” +到⽂本 (IP段组 [2]) + “.” +到⽂本 (IP段组 [3]) + “.” +到⽂本 (IP段组 [4]))写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, 到⽂本 (端⼝号))⽹址.置IP端⼝ (到字节 (IP段组 [1]), 到字节 (IP段组 [2]), 到字节 (IP段组 [3]), 到字节 (IP段组 [4]), 端⼝号)返回 (#拦截操作.更改调⽤).如果真结束.如果真 (新端⼝号 ≠ 0)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, 全_IP)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, “单转-” +到⽂本 (新端⼝号))⽹址.置IP端⼝ (IP段1, IP段2, IP段3, IP段4, 新端⼝号)返回 (#拦截操作.更改调⽤).如果真结束写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, 全_IP)写配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, 到⽂本 (端⼝号))返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调发送, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹络数据, ⽹络数据, 参考.参数调⽤⽅式, 整数型, 参考.局部变量表项索引, 整数型.局部变量数据内容, 字节型.局部变量⽂本数据, ⽂本型.如果真 (清空发送选择框.选中=真) ' 全局过滤⽂本数据=⽹络数据.到⽂本 ()表项索引=发送数据列表框.插⼊表项 (, , , , , )发送数据列表框.置标题 (表项索引, 0, “↑”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, “数据被清空”)⽹络数据.释放 ()返回 (#拦截操作.更改调⽤).如果真结束.如果真 (读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ) = “”) ' 过滤IP为空的数据局返回 (#拦截操作.默认调⽤).如果真结束.如果真 (暂停过滤选择框.选中=真) ' 全局暂停过滤⽂本数据=⽹络数据.到⽂本 ()表项索引=发送数据列表框.插⼊表项 (, , , , , )发送数据列表框.置标题 (表项索引, 0, “↑”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, ⽂本数据)返回 (#拦截操作.默认调⽤).如果真结束⽂本数据=⽹络数据.到⽂本 ().如果真 (过滤1选择框.选中=真) ' 全局过滤.如果真 (⽹络数据.取长度 () ≤ 1)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (过滤2选择框.选中=真).如果真 (到⼤写 (取⽂本左边 (⽂本数据, 3)) ≠ “GET” 且到⼤写 (取⽂本左边 (⽂本数据, 4)) ≠ “POST”)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (读配置项 (临时句柄⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “fs”, ) = “真”) ' 单进程过滤⽂本数据=⽹络数据.到⽂本 ()表项索引=发送数据列表框.插⼊表项 (, , , , , )发送数据列表框.置标题 (表项索引, 0, “↑”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, “数据被清空”)⽹络数据.释放 ().如果真结束.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “1”, ) = “真”).如果真 (⽹络数据.取长度 () ≤ 1)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “2”, ) = “真”).如果真 (到⼤写 (取⽂本左边 (⽂本数据, 3)) ≠ “GET” 且到⼤写 (取⽂本左边 (⽂本数据, 4)) ≠ “POST”)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束表项索引=发送数据列表框.插⼊表项 (, , , , , ) ' 所有过滤关闭发送数据列表框.置标题 (表项索引, 0, “↑”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, ⽂本数据)返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调接收, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹络数据, ⽹络数据, 参考.参数调⽤⽅式, 整数型, 参考.局部变量表项索引, 整数型.局部变量数据内容, 字节型.局部变量⽂本数据, ⽂本型.如果真 (清空接收选择框.选中=真) ' 全局过滤⽂本数据=⽹络数据.到⽂本 ()表项索引=发送数据列表框.插⼊表项 (, , , , , )发送数据列表框.置标题 (表项索引, 0, “↓”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, “数据被清空”)⽹络数据.释放 ()返回 (#拦截操作.更改调⽤).如果真结束.如果真 (读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ) = “”) ' 过滤IP为空的数据局返回 (#拦截操作.默认调⽤).如果真结束.如果真 (暂停过滤选择框.选中=真) ' 全局暂停过滤⽂本数据=⽹络数据.到⽂本 ()表项索引=发送数据列表框.插⼊表项 (, , , , , )发送数据列表框.置标题 (表项索引, 0, “↓”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, ⽂本数据)返回 (#拦截操作.默认调⽤).如果真结束⽂本数据=⽹络数据.到⽂本 ().如果真 (过滤1选择框.选中=真) ' 全局过滤.如果真 (⽹络数据.取长度 () ≤ 1)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (过滤2选择框.选中=真).如果真 (到⼤写 (取⽂本左边 (⽂本数据, 3)) ≠ “GET” 且到⼤写 (取⽂本左边 (⽂本数据, 4)) ≠ “POST”)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (读配置项 (临时句柄⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “js”, ) = “真”) ' 单进程过滤⽂本数据=⽹络数据.到⽂本 ()表项索引=发送数据列表框.插⼊表项 (, , , , , )发送数据列表框.置标题 (表项索引, 0, “↓”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, “数据被清空”)⽹络数据.释放 ()返回 (#拦截操作.更改调⽤).如果真结束.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “1”, ) = “真”).如果真 (⽹络数据.取长度 () ≤ 1)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “2”, ) = “真”).如果真 (到⼤写 (取⽂本左边 (⽂本数据, 3)) ≠ “GET” 且到⼤写 (取⽂本左边 (⽂本数据, 4)) ≠ “POST”)返回 (#拦截操作.默认调⽤).如果真结束.如果真结束表项索引=发送数据列表框.插⼊表项 (, , , , , ) ' 所有过滤关闭发送数据列表框.置标题 (表项索引, 0, “↓”)发送数据列表框.置标题 (表项索引, 1, 到⽂本 (调⽤者信息.取进程标识 ()))发送数据列表框.置标题 (表项索引, 2, 读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ))发送数据列表框.置标题 (表项索引, 3, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycip”, ))发送数据列表框.置标题 (表项索引, 4, 读配置项 (临时句柄⽂件路径, 到⽂本 (套接字句柄), “ycdk”, ))发送数据列表框.置标题 (表项索引, 5, 到⽂本 (⽹络数据.取长度 ()))发送数据列表框.置标题 (表项索引, 6, ⽂本数据).⼦程序 _⽹截_调创建套接字, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数地址族, 整数型, 参考.参数格式, 整数型, 参考.参数协议, 整数型, 参考.局部变量临时整数变量, 整数型.局部变量⾏索引, 整数型.局部变量进程路径, ⽂本型.如果真 (读配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, ) ≠ “”)返回 (#拦截操作.默认调⽤).如果真结束⾼级表格.⾏数=⾼级表格.⾏数+ 1⾏索引=⾼级表格.⾏数- 1进程路径=调⽤者信息.取进程名 ()⾼级表格.置数据 (⾏索引, 0, #表格常量.⽂本型, 到⽂本 (调⽤者信息.取进程标识 ()))⾼级表格.置数据 (⾏索引, 1, #表格常量.⽂本型, 取⽂本右边 (进程路径, 取⽂本长度 (进程路径) -倒找⽂本 (进程路径, “\”, , 假)))⾼级表格.置数据 (⾏索引, 2, #表格常量.⽂本型, 进程路径)⾼级表格.置数据 (⾏索引, 3, #表格常量.⽂本型, “”)⾼级表格.置数据 (⾏索引, 4, #表格常量.⽂本型, “”)⾼级表格.置数据 (⾏索引, 5, #表格常量.选择型, 假)⾼级表格.置数据 (⾏索引, 6, #表格常量.选择型, 假)⾼级表格.置数据 (⾏索引, 7, #表格常量.选择型, 假)⾼级表格.置数据 (⾏索引, 8, #表格常量.选择型, 假)写配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “mc”, 取⽂本右边 (进程路径, 取⽂本长度 (进程路径) -倒找⽂本 (进程路径, “\”, , 假)))写配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “fs”, “假”)写配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “js”, “假”)写配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “1”, “假”)写配置项 (临时进程⽂件路径, 到⽂本 (调⽤者信息.取进程标识 ()), “2”, “假”)返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调关闭套接字.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.⼦程序 _⽹截_调许可连接, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹址, ⽹址信息, 参考.局部变量 IP段1, 字节型.局部变量 IP段2, 字节型.局部变量 IP段3, 字节型.局部变量 IP段4, 字节型.局部变量端⼝号, 整数型返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调定向发送, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹络数据, ⽹络数据, 参考.参数调⽤⽅式, 整数型, 参考.参数⽹址, ⽹址信息, 参考.局部变量 IP段1, 字节型.局部变量 IP段2, 字节型.局部变量 IP段3, 字节型.局部变量 IP段4, 字节型.局部变量端⼝号, 整数型返回 (#拦截操作.默认调⽤)⽹址.取IP端⼝ (IP段1, IP段2, IP段3, IP段4, 端⼝号)返回 (#拦截操作.默认调⽤).⼦程序 _⽹截_调定向接收, 整数型.参数调⽤者信息, 调⽤者信息, 参考.参数套接字句柄, 整数型, 参考.参数⽹络数据, ⽹络数据, 参考.参数调⽤⽅式, 整数型, 参考.参数⽹址, ⽹址信息, 参考.局部变量 IP段1, 字节型.局部变量 IP段2, 字节型.局部变量 IP段3, 字节型.局部变量 IP段4, 字节型.局部变量端⼝号, 整数型返回 (#拦截操作.默认调⽤)⽹址.取IP端⼝ (IP段1, IP段2, IP段3, IP段4, 端⼝号)返回 (#拦截操作.默认调⽤).⼦程序彗星URL解码, ⽂本型, 公开, 返回已解码的URL.参数 Bin_URL, ⽂本型, , 欲解码的⽂本.局部变量循环容器, 整数型.局部变量 Len, 整数型.局部变量 HEX, ⽂本型.局部变量⽬标, ⽂本型.局部变量 H, 整数型.局部变量 L, 整数型Len =取⽂本长度 (Bin_URL)循环容器= 1HEX = “0123456789ABCDEF”.判断循环⾸ (循环容器 ≤ Len).判断开始 (取⽂本中间 (Bin_URL, 循环容器, 1) ≠ “%”)⽬标=⽬标+取⽂本中间 (Bin_URL, 循环容器, 1).默认循环容器=循环容器+ 1H =寻找⽂本 (HEX, 到⼤写 (取⽂本中间 (Bin_URL, 循环容器, 1)), , 假) - 1循环容器=循环容器+ 1L =寻找⽂本 (HEX, 到⼤写 (取⽂本中间 (Bin_URL, 循环容器, 1)), , 假) - 1⽬标=⽬标+字符 (H × 16 + L).判断结束循环容器=循环容器+ 1.判断循环尾 ()返回 (⽬标).⼦程序 _⾼级表格_结束编辑.局部变量 x, 整数型.局部变量 y, 整数型x =⾼级表格.取光标列号 ()y =⾼级表格.取光标⾏号 ()写配置项 (临时进程⽂件路径, ⾼级表格.取数据 (y, 0), “ip”, ⾼级表格.取数据 (y, 3))写配置项 (临时进程⽂件路径, ⾼级表格.取数据 (y, 0), “port”, ⾼级表格.取数据 (y, 4))写配置项 (临时进程⽂件路径, ⾼级表格.取数据 (y, 0), “fs”, 到⽂本 (⾼级表格.取数据 (y, 5)))写配置项 (临时进程⽂件路径, ⾼级表格.取数据 (y, 0), “js”, 到⽂本 (⾼级表格.取数据 (y, 6)))写配置项 (临时进程⽂件路径, ⾼级表格.取数据 (y, 0), “1”, 到⽂本 (⾼级表格.取数据 (y, 7)))写配置项 (临时进程⽂件路径, ⾼级表格.取数据 (y, 0), “2”, 到⽂本 (⾼级表格.取数据 (y, 8))).⼦程序 _转IP选择框_被单击IP编辑框.禁⽌=取反 (转IP选择框.选中).⼦程序 _转端⼝选择框_被单击端⼝编辑框.禁⽌=取反 (转端⼝选择框.选中).⼦程序取⽂本之间, ⽂本型.参数被搜寻的⽂本, ⽂本型.参数开始⽂本, ⽂本型.参数结束⽂本, ⽂本型.局部变量⽂本长度, 整数型.局部变量开始位置, 整数型.局部变量取出长度, 整数型.局部变量 a.局部变量 b⽂本长度=取⽂本长度 (开始⽂本)a =寻找⽂本 (被搜寻的⽂本, 开始⽂本, , 真).如果真 (a ≠ -1)开始位置= a +⽂本长度b =寻找⽂本 (被搜寻的⽂本, 结束⽂本, 开始位置, 真).如果真 (b ≠ -1)取出长度= b -开始位置返回 (取⽂本中间 (被搜寻的⽂本, 开始位置, 取出长度)).如果真结束.如果真结束返回 (“”)运⾏结果:总结以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,谢谢⼤家对的⽀持。
MySniffer抓包程序一、开发思路在windows操作系统下,要想捕获网络上的数据包,必须要对网卡进行控制,因为本机的数据报从网络上来到本机是通过网卡然后再保存到本地缓冲区上的,所以要抓获网包就必须调用网卡驱动中的对外函数.因此,通过调用网卡驱动函数,将网卡设置为杂乱模式状态,使得网卡不能阻塞、过滤或控制其他应用程序数据报的收发,以达到抓取数据包的目的.开发环境:系统:Windows XP;IDE:MyEclipse6.0。
1;工具包: winpcap;Jpcap;开发语言:java二、开发流程1、MySniffer功能本程序基本功能:包括对ipv6数据包的抓取,分析.扩展功能:提供友好的可视化界面和操作。
2、MySniffer层次结构MySniffer抓包程序分为三大部分:访问网络底层部分、数据包分析部分、可视化界面部分。
因此,层次结构大概为下图所示:图一、MySniffer抓包程序层次结构图从MySniffer抓包程序层次结构图可知,程序各部分的主要功能包括:●可视化界面部分:提供友好界面显示,抓包操作(网卡选择、开始抓包、停止抓包)及显示数据包分析结果。
●数据包分析部分:负责分析数据包及保存抓取到的数据包.●访问网络底层部分:提供底层服务,检测网卡设备及抓取网络中的原始数据包.3、MySniffer操作流程MySniffer操作流程具体为:初始化界面—〉检测网卡—〉调用网卡抓包—〉对抓到的数据包即时统计、分析->停止抓包—〉显示数据包内容。
如下图所示:图二、MySniffer抓包程序操作流程图4、MySniffer具体实现MySniffer抓包程序包括4个类,分别是IPV6Main(主函数)、IPV6Frame(界面)、IPV6Packet(数据包信息)、IPV6Captor(抓包)。
IPV6Frame提供界面显示,有以下方法:startButton()//开始按钮触发方法,调用doCapture()。
python selenium抓包network 的方法网络抓包是网络调试和分析中常用的技术手段,通过抓取网络数据包,可以了解网络传输的情况,分析网络问题,优化网络性能。
在Python中,可以使用Selenium自动化工具来模拟浏览器操作,并借助Network抓包工具来获取网络数据包信息。
下面介绍使用Python Selenium抓包Network的方法。
一、准备工作1. 安装Selenium首先需要安装Selenium库,可以通过以下命令进行安装:```shellpip install selenium```2. 安装Network抓包工具常用的Network抓包工具包括Chrome开发者工具中的Network面板、Fiddler、Wireshark等。
这里以Chrome开发者工具为例,需要先安装Chrome浏览器。
1. 启动浏览器并启用Network抓包打开Chrome浏览器,进入开发者工具,在Network面板中选择“允许跨域资源共享”(CORS)并启用抓包。
2. 运行Selenium脚本使用Python Selenium库运行自动化脚本,模拟浏览器操作,例如打开网页、点击链接等。
在脚本中添加需要抓取的网络请求,并设置请求头、请求参数等。
3. 获取网络数据包信息脚本执行后,Chrome开发者工具中的Network面板会显示所有请求的数据包信息,包括请求URL、请求方法、请求头、响应状态码、响应时间等。
可以使用Python代码从Network面板中导出数据包信息,并进行进一步的分析和处理。
三、示例代码下面是一个简单的示例代码,演示如何使用Python Selenium和Chrome开发者工具的Network面板来抓取网络数据包:```pythonfrom selenium import webdriverimport time# 启动Chrome浏览器并打开开发者工具driver = webdriver.Chrome()driver.get("about:blank") # 打开空白页面,避免影响真实网络请求time.sleep(2) # 等待一段时间,让浏览器完成初始化driver.switch_to.options.enable_network_logs() # 启用Network抓包# 运行Selenium脚本# 在这里编写需要抓取的网络请求代码,例如打开网页、点击链接等# 导出数据包信息到文件with open("network_logs.txt", "w") as f:for log in driver.log_types["Log Entry"]: # 从Chrome开发者工具中导出数据包信息到文件中f.write(log["level"].ljust(8) + log["message"] + "\n") # 按照指定的格式输出数据包信息到文件中```以上代码中,首先启动Chrome浏览器并打开开发者工具,然后运行Selenium脚本,模拟浏览器操作。
socket和抓包⼯具wiresharksocket和抓包⼯具wireshark最近在学习Python代码中的socket和抓包⼯具wireshark,故⼜将socket等概念⼜学习了⼀遍,温故⽽知新:Python代码如下:server:#!/usr/bin/python# -*- coding: UTF-8 -*-# ⽂件名:server.pyimport socket # 导⼊ socket 模块s = socket.socket() # 创建 socket 对象host = socket.gethostname() # 获取本地主机名port = 12345 # 设置端⼝s.bind((host, port)) # 绑定端⼝s.listen(5) # 等待客户端连接while True:c, addr = s.accept() # 建⽴客户端连接。
print 'conect_address:', addrc.send('welcome to python!')c.close() # 关闭连接client:#!/usr/bin/python# -*- coding: UTF-8 -*-# ⽂件名:client.pyimport socket # 导⼊ socket 模块s = socket.socket() # 创建 socket 对象host = socket.gethostname() # 获取本地主机名port = 12345 # 设置端⼝好s.connect((host, port))print s.recv(1024)s.close()启动server后⽤client进⾏访问,wireshark监听本地回环⽹卡,抓取tcp.port==12345的ip报⽂可以从抓取的报⽂中看到返回的内容总结:在TCP和UDP同属于传输层,共同架设在IP层(⽹络层)之上。
第一次实验:利用Wireshark软件进行数据包抓取1.3.2 抓取一次完整的网络通信过程的数据包实验一,实验目的:通过本次实验,学生能掌握使用Wireshark抓取ping命令的完整通信过程的数据包的技能,熟悉Wireshark软件的包过滤设置和数据显示功能的使用。
二,实验环境:操作系统为Windows 7,抓包工具为Wireshark.三,实验原理:ping是用来测试网络连通性的命令,一旦发出ping命令,主机会发出连续的测试数据包到网络中,在通常的情况下,主机会收到回应数据包,ping采用的是ICMP协议。
四,验步骤:1.确定目标地址:选择作为目标地址。
2.配置过滤器:针对协议进行过滤设置,ping使用的是ICMP协议,抓包前使用捕捉过滤器,过滤设置为icmp,如图 1- 1图 1-13.启动抓包:点击【start】开始抓包,在命令提示符下键入ping , 如图 1-2图 1-2停止抓包后,截取的数据如图 1-3图 1-34,分析数据包:选取一个数据包进行分析,如图1- 4图1-4每一个包都是通过数据链路层DLC协议,IP协议和ICMP协议共三层协议的封装。
DLC协议的目的和源地址是MAC地址,IP协议的目的和源地址是IP地址,这层主要负责将上层收到的信息发送出去,而ICMP协议主要是Type和Code来识别,“Type:8,Code:0”表示报文类型为诊断报文的请求测试包,“Type:0,Code:0”表示报文类型为诊断报文类型请正常的包。
ICMP提供多种类型的消息为源端节点提供网络额故障信息反馈,报文类型可归纳如下:(1)诊断报文(类型:8,代码0;类型:0代码:0);(2)目的不可达报文(类型:3,代码0-15);(3)重定向报文(类型:5,代码:0--4);(4)超时报文(类型:11,代码:0--1);(5)信息报文(类型:12--18)。
1.4.1,TCP协议的分析实验一,实验目的:通过本次实验,掌握使用Wireshark抓取TCP协议的数据包的技能,能够在深入分析“TCP的三次握手”,TCP的四次挥手协议在网络数据流的基础上,进一步提高理论联系实践的能力。
charles抓包教程Charles抓包教程:1. 首先,下载并安装Charles抓包工具。
可以在官方网站或者第三方下载平台找到合适的版本,并按照安装向导进行安装。
2. 打开Charles工具,在主界面上方的工具栏中,点击"Proxy",然后选择"Proxy Settings",在弹出的窗口中确认默认端口号为8888,并记下当前使用的IP地址。
3. 在手机或者其他设备上设置代理,将代理服务器地址设置为上一步中记下的IP地址,端口号为8888。
具体设置方法可以参考设备的操作系统,通常可以在无线网络设置中找到相关选项。
4. 检查代理设置是否成功,打开浏览器并访问任意网页,在Charles工具中会自动显示出相关请求和响应信息,表示代理已经生效。
5. 开始抓包。
在Charles主界面上方的工具栏中,点击"Record"按钮,将其置为选中状态。
此时,Charles会记录所有经过代理的网络请求和响应。
6. 在设备上进行需要抓包的操作,比如打开某个应用程序或者访问某个网页。
Charles会在请求发出和响应返回时捕捉相关数据,并在主界面中显示出来。
7. 分析抓包结果。
在Charles主界面中,可以通过过滤器或者搜索等功能找到特定的请求或者响应。
可以查看请求的URL、请求头、请求体等详细信息,也可以查看响应的状态码、响应头、响应体等内容。
8. 可以对抓包结果进行一些操作,比如保存请求或者响应数据,重发请求,修改请求或者响应等等。
9. 当完成抓包分析后,可以点击工具栏中的"Stop Recording"按钮,停止抓包记录。
10. 最后,根据自己的需求和目的,可以将抓包结果导出或者分享给其他人,也可以对抓包工具进行设置和优化。
注意:在使用Charles进行抓包时,请遵守相关法律法规和道德规范,合法使用该工具,不要盗取他人的隐私信息或者进行其他不正当的行为。
自己动手写网络抓包工具当打开一个标准SOCKET套接口时,我们比较熟悉的协议往往是用AF_INET来建立基于TCP(SOCK_STREAM)或UDP(SOCK_DGRAM)的链接。
但是这些只用于IP层以上,要想从更底层抓包,我们需要使用AF_PACKET来建立套接字,它支持SOCK_RAW和SOCK_DGRAM,它们都能从底层抓包,不同的是后者得到的数据不包括以太网帧头(最开始的14个字节)。
好了,现在我们就知道该怎样建立SOCKET 套接口了:sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)); 最后一个参数ETH_P_IP 指出,我们只对IP包感兴趣,而不是ARP,RARP等。
之后就可以用recvfrom从套接口读取数据了。
现在我们可以抓到发往本地的所有IP数据报了,那么有没有办法抓到那些“流经”本地的数据呢?呵呵,当然可以了,这种技术叫网络嗅探(sniff),它很能威胁网络安全,也非常有用,尤其是当你对网内其他用户的隐私感兴趣时:( 由于以太网数据包是对整个网段广播的,所以网内所有用户都能收到其他用户发出的数据,只是默认的,网卡只接收目的地址是自己或广播地址的数据,而把不是发往自己的数据包丢弃。
但是多数网卡驱动会提供一种混杂模式(promiscous mode),工作在这种模式下的网卡会接收网络内的所有数据,不管它是发给谁的。
下面的方法可以把网卡设成混杂模式:// set NIC to promiscous mode, so we can recieve all packets of the networkstrncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);ioctl(sock, SIOCGIFFLAGS, &ethreq);ethreq.ifr_flags |= IFF_PROMISC;ioctl(sock, SIOCSIFFLAGS, &ethreq);通过ifconfig可以很容易的查看当前网卡是否工作在混杂模式(PROMISC)。
但是请注意,程序退出后,网卡的工作模式不会改变,所以别忘了关闭网卡的混杂模式:// turn off promiscous modeethreq.ifr_flags &= ~IFF_PROMISC;ioctl(sock, SIOCSIFFLAGS, &ethreq);现在我们可以抓到本网段的所有IP数据包了,但是问题也来了:那么多的数据,怎么处理?CPU可能会被严重占用,而且绝大多数的数据我们可能根本就不敢兴趣!那怎么办呢?用if语句?可能要n多个,而且丝毫不会降低内核的繁忙程度。
最好的办法就是告诉内核,把不感兴趣的数据过滤掉,不要往应用层送。
BPF就为此而生。
BPF(Berkeley Packet Filter)是一种类是汇编的伪代码语言,它也有命令代码和操作数。
例如,如果我们只对用户192.168.1.4的数据感兴趣,可以用tcpdump的-d选项生成BPF代码如下:$tcpdump -d host 192.168.1.4(000) ldh [12](001) jeq #0x800 jt 2 jf 6(002) ld [26](003) jeq #0xc0a80104 jt 12 jf 4(004) ld [30](005) jeq #0xc0a80104 jt 12 jf 13(006) jeq #0x806 jt 8 jf 7(007) jeq #0x8035 jt 8 jf 13(008) ld [28](009) jeq #0xc0a80104 jt 12 jf 10(010) ld [38](011) jeq #0xc0a80104 jt 12 jf 13(012) ret #96(013) ret #0其中第一列代表行号,第二列是命令代码,后面是操作数。
下面我们采用汇编注释的方式简单的解释一下:(000) ldh [12] ;load h?? (2 bytes) from ABS offset 12 (the TYPE of ethernet header)(001) jeq #0x800 jt 2 jf 6 ;compareand jump, jump to line 2 if true; else jump to line 6(002) ld [26] ;load word (4 bytes) from ABS offset 26 (src IP address of IP header)(003) jeq #0xc0a80104 jt 12 jf 4 ;compare and jump, jump to line 12 if true, else jump to line 4(004) ld [30] ; load word (4 bytes) from ABS offset 30 (dst IP address of IP header)(005) jeq #0xc0a80104 jt 12 jf 13 ;see line 3(006) jeq #0x806 jt 8 jf 7 ;compare with ARP, see line 1(007) jeq #0x8035 jt 8 jf 13 ;compare with RARP, see line 1(008) ld [28] ;src IP address for other protocols(009) jeq #0xc0a80104 jt 12 jf 10(010) ld [38] ;dst IP address for other protocols(011) jeq #0xc0a80104 jt 12 jf 13(012) ret #96 ;return 96 bytes to user application(013) ret #0 ;drop the packet但是这样的伪代码我们是无法在应用程序里使用的,所以tcpdum提供了一个-dd选项来输出一段等效的C代码:$tcpdump -dd host 192.168.1.4{ 0x28, 0, 0, 0x0000000c },{ 0x15, 0, 4, 0x00000800 },{ 0x20, 0, 0, 0x0000001a },{ 0x15, 8, 0, 0xc0a80104 },{ 0x20, 0, 0, 0x0000001e },{ 0x15, 6, 7, 0xc0a80104 },{ 0x15, 1, 0, 0x00000806 },{ 0x15, 0, 5, 0x00008035 },{ 0x20, 0, 0, 0x0000001c },{ 0x15, 2, 0, 0xc0a80104 },{ 0x20, 0, 0, 0x00000026 },{ 0x15, 0, 1, 0xc0a80104 },{ 0x6, 0, 0, 0x00000060 },{ 0x6, 0, 0, 0x00000000 },该代码对应的数据结构是struct sock_filter,该结构在linux/filter.h中定义如下:struct sock_filter // Filter block{__u16 code; // Actual filter code__u8 jt; // Jump true__u8 jf; // Jump false__u32 k; // Generic multiuse field};code对应命令代码;jt是jump if true后面的操作数,注意这里用的是相对行偏移,如2就表示向前跳转2行,而不像伪代码中使用绝对行号;jf为jump if false后面的操作数;k对应伪代码中第3列的操作数。
了解了BPF伪代码和结构,我们就可以自己定制更加简单有效的BPF filter了,如上例中的6-11行不是针对IP协议的,而我们的套接字已经指定只读取IP数据了,所以就可以把他们删除,不过要注意,行偏移也要做相应的修改。
另外,tcpdump默认只返回96字节的数据,但对大部分应用来说,96字节是远远不够的,所以tcpdump提供了-s选项用于指定返回的数据长度。
OK,下面我们就来看看怎样把过滤器安装到套接口上吧:$tcpdump ip -d -s 2048 host 192.168.1.2(000) ldh [12](001) jeq #0x800 jt 2 jf 7(002) ld [26](003) jeq #0xc0a80102 jt 6 jf 4(004) ld [30](005) jeq #0xc0a80102 jt 6 jf 7(006) ret #2048(007) ret #0struct sock_filter bpf_code[] = {{ 0x28, 0, 0, 0x0000000c },{ 0x15, 0, 5, 0x00000800 },{ 0x20, 0, 0, 0x0000001a },{ 0x15, 2, 0, 0xc0a80102 },{ 0x20, 0, 0, 0x0000001e },{ 0x15, 0, 1, 0xc0a80102 },{ 0x6, 0, 0, 0x00000800 },{ 0x6, 0, 0, 0x00000000 }};struct sock_fprog filter;filter.len = sizeof(bpf_code)/sizeof(bpf_code[0]);filter.filter = bpf_code;setsockopt(sock, SOL_SOCKET,SO_ATTACH_FILTER, &filter, sizeof(filter));最后加上信号处理器,以便能在程序退出前恢复网卡的工作模式。
到现在我们已经可以看到一个小聚规模抓包小工具了,呵呵,麻雀虽小,但也五脏俱全啊!下面给出完整的代码。
#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <linux/types.h>#include <netinet/in.h>#include <netinet/udp.h>#include <netinet/ip.h>#include <netpacket/packet.h> #include <net/ethernet.h>#include <arpa/inet.h>#include <string.h>#include <signal.h>#include <net/if.h>#include <stdio.h>#include <sys/uio.h>#include <fcntl.h>#include <unistd.h>#include <linux/filter.h>#include <stdlib.h>#define ETH_HDR_LEN 14#define IP_HDR_LEN 20#define UDP_HDR_LEN 8#define TCP_HDR_LEN 20static int sock;void sig_handler(int sig){struct ifreq ethreq;if(sig == SIGTERM)printf("SIGTERM recieved, exiting...\n");else if(sig == SIGINT)printf("SIGINT recieved, exiting...\n");else if(sig == SIGQUIT)printf("SIGQUIT recieved, exiting...\n");// turn off the PROMISCOUS modestrncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);if(ioctl(sock, SIOCGIFFLAGS, &ethreq) != -1) {ethreq.ifr_flags &=~IFF_PROMISC;ioctl(sock, SIOCSIFFLAGS,&ethreq);}close(sock);exit(0);}int main(int argc, char ** argv) {int n;char buf[2048];unsigned char *ethhead;unsigned char *iphead;struct ifreq ethreq;struct sigaction sighandle;#if 0$tcpdump ip -s 2048 -d host 192.168.1.2(000) ldh [12](001) jeq #0x800 jt 2 jf 7(002) ld [26](003) jeq #0xc0a80102 jt 6 jf 4(004) ld [30](005) jeq #0xc0a80102 jt 6 jf 7(006) ret #2048(007) ret #0#endifstruct sock_filter bpf_code[] = {{ 0x28, 0, 0, 0x0000000c },{ 0x15, 0, 5, 0x00000800 },{ 0x20, 0, 0, 0x0000001a },{ 0x15, 2, 0, 0xc0a80102 },{ 0x20, 0, 0, 0x0000001e },{ 0x15, 0, 1, 0xc0a80102 },{ 0x6, 0, 0, 0x00000800 },{ 0x6, 0, 0, 0x00000000 }};struct sock_fprog filter;filter.len = sizeof(bpf_code)/sizeof(bpf_code[0]);filter.filter = bpf_code;sighandle.sa_flags = 0;sighandle.sa_handler = sig_handler;sigemptyset(&sighandle.sa_mask);//sigaddset(&sighandle.sa_mask, SIGTERM);//sigaddset(&sighandle.sa_mask, SIGINT);//sigaddset(&sighandle.sa_mask, SIGQUIT);sigaction(SIGTERM, &sighandle, NULL);sigaction(SIGINT, &sighandle, NULL);sigaction(SIGQUIT, &sighandle, NULL);// AF_PACKET allows application to read pecket from and write packet to network device// SOCK_DGRAM the packet exclude ethernet header// SOCK_RAW raw data from the device including ethernet header// ETH_P_IP all IP packetsif((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP))) == -1) {perror("socket");exit(1);}// set NIC to promiscous mode, so we can recieve all packets of the networkstrncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);if(ioctl(sock, SIOCGIFFLAGS, &ethreq) == -1) {perror("ioctl");close(sock);exit(1);}ethreq.ifr_flags |= IFF_PROMISC;if(ioctl(sock, SIOCSIFFLAGS, &ethreq) == -1) {perror("ioctl");close(sock);exit(1);}// attach the bpf filterif(setsockopt(sock, SOL_SOCKET,SO_ATTACH_FILTER, &filter, sizeof(filter)) == -1) {perror("setsockopt");close(sock);exit(1);}while(1) {n = recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL);if(n <(ETH_HDR_LEN+IP_HDR_LEN+UDP_HDR_LEN)) {printf("invalid packet\n");continue;}printf("%d bytes recieved\n", n);ethhead = buf;printf("Ethernet:MAC[%02X:%02X:%02X:%02X:%02X:%02X]", ethhead[0], ethhead[1], ethhead[2],ethhead[3], ethhead[4], ethhead[5]);printf("->[%02X:%02X:%02X:%02X:%02X:%02X]", ethhead[6], ethhead[7], ethhead[8],ethhead[9], ethhead[10], ethhead[11]);printf(" type[%04x]\n",(ntohs(ethhead[12]|ethhead[13]<<8)));iphead = ethhead + ETH_HDR_LEN;// header length as 32-bitprintf("IP: Version: %dHeaderLen: %d[%d]", (*iphead>>4), (*iphead &0x0f), (*iphead & 0x0f)*4);printf(" TotalLen %d",(iphead[2]<<8|iphead[3]));printf(" IP [%d.%d.%d.%d]", iphead[12], iphead[13], iphead[14], iphead[15]);printf("->[%d.%d.%d.%d]",iphead[16], iphead[17], iphead[18], iphead[19]);printf(" %d", iphead[9]);if(iphead[9] == IPPROTO_TCP)printf("[TCP]");else if(iphead[9] == IPPROTO_UDP)printf("[UDP]");else if(iphead[9] == IPPROTO_ICMP)printf("[ICMP]");else if(iphead[9] == IPPROTO_IGMP)printf("[IGMP]");else if(iphead[9] == IPPROTO_IGMP)printf("[IGMP]");elseprintf("[OTHERS]");printf(" PORT [%d]->[%d]\n", (iphead[20]<<8|iphead[21]),(iphead[22]<<8|iphead[23]));}close(sock);exit(0);}本文来自CSDN博客,转载请标明出处:/wangxg_7520/archive/2008/08/19/2795229.aspx。