My first Lua Wireshark plugin
Introduction
In this blog post we will write a simple protocol dissector for Wireshark. Our very first dissector will analyze the Nordic Led Button Service, a very simple one-byte protocol on top of Bluetooth GATT protocol. Stay tuned!
Environment
This guide is based on the latest stable Wireshark release, which at the time of writing is 4.2.0
. I assume the reader has already installed it.
Prior art
Lua in Wireshark
Wireshark is written in C++, and historically so were all the plugins. The newer Lua API gives us access to a better prototyping language, which is great for a quick protocol reverse-engineering exercise.
The Wireshark Lua API is documented in the Wireshark Lua API reference.
The Lua API is essentially just bindings to the C++ API. It's useful to know to look at the C++ documentation whenever the Lua documentation is less than perfect. The last resort is to read the source code. Here are some resources:
- Wireshark dissector documentation
- README.dissector
- https://wiki.wireshark.org/uploads/moin_import/attachments/Lua/wsluarm.html
Note that the rendered documentation on wireshark.org is from the development branch of Wireshark, not the stable release. There will be discrepancies.
The Lua API is still a work in progress, and not all functionality is available, but it's already very workable. It's definitely a good idea to ensure you have the latest Wireshark.
Hello Lua-shark 🦈
Plugging Wireshark with Lua is easy. All Lua files under Wireshark's "Lua Plugins" path are run at startup. This includes sub-folders.1
The path to this folder on your machine can be found in the GUI:
Help -> About Wireshark -> Folders -> Personal Lua Plugins
The default location on Linux is ~/.local/lib/wireshark/plugins
.
The Lua plugins can easily be reloaded without restarting Wireshark.
Analyze -> Reload Lua plugins (Ctrl+Shift+L)
The above command resets the Lua environment just like restarting Wireshark. All definitions are cleared and the plugins are sourced again. But unlike restarting Wireshark, the state of the GUI stays mostly intact. This makes interactive development a breeze.
There is a rudimentary Lua REPL available in the GUI under Tools -> Lua Console. While the Console window is open, any print
from Lua is redirected there. Otherwise it goes to stdout.
Try it now: Create a file hello.lua
in the plugins folder with a hello world. Look for the print out in the console or stdout.
print("Hello 🦈!")
✂️ Snip, chomp, protocol.. (dissectors)
Wireshark needs specialized dissectors for each protocol to make heads or tails of it. This is the job of a protocol dissector. It will be our goal to teach an old Wireshark a new trick. The protocols known to your Wireshark are to be found in Analyse
-> Enabled Protocols
, and we will add a new one.
It's a protocol dissector's job to reassemble, parse, update packet info and payload trees, and select and run the next dissectors for any payloads it needs help with.
Hello dissector
The first step is to instantiate a protocol using the Proto
constructor and define the dissector function. To follow along, put the code in a file under the plugins folder.
local p = Proto('nordic_lbs_led', "Nordic LBS LED")
function p.dissector(tvb, pinfo, tree)
pinfo.cols.info:set("Hello from dissector")
end
After reloading, it shows up under Analyze -> Enabled protocols.
Don't ask me why it's yelling its name. It's your protocol.
Note that the order in which the files are sourced is not defined. archive.org link↩