Wireshark lua dissector 对TCP消息包合并分析

简介: Wireshark lua dissector 对TCP消息包合并分析

应用程序发送的数据报都是流式的,IP不保证同一个一个应用数据包会被抓包后在同一个IP数据包中,因此对于使用自制dissector的时候需要考虑这种情况。


Lua Dissector相关资料可以见:http://wiki.wireshark.org/Lua/Dissectors


Lua脚本书写wireshark dissector非常方便,使用Lua合并tcp数据报进行分析的样例如下,其实就是多了一个条件分支,所谓难者不会,会者不难:

local slicer = Proto("slicer","Slicer")
function slicer.dissector(tvb, pinfo, tree)
    local offset = pinfo.desegment_offset or 0
    local len = get_len() -- for tests i used a constant, but can be taken from tvb
    while true do
        local nxtpdu = offset + len
        if nxtpdu > tvb:len() then
            pinfo.desegment_len = nxtpdu - tvb:len()
            pinfo.desegment_offset = offset
            return
        end
        tree:add(slicer, tvb(offset, len))
        offset = nxtpdu
        if nxtpdu == tvb:len() then
             return
        end
    end
end
local tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(2506, slicer)


对于Lua Dissector脚本使用方法如下:


tshark


tshark -X lua_script:slicer.lua -i lo0 -f "tcp port 2506" -O aa -V


Wireshark


On OSX

Copy slicer.lua to ~/.wireshark

Add dofile(USER_DIR.."slicer.lua") to the end of /Applications/Wireshark.app/Contents/Resources/share/wireshark/init.lua

 

在wireshark的C语言版本中,有针对tcp合并报的相关函数,packet-tcp.c 具体见下:

