簡體   English   中英

在C中取消引用函數指針以訪問CODE內存

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM