2017-08-07 126 views
0

我目前正在研究我的第一个协议解析器。我面临着一个我无法解决的问题。基本上我有一个长度为8个字节的字段(但是定义为9个字节),所以我创建了一个位字段来定义这个protofield。Lua - 显示字段ASCII解密器

下面是到目前为止,我已经测试领域的deffinitions:

a) local harer_id = ProtoField.string ("myProto.harer_id","Harer ID", base.ASCII) 
b) local harer_id = ProtoField.uint64 ("myProto.harer_id", "Harer ID", base.HEX) 

然后我把它添加到下面的方式解剖树:

local harer_id_long = tvbuf:range(16,9) 
    body:add(harer_id, harer_id_long:bitfield(4,64)) 

这最终给出以下错误:

a) Gives no error but it doesnt return the value on ASCII format 
    What I get: 0x0000000000313030 
    What I want: 0x0000000000313030 (100) 
b) calling 'add' on bad self (string expected, got userdata) 

如果您有任何建议,我将不胜感激您的帮助。

谢谢你在前进,

马丁

编辑1:

我写了这个代码,将获得该字段的值从每个字节的ASCII表值:

我不不知道如何使其工作,以便它在数据包视图上显示ASCII值。

function getASCII (str) 
    resultStr = "" 
    asciiValue="" 
    for i = 3, string.len(tostring(str))-1, 2 do 
     asciiValue = string.char(tonumber(tostring(string.sub(tostring(str),i,i+1)), 16)) 
     if asciiValue~=nil then 
      resultStr = resultStr .. tostring(tonumber(asciiValue)) 
     end 
    end 
    resultStr = string.gsub(resultStr, "nil", "") 
    return resultStr 
end 
+0

身体和心脏从哪里来?你在哪里使用harer_id?请提供所有相关信息。 – Piglet

+0

harer_id的定义在我共享的代码上。然后,body是来自解剖树的子树,我在此添加harer_id字段 'local tree = root:add(udpProto,tvbuf:range(0,pktlen)) local header = tree:add(header,tvbuf :range(0,HDR_LEN)) local body = tree:add(body,tvbuf:range(9,BODY_LEN))' 这里的问题是如何定义字段,详细区域,ASCII值也将被显示 –

+0

*“我有一个长度为8个字节的字段(但定义为9个字节)”* - 什么? –

回答

1

这是另一种方法,也适用于我。我不知道你喜欢,但你现在有2个从(假设你可以让我的原始的方法来工作)来选择:

local harer_id = ProtoField.uint64("myProto.harer_id", "Harer ID", base.HEX) 

harer_item = body:add(harer_id, tvbuf(16, 9):bitfield(4, 64)) 
harer_item:set_len(9) 

vals = {} 
for i = 0, 7 do 
    vals[i] = bit.bor(buf(16 + i, 2):bitfield(4, 8), 0x30) 
end 
harer_item:append_text(" (" .. 
    tonumber(string.format("%c%c%c%c%c%c%c%c", vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7])) .. 
    ")") 

编辑:这是一个简单的Lua剥离和样本包,你可以用它来测试该解决方案:

-- Protocol 
local p_foo = Proto("foo", "FOO Protocol") 

-- Fields 
local f_foo_res1 = ProtoField.uint8("foo.res1", "Reserved 1", base.DEC, nil, 0xf0) 
local f_foo_str = ProtoField.uint64("foo.str", "String", base.HEX) 
local f_foo_res2 = ProtoField.uint8("foo.res2", "Reserved 2 ", base.DEC, nil, 0x0f) 
local f_foo_res3 = ProtoField.uint8("foo.res3", "Reserved 3", base.HEX) 
local f_foo_ipv6 = ProtoField.ipv6("foo.ipv6", "IPv6 Address") 

p_foo.fields = { f_foo_res1, f_foo_str, f_foo_res2, f_foo_res3, f_foo_ipv6 } 

-- Dissection 
function p_foo.dissector(buf, pinfo, tree) 
    local foo_tree = tree:add(p_foo, buf(0,-1)) 

    pinfo.cols.protocol:set("FOO") 
    foo_tree:add(f_foo_res1, buf(0, 1)) 

    str_item = foo_tree:add(f_foo_str, buf(0, 9):bitfield(4, 64)) 
    str_item:set_len(9) 

    vals = {} 
    for i = 0, 7 do 
     vals[i] = bit.bor(buf(i, 2):bitfield(4, 8), 0x30) 
    end 
    str_item:append_text(" (" .. 
     tonumber(string.format("%c%c%c%c%c%c%c%c", vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7])) .. 
     ")") 

    foo_tree:add(f_foo_res2, buf(9, 1)) 
    foo_tree:add(f_foo_res3, buf(10, 1)) 
    foo_tree:add(f_foo_ipv6, buf(11, 16)) 
end 

-- Registration 
local udp_table = DissectorTable.get("udp.port") 
udp_table:add(33333, p_foo) 

使用text2pcap这个数据成为分组,Wireshark才能读取或使用Wireshark的“文件 - >导入从十六进制转储...” featu再次:

0000 00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00 
0010 00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00 
0020 02 66 82 35 82 35 00 23 00 00 03 03 13 23 33 43 
0030 53 63 70 80 64 20 01 0d b8 00 00 00 00 00 00 00 
0040 00 00 00 00 01 

我的Wireshark的细节:
编译(64位)使用Qt 5.6.2,与WinPcap的(4_1_3),与GLib的2.42.0,与 的zlib 1.2.8,与SMI 0.4。 8,c-ares 1.12.0,Lua 5.2.4,GnuTLS 3.4.11,Gcrypt 1.7.6,MIT Kerberos,GeoIP,nghttp2 1.14.0, 与LZ4,Snappy,带libxml2 2.9.4,带QtMultimedia,带AirPcap,带SBC,带SpanDSP。

+0

我真的很喜欢你建议的解决方案,但他们似乎不适合我。我能做什么错了? “Lua错误....:试图连接一个零值” –

+1

我修改了我的答案和更多细节。你应该可以使用我提供的Lua脚本,并根据我提供的数据包进行测试。 –

+0

非常感谢你,男人!真的很感谢你的努力!我已经设法让你的例子工作,这很好。我感觉我知道我的代码正在发生什么。问题是,在我的代码中,大多数字段都是00,所以当它转换为ASCII时,它会尝试连接一个零值并中断。 –

0

有可能是一个更有效的方法来做到这一点,但你可以尝试这样的事情?

harer_id = ProtoField.string("myProto.harer_id", "Harer ID", base.ASCII) 

harer_item = body:add(harer_id, tvbuf(16, 9)) 
harer_item:set_text("Harer ID: " .. 
    tonumber(
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(16, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(17, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(17, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(18, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(18, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(19, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(19, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(20, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(20, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(21, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(21, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(22, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(22, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(23, 1):uint(), 4))) .. 
     string.char(bit.bor(bit.band(bit.lshift(tvbuf(23, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(24, 1):uint(), 4))) 
     ) 
    ) 
+0

谢谢你的回答,我非常喜欢你提出的想法。但是,我不知道我是否做错了什么,但它是什么......它返回 '更高的ID:',没有更多。你有什么建议我应该如何修改我的代码? (我没有得到任何调试错误) –

+0

我不知道为什么它不适合你;它在我的测试中起作用。我会提出一个备用解决方案... –