summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2016-12-21 16:00:07 +0100
committerPeter Wu <peter@lekensteyn.nl>2016-12-21 16:00:07 +0100
commit2c4258016fe63b726b16f4d74de5c111e28c03f3 (patch)
treeca39f0a3f38af4c651c3c3547da02b0b011ac08c
parent544430d27c019c0584b341b454189729c329433d (diff)
downloadwireshark-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.lua72
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