簡體   English   中英

如何讓符號表中的 function 名稱指向不同的 function?

[英]How do I get a function name in the symbol table to point to a different function?

在 MacOS Ventura 上,使用 dlopen(NULL, 0) 獲取動態加載程序的句柄會返回包含整個可執行文件符號表的句柄。 使用這個句柄,可以獲得指向符號數據的指針,訪問和修改它們的內容,這些更改將滲透到整個程序中。 但是,嘗試使用函數指針進行此操作的方式不同。

例如,下面的代碼:

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

int my_var = 0;

int main() {
void *handle = dlopen(NULL, 0);
int *a = dlsym(handle, "my_var");
*a = 5;
printf("%d", my_var);
return 0;
}

將打印 5 而不是 0。但是,當嘗試使用 function 指針進行類似操作時:

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

typedef void (*ftype)(void);

void fun1() {
printf("a");
}

void fun2() {
printf("b");
}

int main() {
void *handle = dlopen(NULL, 0);
ftype f1ptr;
 *(void **)(&f1ptr) = dlsym(handle, "fun1");
f1ptr = fun2;
fun1();
return 0;
}

將打印 a 而不是 b。 有沒有辦法用 function 指針執行類似於第一個代碼段的操作? 本質上,我希望 fun1 現在指向 fun2 指向的代碼。 將 f1ptr 的類型交換為“ftype *”然后執行“*f1ptr = fun2”會導致總線故障。

但是,嘗試使用函數指針進行此操作的方式不同。

標識符命名為 object 或 function。function 的標識符不是 function 指針,並且您的示例未顯示代碼對對象或函數的工作方式不同。

In int *a = dlsym(handle, "my_var"); ,您的代碼獲得指向my_var的指針。 然后它使用*a = 5; 更改my_var的值。

*(void **)(&f1ptr) = dlsym(handle, "fun1"); ,您的代碼獲得了指向fun1的指針(盡管它處理不當,如下所述)。 所以f1ptr是指向fun1的指針。 它是指向 function 的指針,而不是指向 function 的指針。 如果函數可以某種方式修改,那么*f1ptr = …; 將修改 function。

但是,您不使用*f1ptr = …; . 你使用f1ptr = fun2; . 這只是改變f1ptr 它不會改變f1ptr指向的內容。 它不會改變fun1

fun1是 function 的標識符。它不是指針。 所以沒有指向改變的指針。 程序中無法使fun1成為不同的 function 或指向不同的 function。

關於為什么*(void **)(&f1ptr) = dlsym(handle, "fun1"); 是錯誤的,這表示獲取f1ptr的地址,將地址轉換為void ** ,並使用該 memory 位置,就好像它是void *一樣。 然后為 memory 位置分配dlsym返回的void *的值。 換句話說,您正在使用指向void的類型指針訪問指向函數 object f1ptr的指針。 這違反了 C 2018 6.5 7,它說 object 只能使用其定義的類型或某些其他類型進行訪問,其中任何一種都不允許使用void *訪問指向 function 的指針。

C 標准允許指向 function 的指針和指向void的指針在 memory 中具有不同的表示形式,甚至不同的大小,在這種情況下,此分配將“機械地”失敗; 寫入f1ptr的字節不適合用作指向函數的指針。 但即使在所有指針都具有相同表示的 C 實現中,此賦值也可能與編譯器的優化發生沖突。 它不應該被使用。

dlsym的結果分配給f1ptr的正確方法是將結果轉換為必要的類型:

f1ptr = (ftype) dlsym(handle, "fun1");

(這仍然不會讓您更改fun1 ;它只是向您展示如何正確使用dlsym 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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