I found very useful example of heuristic tables usage in Lua.
a link
But it doesn't not cover my case.
I've written custom dissector in lua. Described custom protocol has many subprotos. So I create new subdissectors table DissectorTable.new() and register new subprotos.
But some of subprotocols doesn't have identification sign and their types must be found out dynamically.
I hoped to register heuristic dissector with proto:register_heuristic() method, but there is no my new table in DissectorTable.heuristic_list() list.
Creating new dissector table does not create heuristic dissectors table.
Is there a way to create new own heuristic dissectors table?
There is no way to create a real heuristic dissector table for your protocol in the current Lua API, but I'm not sure it makes a lot of sense to have such a thing. The purpose of having a protocol create a heuristic dissector table for itself is so that other protocols can register their heuristic dissectors into it - for example the UDP protocol creates a heuristic dissector table named "udp", so that other protocols like RTP, STUN, Skype, etc., can all register their heuristic dissectors into it, and UDP can try them all without knowing about them before-hand.
But when you create a new protocol in a Lua plugin, no other code is going to know about your new protocol or any heuristic dissector table you create. Only your own Lua code will know about it. Obviously your new protocol might have subprotocols that need to be tried heuristically, as you appear to need, but you don't need a heuristic dissector table to do that - just call your subprotocols's heuristic dissector functions directly in Lua.
For example:
local myProto = Proto("myproto", "My Main Protocol")
local mySubproto1 = Proto("mysubproto1", "My First Sub-Protocol")
local mySubproto2 = Proto("mysubproto2", "My Second Sub-Protocol")
-- the sub-prpotocol's heuristic function
-- returns true if the packet is its protocol and it dissected it
-- otherwise returns false
function heur_dissect_mySubproto1(tvbuf, pktinfo, root)
-- see if the passed in tvb is Subproto1 protocol
-- and if so then add tree items and such or
-- call mySubproto1's normal dissector function to do that stuff
return is_Subproto1
end
function heur_dissect_mySubproto2(tvbuf, pktinfo, root)
-- see if the passed in tvb is Subproto2 protocol
return is_Subproto2
end
function myProto.dissector(tvbuf, pktinfo, root)
-- do stuff for my main protocol
-- create a new sub-tvb of what has not been processed by the main protocol
local newTvb = tvbuf(bytes_parsed_by_myproto):tvb()
-- call the heuristic dissector functions of my sub protocols
-- with the portion of the tvb that belongs to them
if heur_dissect_mySubproto1(newTvb, pktinfo, root) then
-- do here anything you need to afterwards
elseif heur_dissect_mySubproto2(newTvb, pktinfo, root) then
-- do here anything you need to afterwards
end
end
or if you want to be fancier, use a table of your own...
local myProto = Proto("myproto", "My Main Protocol")
local mySubproto1 = Proto("mysubproto1", "My First Sub-Protocol")
local mySubproto2 = Proto("mysubproto2", "My Second Sub-Protocol")
-- a heuristic dissector table for myProto
local myProto_heuristic_table = {}
-- a function to register into myProto's heuristic table
local function register_heuristic(func)
myProto_heuristic_table[#myProto_heuristic_table + 1] = func
end
function heur_dissect_mySubproto1(tvbuf, pktinfo, root)
-- do stuff
return is_Subproto1
end
-- "register" the above function
register_heuristic(heur_dissect_mySubproto1)
function heur_dissect_mySubproto2(tvbuf, pktinfo, root)
-- do stuff
return is_Subproto2
end
register_heuristic(heur_dissect_mySubproto2)
function myProto.dissector(tvbuf, pktinfo, root)
-- do stuff for my main protocol
local newTvb = tvbuf(bytes_parsed_by_myproto):tvb()
-- call the heuristic dissector functions of my sub protocols
-- with the portion of the tvb that belongs to them
for _, func in ipairs(myProto_heuristic_table) do
-- call the heuristic
if func(newTvb, pktinfo, root) then
-- do here anything you need to afterwards
return
end
end
end
Related
I have a Lua Wireshark dissector that is structured like so:
-- Initialize Protocol
-- Initialize Protocol Fields
-- Register Protocol Fields
-- DissectionFunction(tvbuf, pktinfo, root)
-- Initialize Protocol
-- Function definitions.
I have a function written that I'd like to use to calculate some values, and then use those values in the dissector. So I wrote my function outside the dissection function and in the function definitions section.
But the function call also works within the dissector function, if called outside the dissector function Wireshark does not recognize it. Calling it in the dissection function is very inefficient, as it only needs to be executed once and will be executed for every frame instead.
Is there a way to call it once outside the dissection function?
I'm not quite sure of what the question is, but you can do the following in Lua
local function calculate_constant_value()
return a * b + c
end
local my_constant_value = calculate_constant_value()
function proto.dissector()
-- use my_constant_value here
end
I'm writing a chained dissector in Lua for the Ethercat protocol. I named my chained dissector littlecat.
For what I have so far, littlecat correctly dissects the fields I want it to. However, instead of executing after the built in ecat dissector, littlecat takes it over completely.
This is what the registration at the end of my Lua code looks like.
-- Initialize Protocol
function littlecat.init()
end
-- Register Chained Dissector Ethercat Port
local ethercat_dissector_table = DissectorTable.get("ecatf.type")
dissector = ethercat_dissector_table:get_dissector(1)
-- Dissector can be called from littlecat.dissector
-- So the previous dissector gets called
ethercat_dissector_table:add(1, littlecat)
How can I have my dissector execute after ecat has been executed?
I found a solution.
To ensure that the default dissector is called, and then the custom dissector:
Define the dissector table and original dissector before the dissection function.
Call original dissector within the dissection function.
Example
-- Initialize Protocol
-- Initialize Protocol Fields
-- Define dissector table and default dissector here
-- so they can be called within the dissection func.
local dissector_table = DissectorTable.get("shortname")
dissector = dissector_table:get_dissector(PORT)
-- Dissection Function
function dissectorname.dissector (tvbuf, pktinfo, root)
-- Call default dissector.
dissector(tvbuf, pktinfo, root)
-- Continue dissection....
end
-- Initialize Protocol
function dissectorname.init()
end
-- Dissector can be called from dissectorname.dissector
-- So the previous dissector gets called
dissector_table:add(PORT, dissectorname)
I wrote a lua function write_json which translates lua table into json text.
Is it possible to bind the function with the io library, so that I can use it like this:
mytable = {name="Jack", age="22", score=[12,33,55,66]}
f = io.open("score.json", "wb")
f:write_json(mytable) -- call my function here.
f:close()
You need access to the __index table of the metatable for file objects and put your new methods there:
local metatable = getmetatable( io.stdout )
local indextable = metatable.__index
indextable.write_json = function( file, tab )
-- ...
end
There is another way: The C API function luaL_newmetatable stores the metatable for file objects in the registry under the key "FILE*", so the following will also work (but requires the debug library):
local metatable = debug.getregistry()["FILE*"]
local indextable = metatable.__index
-- ...
There is yet another (more hackish) way: All Lua versions I tested (PUC-Rio Lua 5.1, 5.2, 5.3, and LuaJIT) set the __index field of the metatable to the metatable itself, so you can get at the __index table like that:
local indextable = io.stdout.__index
The best way is probably the first one.
The type of the object returned by io.open is userdata, which I believe cannot be monkey-patched due to its unique nature.
Good day, I'm trying to understand a little more NSE scripts that are based on Lua, but there is something that I can't understand related to syntax when using functions as elements from a table. I'm going to show parts of the script nmap/scripts/broadcast-rip-discver.nse where I'm getting lost:
RIPv2 = {
-- The Request class contains functions to build a RIPv2 Request
Request = {
-- Creates a new Request instance
--
-- #param command number containing the RIPv2 Command to use
-- #return o instance of request
-- code ommitted (give values to the table o)
setmetatable(o, self)
self.__index = self
return o
end,
-- Converts the whole request to a string
__tostring = function(self)
--- -- code ommitted ( Override the metafunction __tostring)
return data
end,
},
-- The Response class contains code needed to parse a RIPv2 response
Response = {
-- Creates a new Response instance based on raw socket data
--
-- #param data string containing the raw socket response
-- #return o Response instance
new = function(self, data)
local o = { data = data }
-- code ommitted (Read from data and pass values to o)
setmetatable(o, self)
self.__index = self
return o
end,
}
}
And from the "action" part of the script we have a use like this
local rip = RIPv2.Request:new(RIPv2.Command.Request)
local response = RIPv2.Response:new(data) -- Data has been already give a value
I understand that is "similar" to create a new instance of the Table RIPv2 for those two lines. As all the function are inside of a table (that is not a class because Lua only have basic tools for make things similar but no the same to class) so the "self" argument it's mandatory for Lua have a idea to where place that.
But what I can't understand it's why try to override functions from the table RIPv2 to the table o, I mean the lines what objective has?:
setmetatable(o, self) )
I understand that the variable table o could have now the same functions that RIPv2 together his own values but this part make me crazy and I can't find a straight answer at Nmap's Forum.
P.d. which would be the difference to declare RiPv2 with "local" (Be sure that is not a Global variable)
As all the function are inside of a table so the "self" argument it's mandatory for Lua have a idea to where place that.
All the functions aren't necessarily part of the table. A metatable allows you to specify that lookups in table a can resolve to lookups in table b, and that's exactly what's being done here.
But what I can't understand it's why try to override functions from the table RIPv2 to the table o, I mean the lines what objective has?: setmetatable(o, self) )
o is an instance of a class, it contains only the instance data. The methods are stored in class objects Request or Response. The metatable allows attempts to index o to resolve via the class object.
See the Programming in Lua chapter on classes.
Say I declare a lua function using the : operator like so:
function ClassName:myFunc( stuff )
--do stuff
end
And then say I store that function in a table like so:
someTable = {
ClassName.myFunc,
someGlobalFunc,
}
And then, say I have another function that goes through the table and attempts to call the given functions.
function ClassName:callStuffInThisTable(table)
-- I go through the table, which might be someTable above, and call all the functions
end
My question is, how do I know if a function in the table is owned by ClassName, so that I can call it using self?
You don't. At least, Lua isn't going to tell you.
function ClassName:myFunc( stuff ) is just syntactic sugar as far as Lua is concerned. It's no different from this: ClassName.myFunc = function (self, stuff). The functions are equivalent.
Likewise for the : call syntax, ClassName:myFunc(stuff) is semantically equivalent to ClassName.myFunc(ClassName, stuff).
It is up to you to know what your functions are and what they do. This requires coding discipline. If you have a list of functions that you need to call in a loop, then they should be designed to be called with the same parameters.
There are two ways to do this. One way is to make all of the functions "class functions":
someTable = {
ClassName.myFunc,
function(self, ...) return someGlobalFunc(...) end,
}
This way, the self parameter is ignored. Obviously, you could create a special function table object that has functions for inserting "global" functions into the table that will automatically generate the wrapper:
function insertFuncIntoTable(self, func)
self[#self + 1] = function(self, ...) func(...) end
end
insertFuncIntoTable(someTable, someGlobalFunc)
Note: there is a difference between these, assuming "someGlobalFunc" is actually a member of the global table (rather than a local). This version will take the value that _G["someGlobalFunc"] currently has, just as your original code does. However, the first version takes the value that it has at the time it is called, which may be a different function from the one it was at the time someTable was created.
So this version is safer.
Alternatively, you can make it so that any "class functions" in the table are explicitly bound to an object instance:
someTable = {
function(self, ...) ClassName.myFunc() end,
function(self, ...) return someGlobalFunc(...) end,
}
BTW, in general, if you declare a function using : syntax, you're supposed to use that function that way, via instance:myFunc(...). Obviously it's just a Lua function like any other, so you can do what you like. But misuse can make understanding what's going on harder.
Lua affords you a lot of power. But you're still required to exercise judgement and discipline when coding. Lua will not save you from yourself (entirely).
One way to tell if the function is "owned" by ClassName would be to scan and check.
ClassName = {}
function ClassName:fn(self) ... end
t = { function() ... end , ClassName.fn() }
function has_value( klass, value )
for k,v in pairs(klass) do
if v==value then return true
end
return false
function ClassName:callStuffInThisTable(table)
for k,v in pairs(table) do
if has_value(ClassName, v) then
v(self)
else
v()
end
end
end
This has O(n^2) behaviour though due to the table scan. We can reduce this to O(n log(n)) ) by using the functions in ClassName as a new table
function ClassName:callStuffInThisTable(table)
local t = {}
for k,v in pairs(ClassName) do
t[v] = 1
end
for k,v in pairs(table) do
if t[v]==1 then
v(self)
else
v()
end
end
end