无法正确地将char数组memcpy到结构体 [英] Cannot properly memcpy a char array to struct

查看:2687
本文介绍了无法正确地将char数组memcpy到结构体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个名为packet的结构。

So I have a construct called packet

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));
    }
};

我试图从这些数据中去除分层

I'm trying to desieralize from this data

{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

但是,在deserialze中的memcpy不是给我的file_name,但它给了我packet_length。这是什么?谢谢!

But the memcpy in deserialze isn't giving me the file_name, but it does give me the packet_length. What's up with this? Thanks!

编辑:
现在我清楚地知道,wchar_t比我曾经想过的占用更多的空间;但是,我被告知不要使用memcpy?

So it's clear to me now that wchar_t is taking up more space than I once thought; however, I'm being told not to use memcpy at all?

我写了这个反序列化方法,它正确地获取数据。这会仍然导致安全漏洞?

I've written this deserialize method and it grabs the data correctly. Will this still cause a security leak?

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);
    }


推荐答案

c $ c> char 数组假定 wchar_t 的大小是两个字节;这不是一个系统的例子,其中 wchar_t 的大小是 4 ,所以大小 10756 ,而不是 2692 字节: =http://ideone.com/dLf0pn =nofollow>链接到演示)。

The layout of your char array assumes that the size of wchar_t is two bytes; it is not - here is an example of a system where the size of wchar_t is 4, so the size of Packet is 10756, not 2692 bytes: (link to a demo).

这就是为什么你的 memcpy 从编辑的技巧提出了一个问题:它假设在 char [] 数组中的数据布局匹配的布局 wchar_t [] 数组,它可能匹配也可能不匹配。如果您知道您的数据数组有两个字符的元素以小尾数格式存储(LSB优先),您可以编写自己的函数将数据从源转换为目标,并调用它为部分序列化数据,如this:

That is why your memcpy trick from the edit presents a problem: it assumes that the layout of data in the char[] array matches the layout of wchar_t[] arrays, which it may or may not match. If you know that your data array has two-character elements stored in little endian format (LSB first), you can write your own function that converts the data from the source to the destination, and call it for portions of your serialized data, like this:

void bytes_to_wchar(wchar_t *dest, const unsigned char* src, size_t length) {
    for (size_t i = 0 ; i != lengt ; i++) {
        dest[i] = src[2*i] | (src[2*i+1] << 8);
    }
}

现在您可以使用此函数将数据复制到 wchar_t 数组独立于目标系统上的 wchar_t 大小或目标系统的字节序:

Now you can use this function to copy data into wchar_t arrays independently of the wchar_t size on the target system, or the endianness of the target system:

void deserialize(const char * dat) {
    bytes_to_wchar(packet_type,       dat + 0,      4);
    bytes_to_wchar(packet_length[0],  dat + 4,    128);
    bytes_to_wchar(file_name[0],      dat + 132,  256);
    bytes_to_wchar(template_name[0],  dat + 388,  256);
    bytes_to_wchar(file_name_list[0], dat + 644,  1024);
    bytes_to_wchar(file_data[0],      dat + 1668, 1024);
}

从内存中保存数据和写回数据的快捷方式可能在您做在同一个硬件上,使用相同的编译器。即使这样,它仍然对您使用的头文件和编译器设置中的小调整保持敏感。

The shortcut of saving the data from memory and writing it back may work when you do it on the same hardware, using the same compiler. Even then it remains sensitive to small adjustments in the headers that you use and in the settings of the compiler.

如果需要复制到 struct 有一个固定的布局,你需要编写一个函数来处理该布局,将两字节组转换为 wchar_t 四字节组成 unsigned int s等。

If the character array that you need to copy into the struct has a fixed layout, you need to write a function to process that layout, converting two-byte groups into wchar_ts, four-byte groups into unsigned ints, and so on.

这篇关于无法正确地将char数组memcpy到结构体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