diff options
author | Peter Wu <peter@lekensteyn.nl> | 2016-12-21 16:00:07 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2016-12-21 16:00:07 +0100 |
commit | 2c4258016fe63b726b16f4d74de5c111e28c03f3 (patch) | |
tree | ca39f0a3f38af4c651c3c3547da02b0b011ac08c | |
parent | 544430d27c019c0584b341b454189729c329433d (diff) | |
download | wireshark-notes-2c4258016fe63b726b16f4d74de5c111e28c03f3.tar.gz |
file-zip: WIP for data descriptor
Well, this does not work because the actual data size is unknown... And
it turns out that you really have to parse the EoCD first, otherwise
.jar files cannot be parsed...
-rw-r--r-- | lua/file-zip.lua | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/lua/file-zip.lua b/lua/file-zip.lua index 241142c..ee23087 100644 --- a/lua/file-zip.lua +++ b/lua/file-zip.lua @@ -43,7 +43,11 @@ make_fields("zip_archive", { entry = { _ = {ProtoField.none, "File entry"}, version = {ProtoField.uint16, base.DEC}, - flag = {ProtoField.uint16, base.HEX}, + flag = { + _ = {ProtoField.uint16, "General purpose bit flag", base.HEX}, + -- TODO fi wslua documentation, it is wrong. + has_data_desc = {ProtoField.bool, 16, nil, 0x0008, "Whether data descriptor is present"}, + }, comp_method = {ProtoField.uint16, base.HEX}, lastmod_time = {ProtoField.uint16, base.HEX}, lastmod_date = {ProtoField.uint16, base.HEX}, @@ -55,6 +59,12 @@ make_fields("zip_archive", { filename = {ProtoField.string}, extra = {ProtoField.bytes}, data = {ProtoField.bytes}, + data_desc = { + _ = {ProtoField.none, "Data descriptor"}, + crc32 = {ProtoField.uint32, base.HEX}, + size_comp = {ProtoField.uint32, base.DEC}, + size_uncomp = {ProtoField.uint32, base.DEC}, + }, }, cd = { _ = {ProtoField.none, "Central Directory Record"}, @@ -90,9 +100,6 @@ make_fields("zip_archive", { }, }, hf, proto_zip.fields) -local function dissect_entry(tvb, pinfo, tree) -end - local function dissect_one(tvb, offset, pinfo, tree) local orig_offset = offset local magic = tvb(offset, 4):le_int() @@ -101,7 +108,9 @@ local function dissect_one(tvb, offset, pinfo, tree) -- header subtree:add_le(hf.signature, tvb(offset, 4)) subtree:add_le(hf.entry.version, tvb(offset + 4, 2)) - subtree:add_le(hf.entry.flag, tvb(offset + 6, 2)) + local flgtree = subtree:add_le(hf.entry.flag._, tvb(offset + 6, 2)) + -- TODO why does flag.has_data_desc segfault if tvb is not given? + flgtree:add_le(hf.entry.flag.has_data_desc, tvb(offset + 6, 2)) subtree:add_le(hf.entry.comp_method, tvb(offset + 8, 2)) subtree:add_le(hf.entry.lastmod_time, tvb(offset + 10, 2)) subtree:add_le(hf.entry.lastmod_date, tvb(offset + 12, 2)) @@ -110,19 +119,56 @@ local function dissect_one(tvb, offset, pinfo, tree) subtree:add_le(hf.entry.size_uncomp, tvb(offset + 22, 4)) subtree:add_le(hf.entry.filename_len, tvb(offset + 26, 2)) subtree:add_le(hf.entry.extra_len, tvb(offset + 28, 2)) + local flag = tvb(offset + 6, 2):le_uint() local data_len = tvb(offset + 18, 2):le_uint() local filename_len = tvb(offset + 26, 2):le_uint() local extra_len = tvb(offset + 28, 2):le_uint() + -- Optional data descriptor follows data if GP flag bit 3 (0x8) is set + --[[ This is wrong, cannot know the location of dd, have to query CD first + local ddlen + if bit.band(flag, 8) ~= 0 then + local dd_offset = offset + 30 + filename_len + extra_len + data_len + if tvb(dd_offset, 4):le_uint() == 0x08074b50 then + -- Optional data descriptor signature... WTF, why?! + dd_offset = dd_offset + 4 + ddlen = 16 + else + ddlen = 12 + end + subtree:add_le(hf.entry.data_desc.size_comp, tvb(dd_offset + 4, 4)) + --data_len = tvb(dd_offset + 4, 4):le_uint() + end + --]] + -- skip header offset = offset + 30 subtree:add(hf.entry.filename, tvb(offset, filename_len)) subtree:append_text(": " .. tvb(offset, filename_len):string()) offset = offset + filename_len - subtree:add(hf.entry.extra, tvb(offset, extra_len)) - offset = offset + extra_len - subtree:add(hf.entry.data, tvb(offset, data_len)) - offset = offset + data_len + if extra_len > 0 then + subtree:add(hf.entry.extra, tvb(offset, extra_len)) + offset = offset + extra_len + end + if data_len > 0 then + subtree:add(hf.entry.data, tvb(offset, data_len)) + offset = offset + data_len + end + --[[ This does need really work.. + -- Optional data descriptor header + if ddlen then + local dd_offset = offset + local ddtree = subtree:add_le(hf.entry.data_desc._, tvb(dd_offset, ddlen)) + if ddlen == 16 then + ddtree:add_le(hf.signature, tvb(dd_offset, 4)) + dd_offset = dd_offset + 4 + end + ddtree:add_le(hf.entry.data_desc.crc32, tvb(dd_offset, 4)) + ddtree:add_le(hf.entry.data_desc.size_comp, tvb(dd_offset + 4, 4)) + ddtree:add_le(hf.entry.data_desc.size_uncomp, tvb(dd_offset + 8, 4)) + offset = offset + ddlen + end + --]] subtree:set_len(offset - orig_offset) return offset @@ -154,8 +200,10 @@ local function dissect_one(tvb, offset, pinfo, tree) subtree:add(hf.cd.filename, tvb(offset, filename_len)) subtree:append_text(": " .. tvb(offset, filename_len):string()) offset = offset + filename_len - subtree:add(hf.cd.extra, tvb(offset, extra_len)) - offset = offset + extra_len + if extra_len > 0 then + subtree:add(hf.cd.extra, tvb(offset, extra_len)) + offset = offset + extra_len + end if comment_len > 0 then subtree:add(hf.cd.comment, tvb(offset, comment_len)) offset = offset + comment_len @@ -192,7 +240,7 @@ function proto_zip.dissector(tvb, pinfo, tree) --pinfo.cols.info = "" local next_offset = 0 - while next_offset < tvb:len() do + while next_offset and next_offset < tvb:len() do next_offset = dissect_one(tvb, next_offset, pinfo, tree) end return next_offset |