【发布时间】:2023-03-16 05:43:01
【问题描述】:
所以我有一个叫做数据包的构造
struct Packet {
unsigned int packet_type;
wchar_t packet_length[128];
wchar_t file_name[256];
wchar_t template_name[256];
wchar_t file_name_list[1024];
wchar_t file_data[1024];
void serialize(char * dat) {
memcpy(dat, this, sizeof(Packet));
}
void deserialize(const char * dat) {
memcpy(this, dat, sizeof(Packet));
}
};
我正在尝试从这些数据中反序列化
{byte[2692]}
[0] 0 unsigned int packet_type; (4 bytes)
[1] 0
[2] 0
[3] 0
[4] 50 '2' wchar_t packet_length[128]; (128 bytes)
[3] 0
[5] 54 '6'
[3] 0
[6] 57 '9'
[3] 0
[7] 50 '2'
[8] 0
[...] 0
[132] 112 'p' wchar_t file_name[256]; (256 bytes)
[133] 0
[134] 104 'h'
[...] 0
但是反序列化中的 memcpy 没有给我文件名,但它确实给了我数据包长度。这是怎么回事?谢谢!
编辑: 所以现在我很清楚 wchar_t 占用的空间比我以前想象的要多;但是,我被告知根本不要使用 memcpy?
我已经编写了这个反序列化方法,它可以正确抓取数据。这还会导致安全漏洞吗?
void deserialize(const char * dat) {
memcpy(&(packet_type), dat, 4);
memcpy(&(packet_length[0]), dat + 4, 128);
memcpy(&(file_name[0]), dat + 132, 256);
memcpy(&(template_name[0]), dat + 388, 256);
memcpy(&(file_name_list[0]), dat + 644, 1024);
memcpy(&(file_data[0]), dat + 1668, 1024);
}
【问题讨论】:
-
在您的目标系统上仔细检查
wchar_t的大小。我打赌它不是 1 字节,所以你对大小的期望是错误的。wchar_t file_name[256]应该至少是 512 字节而不是 256。然后给出你问题的最后一部分,我敢打赌你正在查看数组中的错误偏移量。 -
请不要使用幻数来表示类型大小(例如,4 表示无符号整数的大小)。最安全的方法是使用 sizeof(varname)。这不仅考虑了 varname 类型的大小,还处理了 varname 类型被更改的实例。
标签: c++ char bytearray deserialization memcpy