0

我正在尝试编译和运行下面的代码片段,它在 Windows x86 或 WOW64 中工作,但在 Windows x64 中,他因访问冲突错误而崩溃。

使用 gcc 和 Microsoft C/C++ 编译器进行编译。

/*Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64
 (x64)cl -W3 -Zi tx.c -Fetx64
 (x86)cl -W3 -Zi tx.c -Fetx32

 gcc (tdm64-1) 4.7.1
 (x64)gcc -m64 -Wall -O2 -o tx64 tx.c
 (x86)gcc -m32 -Wall -O2 -o tx32 tx.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int (*fpPUTS)( const char *str ); /*function pointer that takes an const char * as an argument and returns int*/                                          
typedef void (*fpMEMEXEC)( fpPUTS pPuts, char *str ) ;/*function pointer on which first argument is pointer to above function*/

void toMem( fpPUTS pPuts, char *str )
{
    pPuts( str );
}   

int main(int argc, char* argv[])
{
    fpMEMEXEC   pMemexec;
    pMemexec = (fpMEMEXEC) malloc(4*1024);/* Allocate 4 KB memory space to the function pointer */
    memcpy( pMemexec, toMem, 4*1024);    /*  Copy the content of toMem into newly allocated memory */
    pMemexec( puts, "Hello word !!\n"); /* execute it in memory */
    return 0;
}

我的问题是,为什么这段代码在 64 位环境下不能正常工作?
哪些规则没有得到满足,但应该是为了让这段代码正常工作?

4

1 回答 1

3

您的系统可能具有DEP-数据执行保护。这意味着每个页面都可以是可写的可执行的,但不能两者兼而有之。

在 32 位系统上,您需要使用SetProcessDEPPolicy才能为当前进程禁用它。

在 64 位系统上,您应该使用PAGE_EXECUTE_READWRITE进行分配- 类似于

pMemexec = VirtualAlloc(0, 4*1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

你可能想看看这个这个问题,还有这个例子。


正如已经指出的那样,这并不能保证它会起作用。

  1. 据我所知,C 编程语言不能保证这样的复制会产生一个合理的可调用函数。
  2. 如果函数不是页面对齐的(这很可能)并且没有分配下一页,您会发现自己试图从未分配的内存中读取。因此,您必须以某种方式确切地找到该函数的长度。
于 2013-06-30T15:04:41.410 回答