Created
March 17, 2017 20:32
-
-
Save Subv/994a2b6f64156da9105c2bd5c7a21b1a to your computer and use it in GitHub Desktop.
Wireshark dissector for the UDS protocol of the Nintendo 3DS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local TAG_VENDOR_SPECIFIC_IE = 0xDD | |
local uds = Proto("nin_uds", "Nintendo UDS Protocol") | |
local oui = ProtoField.new("OUI", "nin_uds.oui", ftypes.UINT24, nil, base.HEX) | |
local oui_type = ProtoField.new("OUI Type", "nin_uds.oui_type", ftypes.UINT8) | |
local tag20_data = ProtoField.new("Tag 20 data", "nin_uds.tag20.data", ftypes.UINT24, nil, base.HEX) | |
-- Tag 21 fields | |
-- NetworkInfo structure fields | |
local wlancommid = ProtoField.new("WLAN Communications Id", "nin_uds.network_info.wlancommid", ftypes.UINT32, nil, base.HEX) | |
local id = ProtoField.new("Id", "nin_uds.network_info.id", ftypes.UINT8, nil, base.HEX) | |
local counter = ProtoField.new("Counter", "nin_uds.network_info.counter", ftypes.UINT8, nil, base.HEX) | |
local attributes = ProtoField.new("Attributes", "nin_uds.network_info.attributes", ftypes.UINT16, nil, base.HEX) | |
local network_id = ProtoField.new("Network Id", "nin_uds.network_info.network_id", ftypes.UINT32, nil, base.HEX) | |
local num_nodes = ProtoField.new("Number of nodes", "nin_uds.network_info.num_nodes", ftypes.UINT8, nil, base.HEX) | |
local max_nodes = ProtoField.new("Max nodes", "nin_uds.network_info.max_nodes", ftypes.UINT8, nil, base.HEX) | |
local unk = ProtoField.new("Unknown", "nin_uds.network_info.unk", ftypes.BYTES, nil, base.SPACE) | |
local data_hash = ProtoField.new("SHA1 Hash", "nin_uds.sha1", ftypes.BYTES, nil, base.SPACE) | |
local appdata_size = ProtoField.new("Size of application data", "nin_uds.appdata_size", ftypes.UINT8, nil, base.HEX) | |
local appdata = ProtoField.new("Application data", "nin_uds.appdata", ftypes.BYTES, nil, base.SPACE) | |
-- Tag 24 fields | |
local encrypted_data0 = ProtoField.new("Encrypted data 0", "nin_uds.enc_data0", ftypes.BYTES, nil, base.SPACE) | |
uds.fields = { | |
-- Add the outer fields | |
oui, oui_type, tag20_data, | |
-- Tag 21 fields | |
-- Add the fields corresponding to the NetworkInfo structure | |
wlancommid, id, counter, attributes, network_id, num_nodes, max_nodes, unk, | |
data_hash, appdata_size, appdata, | |
-- Tag 24 fields | |
encrypted_data0 | |
} | |
local oui_type_field = Field.new("nin_uds.oui_type") | |
local appdata_size_field = Field.new("nin_uds.appdata_size") | |
-- Helper function to retrieve the latest value of a field. | |
local function getFieldValue(field) | |
local tbl = { field() } | |
return tbl[#tbl]() | |
end | |
function dissect_tag20(tvbuf, pktinfo, tree) | |
tree:add(tag20_data, tvbuf:range(4, 3)) | |
end | |
function dissect_tag21(tvbuf, pktinfo, tree) | |
local subtree = tree:add("Network Info") | |
subtree:add(wlancommid, tvbuf:range(4, 4)) | |
subtree:add(id, tvbuf:range(8, 1)) | |
subtree:add(counter, tvbuf:range(9, 1)) | |
subtree:add(attributes, tvbuf:range(10, 2)) | |
subtree:add(network_id, tvbuf:range(12, 4)) | |
subtree:add(num_nodes, tvbuf:range(16, 1)) | |
subtree:add(max_nodes, tvbuf:range(17, 1)) | |
subtree:add(unk, tvbuf:range(18, 13)) | |
tree:add(data_hash, tvbuf:range(0x1F, 0x14)) | |
tree:add(appdata_size, tvbuf:range(0x33, 1)) | |
tree:add(appdata, tvbuf:range(0x34, getFieldValue(appdata_size_field))) | |
end | |
function dissect_tag24(tvbuf, pktinfo, tree) | |
tree:add(encrypted_data0, tvbuf:range(4, tvbuf:reported_length_remaining() - 4)) | |
end | |
function uds.dissector(tvbuf, pktinfo, root) | |
pktinfo.cols.protocol:set("NinUDS") | |
local pktlen = tvbuf:reported_length_remaining() | |
local tree = root:add(uds, tvbuf:range(0, pktlen)) | |
tree:add(oui, tvbuf:range(0, 3)) | |
tree:add(oui_type, tvbuf:range(3, 1)) | |
local specific_type = getFieldValue(oui_type_field) | |
if specific_type == 20 then | |
dissect_tag20(tvbuf, pktinfo, tree) | |
end | |
if specific_type == 21 then | |
dissect_tag21(tvbuf, pktinfo, tree) | |
end | |
if specific_type == 24 then | |
dissect_tag24(tvbuf, pktinfo, tree) | |
end | |
return pktlen | |
end | |
print("Nintendo UDS: Loaded") | |
-- Add our dissector to the dissector table | |
DissectorTable.get("wlan.tag.number"):add(TAG_VENDOR_SPECIFIC_IE, uds) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How do I use this?