我正在开发一个Wireshark插件,它必须解码通过将结构写入数据包而创建的大数据包。如果我能够知道原始结构的变量名称和偏移量,那么我将能够解码数据而不考虑原始编译器。结构很大(> 650字节)并包含复合元素和typedef。
结构的构造根据生成数据的软件版本而变化。我可以访问原始头文件和用于创建软件的编译器,因此我可以创建一个框架来提取我需要在Wireshark中使用的细节。
我已成功手动编码解码所需的一些变量和偏移量,但结构的大小和复杂性需要比我手工完成的更多自动化。
关于如何做到这一点的任何建议都是非常受欢迎的。
答案 0 :(得分:0)
免责声明:除了你在这里看到的,我自己并没有使用过这个,特别是在复杂的情况下;我只是将此作为答案发布,因为它比当前的答案缺乏更好,但如果这个答案中缺少更好的选项或关键信息,请不要感到惊讶。
使用-g
标志进行编译时,看起来调试信息中提供了所需的所有信息。您可以使用
objdump -Wi object_file.o
这不是最有用的格式,有些工具可以为您分析。其中一个是pahole
(sources,LWN article,man page);我没有用它来推荐它,但似乎至少值得进一步研究。它可能位于dwarves
或包管理器中的某个位置,因为它是处理DWARF调试信息的相关工具集合的一部分。
它似乎输出了你想要的信息,带有一些标志。解析原始C更容易,但它看起来更像是人类而不是计算机解析;我还没有找到一个看起来纯粹用于机器解析的标志。以下是pahole
运行示例:
输入struct.c
#include <stdint.h>
struct simple {
int32_t i32;
char c;
uint64_t u64;
} simple_object;
struct complicated {
struct simple nested_simple;
union {
float union_float;
uint32_t union_int;
} nested_union;
struct {
double d;
char c;
} nested_struct;
char some_chars[5];
struct simple_packed nested_simple_packed;
enum {COMPLICATED_ENUM1, COMPLICATED_ENUM2, COMPLICATED_ENUM3} enumeration;
} complicated_object;
跑完之后
gcc -g structs.c -c -o structs.o
pahole --expand_types structs.o
你得到了
struct simple {
/* typedef int32_t -> __int32_t */ int i32; /* 0 4 */
char c; /* 4 1 */
/* XXX 3 bytes hole, try to pack */
/* typedef uint64_t -> __uint64_t */ long unsigned int u64; /* 8 8 */
/* size: 16, cachelines: 1, members: 3 */
/* sum members: 13, holes: 1, sum holes: 3 */
/* last cacheline: 16 bytes */
};
struct complicated {
struct simple {
/* typedef int32_t -> __int32_t */ int i32; /* 0 4 */
char c; /* 4 1 */
/* XXX 3 bytes hole, try to pack */
/* typedef uint64_t -> __uint64_t */ long unsigned int u64; /* 8 8 */
} nested_simple; /* 0 16 */
union {
float union_float; /* 4 */
/* typedef uint32_t -> __uint32_t */ unsigned int union_int; /* 4 */
} nested_union; /* 16 4 */
/* XXX 4 bytes hole, try to pack */
struct {
double d; /* 24 8 */
char c; /* 32 1 */
} nested_struct; /* 24 16 */
char some_chars[5]; /* 40 5 */
/* XXX 3 bytes hole, try to pack */
enum {
COMPLICATED_ENUM1 = 0,
COMPLICATED_ENUM2 = 1,
COMPLICATED_ENUM3 = 2,
} enumeration; /* 48 4 */
/* size: 56, cachelines: 1, members: 5 */
/* sum members: 45, holes: 2, sum holes: 7 */
/* padding: 4 */
/* last cacheline: 56 bytes */
};