9

我知道如何手动操作(通过查看十六进制转储)。我怎样才能自动获得相同的东西?我必须使用 API 吗?我有wireshark和微软网络监视器。

4

4 回答 4

9

这可以简单地通过Lua 解析器来实现,该解析器将 HTTP 标头字段添加到数据包树中,允许您对其进行过滤,如下面的屏幕截图所示:

在此处输入图像描述

将此 Lua 脚本复制到您的插件目录(例如${WIRESHARK_HOME}/plugins/1.4.6/http_extra.lua),然后重新启动 Wireshark(如果已经运行)。

do
        local http_wrapper_proto = Proto("http_extra", "Extra analysis of the HTTP protocol");
        http_wrapper_proto.fields.hdr_len = ProtoField.uint32("http.hdr_len", "Header length (bytes)")

        -- HTTP frames that contain a header usually include the HTTP
        -- request method or HTTP response code, so declare those here
        -- so we can check for them later in the dissector.
        local f_req_meth    = Field.new("http.request.method")
        local f_resp_code   = Field.new("http.response.code")

        local original_http_dissector
        function http_wrapper_proto.dissector(tvbuffer, pinfo, treeitem)
                -- We've replaced the original http dissector in the dissector table,
                -- but we still want the original to run, especially because we need 
                -- to read its data. Let's wrap the call in a pcall in order to catch
                -- any unhandled exceptions. We'll ignore those errors.
                pcall(
                    function()
                        original_http_dissector:call(tvbuffer, pinfo, treeitem)
                    end
                )

                -- if the request method or response code is present,
                -- the header must be in this frame
                if f_req_meth() or f_resp_code() then

                        -- find the position of the header terminator (two new lines),
                        -- which indicates the length of the HTTP header, and then add
                        -- the field to the tree (allowing us to filter for it)
                        local hdr_str = tvbuffer():string()
                        local hdr_len = string.find(hdr_str, "\r\n\r\n") or string.find(hdr_str, "\n\n\n\n")
                        if hdr_len ~= nil then
                            treeitem:add(http_wrapper_proto.fields.hdr_len, hdr_len):set_generated()
                        end
                end
        end

        local tcp_dissector_table = DissectorTable.get("tcp.port")
        original_http_dissector = tcp_dissector_table:get_dissector(80) -- save the original dissector so we can still get to it
        tcp_dissector_table:add(80, http_wrapper_proto)                 -- and take its place in the dissector table
end
于 2011-04-26T17:49:08.787 回答
2

不幸的是,尽管您可以创建自定义列,但您想要在该列中的数据当前不是由 HTTP 协议解码器生成的。当然,今天可能还有其他我不熟悉的工具可以做到这一点,但就 Wireshark 而言,您必须添加该功能。

有一些关于创建 Wireshark 插件的好资源,例如:

http://simeonpilgrim.com/blog/2008/04/29/how-to-build-a-wireshark-plug-in/

http://www.wireshark.org/docs/wsdg_html_chunked/ChDissectAdd.html

http://www.codeproject.com/KB/IP/custom_dissector.aspx

这是一个视频,描述了如何将协议解码器公开的字段添加为自定义列:

http://www.youtube.com/watch?v=XpUNXDkfkQg

问题是,您不想重新实现 HTTP 协议解码器。

我要做的是找到内置 HTTP 解码器的源代码,并考虑添加一个新字段,例如http.header_length现有的http.content_length

图像

我没有看过代码,但我想这是一个很容易添加的东西。如果您向 Wireshark 团队提交补丁,他们可能还会在下一个版本中包含您的新字段。

于 2011-04-18T22:20:20.643 回答
2

user568493 发布的代码对我根本不起作用,所以我将其更改为 post dissector,而且它也没有正确计算字节数。它还计算 IP 和以太网字节数。

这是我的版本,适用于 1.8.2:

local http_wrapper_proto = Proto("http_extra", "Extra analysis of the HTTP protocol");
http_wrapper_proto.fields.hdr_len = ProtoField.uint32("http.hdr_len", "HTTP Header length (bytes)")

-- HTTP frames that contain a header usually include the HTTP
-- request method or HTTP response code, so declare those here
-- so we can check for them later in the dissector.
local f_req_meth    = Field.new("http.request.method")
local f_resp_code   = Field.new("http.response.code")

local original_http_dissector
function http_wrapper_proto.dissector(tvbuffer, pinfo, treeitem)
        -- if the request method or response code is present,
        -- the header must be in this frame
        if f_req_meth() or f_resp_code() then
                local start_offset = 0
                local end_offset = 0
                -- find the position of the header terminator (two new lines),
                -- which indicates the length of the HTTP header, and then add
                -- the field to the tree (allowing us to filter for it)
                local hdr_str = tvbuffer():string()
                if f_req_meth() then
                    start_offset = string.find(hdr_str, "GET")
                    end_offset = string.find(hdr_str, "\r\n\r\n")
                end
                if f_resp_code() then
                    start_offset = string.find(hdr_str, "HTTP")
                    end_offset = string.find(hdr_str, "\r\n\r\n")
                end
                local hdr_len = end_offset - start_offset + 4
                -- 4 Bytes because the \r\n\r\n are not part of the HTTP Payload, hence should be counted in the header length.
                if hdr_len ~= nil then
                    treeitem:add(http_wrapper_proto.fields.hdr_len, hdr_len):set_generated()
                end
        end
end

register_postdissector(http_wrapper_proto)
于 2014-07-17T08:48:51.867 回答
0

我发现这种在链中调用前一个解析器的方式会以某种方式干扰为“分块”传输编码完成的 HTTP 数据包重组。也就是说,如果您的响应具有“Transfer-Encoding: chunked”标头,则原始 HTTP 解析器会尝试重新组装数据,并且如果您将其与此类 http_wrapper 挂钩,则重新组装会失败。

例如,这也会导致 http 统计失败。Statistics/HTTP/Packet Counter 会给你,比如 6 个请求和 4 个响应,但事实并非如此 =)

最好使用“register_postdissector”API 调用安装这种“增值”解析器,或仔细测试重新组装逻辑。

于 2011-11-09T00:53:10.060 回答