3个版本 (破坏性更新)
0.3.0 | 2022年5月30日 |
---|---|
0.2.0 | 2022年5月23日 |
0.1.0 | 2022年5月7日 |
#3 in #dissector
32KB
520 行
目录
概述
Wirdigen (Wireshark DiGenerator) 是一个小的库,旨在根据要分析的包的JSON描述生成Wireshark的LUA dissector。
有关数据解包的更多信息,请参阅Wireshark 文档 和 维基。
如何使用
该库由两个工具组成
验证器
Validator
将JSON包描述与预定义的JSON模式进行比较,以确保插件生成时的数据完整性。
如果包描述无效,将通过 stderr
自动向用户报告错误,并提供详细的/描述。
use wirdigen::validator::Validator;
use wirdigen::error::WirdigenError;
fn foo() -> Result<(), WirdigenError> {
// Load JSON file
let file_path = "./example/example_dissector.json";
let file = File::open(file_path)?;
let rdr = BufReader::new(file);
// Create serde JSON value from the file
let value: Value = serde_json::from_reader(rdr)?;
// Create Validator object
let val = Validator::new()?;
// Call to validation function
match val.validate(&value) {
true => println!("{}: VALID", file_path),
false => println!("{}: INVALID", file_path)
}
Ok(())
}
生成器
Generator
生成基于用户提供的JSON输入的LUA插件。
use wirdigen::generator::Generator;
use wirdigen::error::WirdigenError;
fn foo() -> Result<(), WirdigenError> {
// Load JSON file
let file_path = "./example/example_dissector.json";
let file = File::open(file_path)?;
let rdr = BufReader::new(file);
// Create Generator object
let gen = Generator::default();
// let gen = Generator::new(); <-- Alternative
// Generate from a reader source
let generated_file_path: String = gen.from_reader(rdr)?;
println!("Generated: {}", generated_file_path);
Ok(())
}
注意: Generator
不会对用户输入执行任何预验证。这是 Validator
的作用。在文件无效的情况下,Generator
的方法将返回适当的 Err(WirdigenError)
。为了避免这些问题,最好首先进行验证,然后生成LUA dissector。
Generator
对象还有一个 from_value
方法,以便重用验证任务中的serde-json Value
。
fn foo() -> Result<(), WirdigenError> {
// Open the JSON file
let file_path = "./example/example_dissector.json";
let file = File::open(file_path)?;
let rdr = BufReader::new(file);
// Create serde JSON value from the file
let value: Value = serde_json::from_reader(rdr)?;
// Create Validator object
let val = Validator::new()?;
// Call to validation method
if val.validate(&value) {
// Create Generator object
let gen = Generator::default();
// Generate plugin from validated data
let generated_file_path: String = gen.from_value(value)?;
println!("{}", generated_file_path);
}
else {
println!("Invalid user input: {}", file_path);
}
Ok(())
}
默认情况下,插件是在环境变量中定义的临时文件夹中生成的。用户可以通过 set_output_directory()
方法修改输出目录,并通过 get_output_directory()
方法检索当前目录。
fn foo {
let mut gen = Generator::default();
println!("{}", gen.get_output_directory());
let new_output = "/Documents/MyDissectors";
gen.set_output_directory(new_output);
println!("{}", gen.get_output_directory());
}
注意: 方法 set_output_directory
不会根据用户输入创建不存在的目录。如果输出目录不可达,则在尝试创建最终LUA文件时,生成方法将传播错误。
Dissector格式
JSON dissector描述由4个元素组成
名称
Endianness
连接
数据
名称
name
元素是一个字符串(最大长度:32),表示要分析的协议名称,该名称将在 Wireshark 中("协议"列)用于识别您的数据包。
注意: 此名称也用于生成的 LUA 文件。例如,如果属性是 MY_PROTO
,则生成的插件将被命名为 dissector_MY_PROTO.lua
。
字节序
定义协议使用的字节序的字符串。可能的值是 little
和 big
。
连接
connection
对象包含 2 个字段
protocol
:字符串。可以是udp
或tcp
。ports
:需要监视的端口号数组(介于 1 和 65535 之间)。
数据
data
是一个对象数组,用于描述数据包。每个对象定义了我们想要识别的数据包的一部分。
每个块包含以下属性
name
:字符串(最大长度:32)。format
:表示块数据类型的字符串。有关可用值,请参阅下面的格式/基础矩阵。base
:表示值应如何显示的字符串。有关可用值,请参阅下面的格式/基础矩阵。offset
:从数据包开始的位置偏移量(以字节为单位)。size
:数据包内块的长度(以字节为单位)。valstr
(可选): 值/字符串对象数组,用于在有效负载中识别特定值。有关更多信息,请参阅下文。
关于 strval
此属性可用于通过其字符串表示形式识别和替换特定值(最大长度:32)。例如,当处理网页状态码时,在 Wireshark 捕获视图中查看状态码 404
作为 "NOT FOUND"
或 200
作为 "OK"
可能很有用。此示例可以描述如下 dissector JSON 文件中
{
..., // First part of data chunk description
"valstr" : [
{ "value": 404, "string": "NOT FOUND" },
{ "value": 200, "string": "OK"}
]
}
格式/基础兼容性矩阵
这些矩阵显示 Wirdigen 支持哪些格式/基础组合。
数字
格式 \ 基础 | NONE | DEC | OCT | HEX | DEC_HEX | HEX_DEC |
---|---|---|---|---|---|---|
bool | X | |||||
char | X | X | ||||
uint8 | X | X | X | X | X | |
uint16 | X | X | X | X | X | |
uint24 | X | X | X | X | X | |
uint32 | X | X | X | X | X | |
uint64 | X | X | X | X | X | |
int8 | X | |||||
int16 | X | |||||
int24 | X | |||||
int32 | X | |||||
int64 | X | |||||
float(*) | X | X | X | X | X | X |
double(*) | X | X | X | X | X | X |
(*) = 对于指定的 format
,Wireshark 会忽略 base
。
时间
格式 \ 基础 | LOCAL | UTC | DOY_UTC |
---|---|---|---|
absolute_time | X | X | X |
relative_time(*) | X | X | X |
(*) = 对于指定的 format
,Wireshark 会忽略 base
。
原始
格式 \ 基础 | NONE | DOT | DASH | COLON | SPACE |
---|---|---|---|---|---|
byte | X | X | X | X | X |
特定
对于这些特定类型的数据,显示将由 Wirehsark 自动处理。因此,在这种情况下建议使用 NONE
。
- none
- ipv4
- ipv6
- ether
- guid
- oid
将解复用器导入 Wireshark
首先,您需要检查 Wireshark 在哪个目录中查找 LUA 插件。
为此,请打开 Wireshark 并转到 帮助 -> 关于 Wireshark -> 文件夹
。
找到与 "个人 Lua 插件"
相关的路径。这是您需要复制解复用器的位置。如果您的机器上不存在该路径,您可以手动创建缺失的目录。
解包脚本将在Wireshark刷新后生效。您可以重新启动Wireshark或按Ctrl + Shift + L重新加载所有Lua脚本。
注意:每次修改解包脚本时,都需要重新加载/重启。
路线图
-
缺少数据类型
- framenum
- 字符串
- 字符串z
- ubytes
- 协议
- rel_oid
- systemid
- eui64
-
支持子树,以便清晰地描述更复杂的数据包。
相关工具
- rust_dissector_generator:使用Wirdigen库的简单可执行文件
- rust_dissector_udp:通过UDP发送自定义数据包,以在Wireshark内部测试由库生成的插件。
依赖项
~10–19MB
~276K SLoC