LUAを使ってWIRESHARKプロトコル解析プラグインを作成します。


http://www.cnblogs.com/wendellyi/p/3475461.html
 
一、プラットフォーム
 
オペレーティングシステム:windows 7
 
ワイスハーク:1.10.3
 
lua:5.1
 
 
 
二、準備
 
lua言語基本文法、特に表操作と循環について
 
Wiresthark文書は、ユーザーがドキュメントや開発者のドキュメントを使うことなどがあります。
 
 
 
はじめに
 
まず簡単なプロトコルを定義します。C言語の文法的な説明を使います。
struct foo
{
    char protocol_type[16];     /* request response notify */
    char service_type[16];      /*             */
    unsigned int msg_len;       /*        */
    char msg_content[0];        /*       ,                */
};
 
今はluaを使って一番基本的なフレームを定義してもいいです。
do
    --[[
                   foo_proto
                          
                     ,    
    --]]
    local foo_proto = Proto("foo", "Foo Protolcol")
    
    --[[
              
    --]]
    local foo_protocol_type = ProtoField.string("foo.prototype", "Protocol Type", base.NONE)
    local foo_service_type = ProtoField.string("foo.servicetype", "Service Type", base.NONE)
    local foo_msg_len = ProtoField.uint32("foo.msglen", "Message Length", base.DEC)
    local foo_msg_content = ProtoField.string("foo.msgcontent", "Message Content", base.NONE)
    
    --          
    foo_proto.fields = {
        foo_protocol_type,
        foo_service_type,
        foo_msg_len,
        foo_msg_content
    }
    
    --[[
             foo        ,      wireshark  
               Tvb   ,               
               Pinfo   ,          ,   UI     
               TreeItem   ,        
    --]]
    function foo_proto.dissector(tvb, pinfo, treeitem)
        
        --      UI      
        pinfo.cols.protocol:set("FOO")
        pinfo.cols.info:set("Foo Protocol")
        
        local offset = 0
        local tvb_len = tvb:len()
        
        --            foo     
        local foo_tree = treeitem:add(foo_proto, tvb:range(offset))
        
        --               ,             
        --    range             ,           
        --                   
        foo_tree:add(foo_protocol_type, tvb:range(offset, 16))
        offset = offset+16        
        foo_tree:add(foo_service_type, tvb:range(offset, 16))
        offset = offset+16
        foo_tree:add(foo_msg_len, tvb:range(offset, 4))
        offset = offset+4
        
        --          
        local foo_content_len = tvb_len-offset
        foo_tree:add(foo_msg_content, tvb:range(offset, foo_content_len))
        offset = offset+foo_content_len
        
    end
    
    --   wireshark             
    local tcp_port_table = DissectorTable.get("tcp.port")
    tcp_port_table:add(12345, foo_proto)
end
 
 
四、拡張
 
(1)単一TCPセグメントマルチアプリケーションPDU
 
このような状況は、私たちのプロトコル解析関数で循環解決を使用することができますが、アプリケーション層PDUは一般的に私たちのカスタムの分割識別子が必要です。そうでないと区別できません。ここでは、プロトコルの終端マークを使用して、0 xFF分割を採用します。つまり、私たちのメッセージの長さフィールドの値はこの値が現れません。
 
(2)単一アプリケーションPDUマルチTCPセグメント
 
この場合は、WirestharkがTCPプロトコルスタックによって分割されたデータを再接続してくれる必要がありますが、これはもう利用できるインターフェースがあります。以下は2つの状況を処理する枠組みです。
do
    --                  
    local tvbrange = tvb:range(0)
    local bytearray = tvbrange:bytes()
    local offset = pinfo.desegment_offset or 0
    
    while true do
        local pdu_flg = false
        local pdu_end_index = 0
        
        -- ByteArray        C   
        --    lua             
        for i = offset, tvb_len do
            if 0xFF == bytearray:get_index(i) then
                pdu_flg = true
                pdu_end_index = i
            end
        end
        
        --        PDU     ,        
        if false == frame_end_flg then
            --                    
            --             ,         
            --            
            pinfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
            return
        end
        
        --           ,             
        --             pdu_end_index
        
    end
end
 
 
五、完璧
 
(1)ネットワークプロトコルについて言えば、整数に関わると必ずバイト順の問題があります。ワイスハークがデフォルトで使うのが大端バイト順であれば、プロトコルの整数が小端バイト順を採用する場合、TreeItemタイプのle_を使用することを考慮してください。add()方法はadd()方法を代替する。
 
(2)addとle_add方法では、私達は明示的に自分達の値を設定し、add方法に第三の値を伝えることができます。例えば、
local protocol_type = tvb:range(offset, 16):string()
foo_tree:add(foo_protocol_type, tvb:range(offset, 4), protocol_type)
 
このように表示されているのがプロトコールです。typeの内容は、他にここのプロトタイプです。タイプは必ず上記とfoo_を定義してください。protocol.typeはwirestharkに解析を一致させます。そうでないとこの値は無効です。つまりこの場所はprotocolです。typeは整数であれば無効です。逆も同じです。
 
(3)プロトコル解析ツリーにノードを追加するには、フィールドを事前に定義する必要はありません。すなわちフィールドの定義は必須ではありません。例えば、
local protocol_type = tvb:range(offset, 16):string()
foo_tree:add(tvb:range(offset, 16), "Protocol Type: " .. protocol_type)
 
効果は同じですが、フィルタではこのフィールドは使えません。
 
(4)pinfo.com.info:set方法は、呼び出しを遅延させることができ、すなわち、メッセージの様々な属性を決定した後に呼び出しを行うことができ、このようにして、プロトコルの要約をより明確に表示することができる。
 
 
 
六、参考
 
(1)ワイスハークユーザーマニュアルは、ワイスハークのインストールディレクトリにchmのバージョンがあり、最も参考になるのは第11章のデータの種類と様々な方法の説明です。
 
(2)分解されたTCPセグメントを再構築するhttp://stackoverflow.com/questions/13138088/how-do-i-reassemble-tcp-packet-in-lua-dissector
 
(3)PDUをセグメント化して処理し、http://stackoverflow.com/questions/14387426/reassembling-packets-in-a-lua-wireshark-dissector
 
(4)サブプロトコルを呼び出す方法は、http://blog.csdn.net/phunxm/article/details/5972904である。