[英]Dereferencing function pointers in C to access CODE memory
我們在這里處理C. 我只是有了這個想法,想知道是否可以訪問存儲函數的內存中的點,比如說foo
並將函數的內容復制到內存中的另一個點。 具體來說,我正在努力讓以下工作:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void foo(){
printf("Hello World");
}
int main(){
void (*bar)(void) = malloc(sizeof foo);
memcpy(&bar, &foo, sizeof foo);
bar();
return 0;
}
但運行它會出現總線錯誤: Bus error: 10
。 我正在嘗試將函數foo
的內容復制到內存bar
空間,然后執行新創建的函數bar
。
除了查看這樣的事情是否可能之外,沒有其他原因可以揭示C語言的復雜性。 我沒想到它有什么實際用途。
我正在尋找指導讓這個工作,或以其他方式被告知,有理由,為什么這不起作用
編輯查看一些答案並了解讀取 , 寫入和可執行內存,我突然意識到可以通過寫入可執行內存來在C中動態創建函數。
使用標准C,您嘗試執行的是實現定義的行為,並且無法移植。 在給定的平台上,您可以使這項工作成功。
內存malloc
為您提供通常不可執行的內容。 跳到那里會導致總線錯誤( SIGBUS
)。 假設您使用類似POSIX的系統,可以使用mmap
為函數分配內存,使用導致內存區域可執行的標志,或者使用mprotect
將區域標記為可執行文件。
你還需要更加小心你提供的內存量,你不能簡單地采用函數的大小並期望它是函數的長度, sizeof
不是為了提供這種功能而設計的。 您需要使用其他方法找出函數長度。
在現代桌面上,虛擬內存管理器會妨礙您。 內存區域有三種訪問類型: 讀取 , 寫入和執行 。 在代碼段僅具有執行權限的系統上, memcpy
將因總線錯誤而失敗。 在更典型的情況下,只有代碼段具有執行權限,您可以復制該函數,但不能運行,因為包含bar
的內存區域將不具有執行權限。
此外,確定功能的大小是有問題的。 考慮以下程序
void foo( int *x )
{
printf( "x:(%zu %zu) ", sizeof x, sizeof *x );
}
int main( void )
{
int x = 0;
foo( &x );
printf( "foo:(%zu %zu)\n", sizeof foo, sizeof *foo );
}
在我的系統上,輸出為x:(8 4) foo:(1 1)
表示獲取函數指針的sizeof
或函數本身不是受支持的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.