当前位置: 首页>移动开发>正文

lua脚本中关闭WLAN方法 lua脚本怎么加网络验证

Wireshark是一款著名的网络协议分析工具,基于GPLv2协议开源,支持Linux、Windows、MacOS等多个操作系统。

 Wireshark is the world's foremost network protocol analyzer, and is the de facto (and often de jure) standard across many industries and educational institutions.

 Wireshark development thrives thanks to the contributions of networking experts across the globe. It is the continuation of a project that started in 1998.[via]

 Wireshark已经支持数千种协议,对新协议的支持还在不断增加。今天,你发明了一个新的网络协议,也想让Wireshark识别,你该怎么办呢?你有两个选择:
 发布你的网络协议,等到有1,000,000人每天使用你的协议时,Wireshark就会支持你的协议
 编写一个Wireshark插件,自己动手、丰衣足食

 如果你选择了前者,请按下CTRL+D,然后在你改变主意的时候再回来。
 Wireshark和Wireshark dissector

 如果你还没有安装Wireshark,请下载并安装Wireshark。

 从功能看,Wireshark可以分为以下几个模块:
 核心
 用户界面
 抓包:调用libpcap或winpcap实现
 协议分析:支持的数千种协议,都有相应的分析组件,称为dissector
 保存/读取文件
 ……

 要让Wireshark识别你发明的协议,应该从“协议分析”部分入手,也就是编写一个Wireshark dissector。

 Wireshark本身是用C语言编写的,用C语言编写dissector是很自然的选择。但是,C语言并不简单,在Windows下编译C语言的代码也并不容易。浏览一遍Wireshark User Guide的目录,你会看到一章Lua Support in Wireshark,这就是编写Wireshark dissector插件的另一种选择。
 Lua脚本语言

 Lua是一种功能强大的、快速的、轻量的、嵌入式的脚本语言。Lua在葡萄牙语里是“月亮”的意思,它不是一个缩写因此不能写成“LUA”。

 Lua is a powerful, fast, light-weight, embeddable scripting language.

 Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.[via]

 Lua是一种嵌入式脚本语言,Wireshark嵌入了Lua脚本引擎,因此我们可以使用Lua脚本语言扩展Wireshark。
 初识Lua编写的Wireshark dissector

 Wireshark User Guide, Example of Dissector written in Lua已经给出了一段Wireshark插件代码,先解读一下:
 --这个dissector只是把几个协议组合起来而已,并不是识别一种新的协议
 do --do...end是Lua语言的语句块关键字,相当于C#语言的{..}
 --创建一个Proto类的对象,表示一种协议
 local p_multi = Proto("multi","MultiProto");

 local vs_protos = {
 [2] = "mtp2",
 [3] = "mtp3",
 [4] = "alcap",
 [5] = "h248",
 [6] = "ranap",
 [7] = "rnsap",
 [8] = "nbap"
 }

 --创建几个ProtoField对象,就是主界面中部Packet Details窗格中能显示的那些属性
 local f_proto = ProtoField.uint8("multi.protocol","Protocol",base.DEC,vs_protos)
 local f_dir = ProtoField.uint8("multi.direction","Direction",base.DEC,{ [1] = "incoming", [0] = "outgoing"})
 local f_text = ProtoField.string("multi.text","Text")

 --把ProtoField对象加到Proto对象上
 p_multi.fields = { f_proto, f_dir, f_text }

 --用Dissector.get函数可以获得另外一个协议的解析组件
 local data_dis = Dissector.get("data")

 local protos = {
 [2] = Dissector.get("mtp2"),
 [3] = Dissector.get("mtp3"),
 [4] = Dissector.get("alcap"),
 [5] = Dissector.get("h248"),
 [6] = Dissector.get("ranap"),
 [7] = Dissector.get("rnsap"),
 [8] = Dissector.get("nbap"),
 [9] = Dissector.get("rrc"),
 [10] = DissectorTable.get("sctp.ppi"):get_dissector(3), -- m3ua
 [11] = DissectorTable.get("ip.proto"):get_dissector(132), -- sctp
 }

 --为Proto对象添加一个名为dissector的函数,
 --Wireshark会对每个“相关”数据包调用这个函数
 function p_multi.dissector(buf,pkt,root) 

 --root:add会在Packet Details窗格中增加一行协议
 local t = root:add(p_multi,buf(0,2))
 --t:add,在Packet Details窗格中增加一行属性,
 --并指定要鼠标点击该属性时Packet Bytes窗格中会选中哪些字节
 t:add(f_proto,buf(0,1))
 t:add(f_dir,buf(1,1))

 --这句是将数据的第一个字节转换成无符号整数
 local proto_id = buf(0,1):uint()

 local dissector = protos[proto_id]

 if dissector ~= nil then
 dissector:call(buf(2):tvb(),pkt,root)
 elseif proto_id < 2 then
 t:add(f_text,buf(2))
 -- pkt.cols.info:set(buf(2,buf:len() - 3):string())
 else
 --调用另外一个dissector
 data_dis:call(buf(2):tvb(),pkt,root)
 end 

 end

 --所有的dissector都是以“table”的形式组织的,table表示上级协议
 local wtap_encap_table = DissectorTable.get("wtap_encap")
 --这个是获得udp协议的DissectorTable,并且以端口号排列
 local udp_encap_table = DissectorTable.get("udp.port")

 wtap_encap_table:add(wtap.USER15,p_multi)
 wtap_encap_table:add(wtap.USER12,p_multi)
 --为UDP的7555端口注册这个Proto对象,
 --当遇到源或目的为UDP7555的数据包,就会调用上面的p_multi.dissector函数
 udp_encap_table:add(7555,p_multi)
 end

 Wireshark虽然嵌入了Lua解释器,但是默认情况下并没有打开。安装Lua插件的方法是:
 打开Wireshark安装目录的init.lua文件,搜索disable_lua(找到disable_lua = true; do return end;),在这一行的开头添加--符号。
 将Lua插件复制到Wireshark安装目录内
 在init.lua的最后调用你的Lua插件:dofile('文件名.lua');
 一个实用的Wireshark dissector

 为了演示如何用Lua脚本语言编写一个实用的Wireshark dissector插件,我设计了一个简单的网络协议——ScoreBoard。

 ScoreBoard协议用于更新比分牌的数值的背景颜色。服务端监听UDP1127端口,客户端端口任意。
 报文格式

 每个报文的前16字节是固定的识别符identifier:
 e2 cb b5 80 cb 09 4e ba a3 6b f6 07 ce 95 3f 2b 

 第17字节表示报文类型operator:
 00 get-value 获取比分数值
 01 set-value 设置比分数值
 80 resp-value 应答比分数值
 10 get-color 获取背景色
 11 set-color 设置背景色
 90 resp-color 应答背景色

 数据部分:
 00、80类型的报文
 第18~21字节为左边的比分数值(32位无符号整数,big endian)
 第22~25字节为右边的比分数值(32位无符号整数,big endian)
 10、90类型的报文
 第18字节为红色分量
 第19字节为绿色分量
 第20字节为蓝色分量
 交互流程
 客户端使用00、01类型的报文请求服务端,服务端应当回复80类型的报文
 客户端使用10、11类型的报文请求服务端,服务端应当回复90类型的报文
 识别ScoreBoard协议的Wireshark插件
 do
 --协议名称为ScoreBoard,在Packet Details窗格显示为yoursunny.P2008.IS409 ScoreBoard
 local p_ScoreBoard = Proto("ScoreBoard","yoursunny.P2008.IS409 ScoreBoard")
 --协议的各个字段
 local f_identifier = ProtoField.bytes("ScoreBoard.identifier","Identifier")
 local f_operator = ProtoField.uint8("ScoreBoard.operator","Operator",base.HEX,
 --这个字段的数字值都有相应的含义,可以自动对应成字符串
 { [0] = "get-value", [1] = "set-value", [128] = "resp-value",
 [16] = "get-color", [17] = "set-color", [144] = "resp-color"})
 --所有可能的字段都要定义,到时没有t:add就不会显示
 local f_left = ProtoField.uint32("ScoreBoard.left","Value Left",base.DEC)
 local f_right = ProtoField.uint32("ScoreBoard.right","Value Right",base.DEC)
 local f_red = ProtoField.uint8("ScoreBoard.red","Color Red",base.DEC)
 local f_green = ProtoField.uint8("ScoreBoard.green","Color Green",base.DEC)
 local f_blue = ProtoField.uint8("ScoreBoard.blue","Color Blue",base.DEC)
 p_ScoreBoard.fields = { f_identifier, f_operator, f_left, f_right, f_red, f_green, f_blue }

 local data_dis = Dissector.get("data")

 local function ScoreBoard_dissector(buf,pkt,root)
 local buf_len = buf:len();
 --先检查报文长度,太短的不是我的协议
 if buf_len < 17 then return false end
 --取得前16字节identifier字段的值
 local v_identifier = buf(0,16)
 --验证identifier是否正确
 if ((buf(0,1):uint()~=226) or (buf(1,1):uint()~=203) or (buf(2,1):uint()~=181)
 or (buf(3,1):uint()~=128) or (buf(4,1):uint()~=203) or (buf(5,1):uint()~=9)
 or (buf(6,1):uint()~=78) or (buf(7,1):uint()~=186) or (buf(8,1):uint()~=163)
 or (buf(9,1):uint()~=107) or (buf(10,1):uint()~=246) or (buf(11,1):uint()~=7)
 or (buf(12,1):uint()~=206) or (buf(13,1):uint()~=149) or (buf(14,1):uint()~=63)
 or (buf(15,1):uint()~=43))
 --不正确就不是我的协议
 then return false end
 --取得operator的值
 local v_operator = buf(16,1)
 local i_operator = v_operator:uint()

 --现在知道是我的协议了,放心大胆添加Packet Details
 local t = root:add(p_ScoreBoard,buf)
 --在Packet List窗格的Protocol列也可以“做个小广告”
 pkt.cols.protocol = "ScoreBoard"
 t:add(f_identifier,v_identifier)
 t:add(f_operator,v_operator)

 if ((i_operator == 1) or (i_operator == 128)) and (buf_len >= 25) then
 --把存在的字段逐个添加进去
 t:add(f_left,buf(17,4))
 t:add(f_right,buf(21,4))
 elseif ((i_operator == 17) or (i_operator == 144)) and (buf_len >= 20) then
 t:add(f_red,buf(17,1))
 t:add(f_green,buf(18,1))
 t:add(f_blue,buf(19,1))
 end
 return true
 end

 function p_ScoreBoard.dissector(buf,pkt,root) 
 if ScoreBoard_dissector(buf,pkt,root) then
 --valid ScoreBoard diagram
 else
 --data这个dissector几乎是必不可少的;当发现不是我的协议时,就应该调用data
 data_dis:call(buf,pkt,root)
 end
 end

 local udp_encap_table = DissectorTable.get("udp.port")
 --只需要处理UDP1127端口就可以了
 udp_encap_table:add(1127,p_ScoreBoard)
 end



查看ScoreBoard协议的Wireshark插件效果演示,下载ScoreBoard协议的样例客户端脚本、服务端程序、pcap抓包、Lua插件源码
插件的调试

我没有找到非常有效的插件调试方法。当Lua脚本中有语法错误时,Wireshark会在启动时弹出提示框;有调用错误时,会在相关数据包的Packet Details窗格中以红色显示。

你可以把捕获的数据包保存为.pcap文件,每次修改Lua脚本后双击.pcap文件打开Wireshark即可。不必每次都进行Live Capture。
小结

Wireshark有了Lua支持后,如虎添翼,大大方便了插件的开发。当你发明了一个网络协议,要让Wireshark支持它的最佳办法就是动手用Lua语言写一个dissector。只要你充分理解自己设计的网络协议,结合Lua语言参考和Wireshark文档(不过有些函数名不够准确、请参考Wireshark源码),写出一个Wireshark插件还是挺容易的。


https://www.xamrdz.com/mobile/4pd1960686.html

相关文章: