为什么我收到此 memcpy 函数的 "Access Violation" 错误?

Why am I receiving an "Access Violation" Error on this memcpy function?

当 运行 这个程序在 Visual Studio 时,当程序到达 memcpy 函数时,我收到一个“访问冲突”错误。无论我将此缓冲区设置为多大,它总是会抛出此读取访问冲突错误。我在 memcpy 函数中设置了断点,一旦我继续执行,它就会抛出这个错误:

snip of error

char data[DATA_SIZE] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
#define DATA_SIZE 27136

void spawn(void * buffer, int length, char * key);

typedef struct {
    int  offset;
    int  length;
    char key[4];
    int  gmh_offset;
    int  gpa_offset;
    char payload[DATA_SIZE];
} phear;

extern char data[DATA_SIZE];
void start(HINSTANCE mhandle) {
    
    phear * payload = (phear *)data;
    char * buffer;

    buffer = (char *)malloc(payload->length);
    memcpy(buffer, payload->payload, payload->length);

    /* execute our code */
    spawn(buffer, payload->length, payload->key);

    /* clean up after ourselves */
    free(buffer);
}

这里有几个问题:

  • data 可能未正确对齐 phear。参见 What is aligned memory allocation?
  • payload->length 是一个严格的别名冲突:这被定义为 (*payload).length 并且表达式 *payload 通过 phear 类型的表达式访问内存但是没有对象在该位置属于 phear 类型。
  • (如果我们暂时忽略上面两个问题)memcpy读取越界是因为sizeof data < sizeof(phear).

一个简单的解决方案是使用 extern phear data; 而不是 char 数组。如果你真的想使用 char 数组,那么使用 memcpy 而不是结构访问将数据复制进出它。