我試圖複製一個功能,我必須一個可執行頁面,並從那裏運行它,但我似乎有一些問題。 這裏是我的代碼:複製功能到可執行頁面和調用
#include <stdio.h>
#include <string.h>
#include <windows.h>
int foo()
{
return 4;
}
int goo()
{
return 5;
}
int main()
{
int foosize = (int)&goo-(int)&foo;
char* buf = VirtualAlloc(NULL, foosize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (buf == NULL)
{
printf("Failed\n");
return 1;
}
printf("foo %x goo %x size foo %d\n", &foo, &goo, foosize);
memcpy (buf, (void*)&foo, foosize);
int(*f)() = &foo;
int ret1 = f();
printf("ret 1 %d\n", ret1);
int(*f2)() = (int(*)())&buf;
int ret2 = f2(); // <-- crashes here
printf("ret2 %d\n", ret2);
return 0;
}
我知道一些代碼在技術上是UB((INT)& goo-(INT)&富),但在這種情況下表現良好。
我的問題是爲什麼這不按預期工作? 在我看來,我把一個頁面映射爲可執行文件,並複製了一個現有的函數,我只是在調用它。
我在想什麼?
這對Linux的mmap會有不同的表現嗎? 在此先感謝
您已經給出了答案:因爲它是_undefined behaviour_。製作可執行代碼不僅僅是將二進制模式從A複製到B,搬遷。 – Olaf
我並不認爲'foo'和'goo'實際上可以保證連續放置在內存中。此外,這些函數可能包含與位置有關的代碼,這些代碼在將它們重新定位到另一個地址時不起作用。 –
另請參閱相關(可能重複)的問題[1](http://stackoverflow.com/questions/3717499/copy-and-call-function)和[2](http://stackoverflow.com/questions/4546071/copy-a-function-in-memory-and-execute-it) – Jester