C 尝试将32位代码移植到64位平台时出现内存错误

C 尝试将32位代码移植到64位平台时出现内存错误,c,windows,64-bit,win64,dep,C,Windows,64 Bit,Win64,Dep,我正在尝试编译和运行下面的代码片段,它在Windowsx86或WOW64中工作 但在Windowsx64中,他因错误访问冲突而崩溃 使用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

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

使用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;
}
/*针对x64的Microsoft(R)C/C++优化编译器版本15.00.30729.01
(x64)cl-W3-Zi tx.c-Fetx64
(x86)cl-W3-Zi tx.c-Fetx32
通用条款(tdm64-1)4.7.1
(x64)gcc-m64-壁-O2-o tx64 tx.c
(x86)gcc-m32-Wall-O2-o tx32 tx.c
*/
#包括
#包括
#包括
typedef int(*fpput)(常量字符*str)/*以常量char*作为参数并返回int*/
typedef void(*fpMEMEXEC)(fpPUTS pput,char*str)/*第一个参数是指向上述函数的指针的函数指针*/
无效时间(fpPUTS pPuts,字符*str)
{
pPuts(str);
}   
int main(int argc,char*argv[])
{
fpMEMEXEC-pMemexec;
pMemexec=(fpMEMEXEC)malloc(4*1024);/*为函数指针分配4KB的内存空间*/
memcpy(pMemexec,toMem,4*1024);/*将toMem的内容复制到新分配的内存中*/
pMemexec(puts,“Hello word!!\n”);/*在内存中执行它*/
返回0;
}
我的问题是,为什么这段代码不能在64位环境下正常工作?
为使此代码正常工作,哪些规则未满足,但应满足?

您的系统可能有-。这意味着每个页面可以是可写的,也可以是可执行的,但不能同时是可写的和可执行的

在32位系统上,您需要使用以在当前进程中禁用它

在64位系统上,您应该使用

pMemexec = VirtualAlloc(0, 4*1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
您可能希望看到和问题,以及示例


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

  • 据我所知,C编程语言不能保证这样的复制会产生一个合理的可调用函数
  • 如果函数没有对齐页面(这是可能的),并且没有分配下一页,则您会发现自己试图从未分配的内存中读取。因此,您必须准确地找到函数的长度
  • 您的系统可能有-。这意味着每个页面可以是可写的,也可以是可执行的,但不能同时是可写的和可执行的

    在32位系统上,您需要使用以在当前进程中禁用它

    在64位系统上,您应该使用

    pMemexec = VirtualAlloc(0, 4*1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
    您可能希望看到和问题,以及示例


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

  • 据我所知,C编程语言不能保证这样的复制会产生一个合理的可调用函数
  • 如果函数没有对齐页面(这是可能的),并且没有分配下一页,则您会发现自己试图从未分配的内存中读取。因此,您必须准确地找到函数的长度

  • 谢谢你的指导!SetProcessDEPPolicy返回GetLastError()-50-不支持该请求。正如MSDN所说,它仅支持32位进程。您提供的链接有助于检查可执行文件(.exe)是否启用了DEP保护(数据执行预防)。感谢您提供的指导!SetProcessDEPPolicy返回GetLastError()-50-不支持该请求。正如MSDN所说,它仅支持32位进程。您提供的链接用于检查可执行文件(.exe)是否启用了DEP保护(数据执行预防)。