/*
2152     * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
2153     * consists of a fixed-length chunk of data that contains enough information
2154     * to determine the length of the PDU, followed by rest of the PDU.
2155     *
2156     * The first three arguments are the arguments passed to the dissector
2157     * that calls this routine.
2158     *
2159     * "proto_desegment" is the dissector's flag controlling whether it should
2160     * desegment PDUs that cross TCP segment boundaries.
2161     *
2162     * "fixed_len" is the length of the fixed-length part of the PDU.
2163     *
2164     * "get_pdu_len()" is a routine called to get the length of the PDU from
2165     * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset".
2166     *
2167     * "dissect_pdu()" is the routine to dissect a PDU.
2168     */
2169    void
2170    tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2171                     gboolean proto_desegment, guint fixed_len,
2172                     guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
2173                     dissector_t dissect_pdu)
2174    {
2175        volatile int offset = 0;
2176        int offset_before;
2177        guint length_remaining;
2178        guint plen;
2179        guint length;
2180        tvbuff_t *next_tvb;
2181        proto_item *item=NULL;
2182        void *pd_save;
2183    
2184        while (tvb_reported_length_remaining(tvb, offset) != 0) {
2185            /*
2186             * We use "tvb_ensure_length_remaining()" to make sure there actually
2187             * *is* data remaining.  The protocol we're handling could conceivably
2188             * consists of a sequence of fixed-length PDUs, and therefore the
2189             * "get_pdu_len" routine might not actually fetch anything from
2190             * the tvbuff, and thus might not cause an exception to be thrown if
2191             * we've run past the end of the tvbuff.
2192             *
2193             * This means we're guaranteed that "length_remaining" is positive.
2194             */
2195            length_remaining = tvb_ensure_length_remaining(tvb, offset);
2196    
2197            /*
2198             * Can we do reassembly?
2199             */
2200            if (proto_desegment && pinfo->can_desegment) {
2201                /*
2202                 * Yes - is the fixed-length part of the PDU split across segment
2203                 * boundaries?
2204                 */
2205                if (length_remaining < fixed_len) {
2206                    /*
2207                     * Yes.  Tell the TCP dissector where the data for this message
2208                     * starts in the data it handed us and that we need "some more
2209                     * data."  Don't tell it exactly how many bytes we need because
2210                     * if/when we ask for even more (after the header) that will
2211                     * break reassembly.
2212                     */
2213                    pinfo->desegment_offset = offset;
2214                    pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2215                    return;
2216                }
2217            }
2218    
2219            /*
2220             * Get the length of the PDU.
2221             */
2222            plen = (*get_pdu_len)(pinfo, tvb, offset);
2223            if (plen < fixed_len) {
2224                /*
2225                 * Either:
2226                 *
2227                 *  1) the length value extracted from the fixed-length portion
2228                 *     doesn't include the fixed-length portion's length, and
2229                 *     was so large that, when the fixed-length portion's
2230                 *     length was added to it, the total length overflowed;
2231                 *
2232                 *  2) the length value extracted from the fixed-length portion
2233                 *     includes the fixed-length portion's length, and the value
2234                 *     was less than the fixed-length portion's length, i.e. it
2235                 *     was bogus.
2236                 *
2237                 * Report this as a bounds error.
2238                 */
2239                show_reported_bounds_error(tvb, pinfo, tree);
2240                return;
2241            }
2242    
2243            /*
2244             * Do not display the the PDU length if it crosses the boundary of the
2245             * packet and no more packets are available.
2246             *
2247             * XXX - we don't necessarily know whether more packets are
2248             * available; we might be doing a one-pass read through the
2249             * capture in TShark, or we might be doing a live capture in
2250             * Wireshark.
2251             */
2252    #if 0
2253            if (length_remaining >= plen || there are more packets)
2254            {
2255    #endif
2256                    /*
2257                     * Display the PDU length as a field
2258                     */
2259                    item=proto_tree_add_uint(pinfo->tcp_tree, hf_tcp_pdu_size,
2260                                             tvb, offset, plen, plen);
2261                    PROTO_ITEM_SET_GENERATED(item);
2262    #if 0
2263            } else {
2264                    item = proto_tree_add_text(pinfo->tcp_tree, tvb, offset, -1,
2265                        "PDU Size: %u cut short at %u",plen,length_remaining);
2266                    PROTO_ITEM_SET_GENERATED(item);
2267            }
2268    #endif
2269    
2270    
2271            /* give a hint to TCP where the next PDU starts
2272             * so that it can attempt to find it in case it starts
2273             * somewhere in the middle of a segment.
2274             */
2275            if(!pinfo->fd->flags.visited && tcp_analyze_seq) {
2276                guint remaining_bytes;
2277                remaining_bytes=tvb_reported_length_remaining(tvb, offset);
2278                if(plen>remaining_bytes) {
2279                    pinfo->want_pdu_tracking=2;
2280                    pinfo->bytes_until_next_pdu=plen-remaining_bytes;
2281                }
2282            }
2283    
2284            /*
2285             * Can we do reassembly?
2286             */
2287            if (proto_desegment && pinfo->can_desegment) {
2288                /*
2289                 * Yes - is the PDU split across segment boundaries?
2290                 */
2291                if (length_remaining < plen) {
2292                    /*
2293                     * Yes.  Tell the TCP dissector where the data for this message
2294                     * starts in the data it handed us, and how many more bytes we
2295                     * need, and return.
2296                     */
2297                    pinfo->desegment_offset = offset;
2298                    pinfo->desegment_len = plen - length_remaining;
2299                    return;
2300                }
2301            }
2302    
2303            /*
2304             * Construct a tvbuff containing the amount of the payload we have
2305             * available.  Make its reported length the amount of data in the PDU.
2306             *
2307             * XXX - if reassembly isn't enabled. the subdissector will throw a
2308             * BoundsError exception, rather than a ReportedBoundsError exception.
2309             * We really want a tvbuff where the length is "length", the reported
2310             * length is "plen", and the "if the snapshot length were infinite"
2311             * length is the minimum of the reported length of the tvbuff handed
2312             * to us and "plen", with a new type of exception thrown if the offset
2313             * is within the reported length but beyond that third length, with
2314             * that exception getting the "Unreassembled Packet" error.
2315             */
2316            length = length_remaining;
2317            if (length > plen)
2318                length = plen;
2319            next_tvb = tvb_new_subset(tvb, offset, length, plen);
2320    
2321            /*
2322             * Dissect the PDU.
2323             *
2324             * Catch the ReportedBoundsError exception; if this particular message
2325             * happens to get a ReportedBoundsError exception, that doesn't mean
2326             * that we should stop dissecting PDUs within this frame or chunk of
2327             * reassembled data.
2328             *
2329             * If it gets a BoundsError, we can stop, as there's nothing more to
2330             * see, so we just re-throw it.
2331             */
2332            pd_save = pinfo->private_data;
2333            TRY {
2334                (*dissect_pdu)(next_tvb, pinfo, tree);
2335            }
2336            CATCH(BoundsError) {
2337                RETHROW;
2338            }
2339            CATCH(ReportedBoundsError) {
2340                /*  Restore the private_data structure in case one of the
2341                 *  called dissectors modified it (and, due to the exception,
2342                 *  was unable to restore it).
2343                 */
2344                pinfo->private_data = pd_save;
2345                show_reported_bounds_error(tvb, pinfo, tree);
2346            }
2347            ENDTRY;
2348    
2349            /*
2350             * Step to the next PDU.
2351             * Make sure we don't overflow.
2352             */
2353            offset_before = offset;
2354            offset += plen;
2355            if (offset <= offset_before)
2356                break;
2357        }
2358    }
2359


