2013-06-30 65 views
0

我正在嘗試編譯並運行代碼片段波紋管,它在Windows x86或WOW64 中工作,但在Windows x64中發生崩潰並出現訪問衝突錯誤。嘗試將32位代碼移植到64位平臺時出現內存錯誤

與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位環境?
什麼規則不符合,但應該是爲了正確工作這段代碼?

回答

3

您的系統可能有DEP - Data Execution Prevention。這意味着每個頁面都可以是可寫的可執行文件,但不能同時寫入。

在32位系統上,您需要使用SetProcessDEPPolicy才能在當前進程中禁用它。

在64位系統中,您應分配使用PAGE_EXECUTE_READWRITE - 像

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

你可能想看到thisthis問題,this例子。


正如已經指出的那樣,這並不保證它會奏效。

  1. 據我所知,C編程語言不能保證這樣的複製將產生一個明智的可調用函數。
  2. 如果該函數不是頁面對齊的(很可能),並且未分配下一頁,則會發現自己試圖從未分配的內存中讀取數據。因此,您必須以某種方式確定函數的確切時間。
+0

感謝您的指導! SetProcessDEPPolicy return GetLastError() - 50 - 請求不受支持。 正如MSDN所說,它僅支持32位進程。 – boleto

+0

@boleto你是對的。我編輯了答案。 – Elazar

+0

您提供的鏈接http://icebuddha.com/slopfinder.htm可用於檢查可執行文件(.exe)是否啓用了DEP保護(數據執行保護)。 –