目录
相关文章
|
16天前
|
数据挖掘 Linux 数据处理
探索Linux下的Lua命令:轻量级脚本语言在数据处理和分析中的应用
**探索Linux上的Lua:轻量级脚本语言用于数据处理。Lua通过命令行解释器执行,适用于游戏开发、数据分析及自动化。特点包括小巧、高效、可扩展和动态类型。使用`lua`或`luajit`,配合-e、-l、-i参数执行脚本或互动模式。示例:执行`hello.lua`脚本打印&quot;Hello, Lua!&quot;。最佳实践涉及版本兼容、性能优化、使用C API、测试和文档编写。**
|
8月前
|
JavaScript 前端开发 C++
[√]lua binding模版文件分析
[√]lua binding模版文件分析
57 0
|
C++
[✔️]unreal插件lua-profiler:分析lua性能
[✔️]unreal插件lua-profiler:分析lua性能
272 0
|
网络协议
ACK的累加规则-wireshark抓包分析-不包含tcp头部、ip头部、数据链路层头部等。
ACK的累加规则-wireshark抓包分析-不包含tcp头部、ip头部、数据链路层头部等。
ACK的累加规则-wireshark抓包分析-不包含tcp头部、ip头部、数据链路层头部等。
|
网络协议 安全 测试技术
TCP 编程快速入门案例分析 | 学习笔记
快速学习 TCP 编程快速入门案例分析
146 0
TCP 编程快速入门案例分析 | 学习笔记
|
安全
【Lua篇】静态代码扫描分析(一)
静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段。通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问题 静态代码分析可以通过评估编写的代码来提高代码质量;可以稳定的运行且可以轻松自动化;增加了在源代码中发现漏洞的可能性,从而提高应用安全;由于是针对源码扫描可以在离线的开发环境中完成。但是静态代码分析并不能完全保证编写的代码没有Bug,它也有一些缺点,
898 0
【Lua篇】静态代码扫描分析(一)
|
监控 网络协议 NoSQL
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
TCP的开销到底有多大,能否进行量化。一条TCP连接的建立需要耗时延迟多少,是多少毫秒,还是多少微秒?能不能有一个哪怕是粗略的量化估计?
529 0
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
|
网络协议 数据挖掘
|
Web App开发 网络协议 架构师
接口协议之抓包分析 TCP 协议
TCP 协议是在传输层中,一种面向连接的、可靠的、基于字节流的传输层通信协议。 ## 环境准备 对接口测试工具进行分类,可以如下几类: - 网络嗅探工具:tcpdump,wireshark - 代理工具:fiddler,charles,anyproxyburpsuite,mitmproxy - 分析工具:curl,postman,chrome Devtool - ## 抓包分析TCP协
|
Web App开发 网络协议 架构师
接口协议之抓包分析 TCP 协议
TCP 协议是在传输层中,一种面向连接的、可靠的、基于字节流的传输层通信协议。 ## 环境准备 对接口测试工具进行分类,可以如下几类: - 网络嗅探工具:tcpdump,wireshark - 代理工具:fiddler,charles,anyproxyburpsuite,mitmproxy - 分析工具:curl,postman,chrome Devtool - ## 抓包分析TCP协