![](/img/trans.png)
[英]Linux: How to modify shared library name in Dynamic Section of an ELF binary
[英]How to get a pointer to a specific section of a dynamic library (Linux ELF)?
從這個問題的第二個答案中可以看出,使用節的名稱從內部獲取指向程序特定部分的指針非常簡單。 使用libelf
,只需打開程序自己的文件,遍歷其中的所有部分(由Elf64_Shdr
結構表示),當部分名稱與您想要的部分匹配時停止,並使用存儲在Elf64_Shdr
結構的sh_addr
元素中的Elf64_Shdr
。 在這種情況下,獲取所需指針非常簡單,因為它是在ELF可執行文件中定義的。
但是,假設您有一個使用動態庫的程序,您需要獲取指向該動態庫的一部分的指針。 由於其部分的地址是在運行時定義的,因此如何獲取指向動態庫部分的指針?
順便說一句,動態庫和主程序本身都有一個具有相同名稱的部分(這是我需要獲取指針的部分)。 因此,在這種情況下,這兩個具有相同名稱的部分是否可能相鄰存儲在內存中,因此我只需要獲取指向主文件部分的指針(如我在第一段中所述)並添加偏移量到達動態庫部分?
從內部獲取指向程序特定部分的指針非常簡單
不必要。 部分表在運行時實際上並不需要,並且可以完全剝離(只有段很重要,而不是段)。
由於其部分的地址是在運行時定義的,因此如何獲取指向動態庫部分的指針?
該庫與主可執行文件完全不同。 主要區別在於庫通常鏈接在地址0
(主可執行文件不是),並由運行時加載程序重定位到其他常量偏移量。
一旦你知道了這個偏移,只需將它添加到section start(你可以從readelf -S foo.so
或libelf中找到),並且瞧:你已經得到了該部分的運行時地址。
那么如何找到給定共享庫的重定位?
不太優雅的解決方案(已經由Nick建議)是解析/proc/self/maps
。
更好的解決方案是使用(glibc特定的) dl_iterate_phdr
。 文檔在這里 。 你會想要使用dlpi_addr
。
這很簡單,這里是一個例子:
#include <stdio.h>
int i __attribute__((section("my_section"))) = 2;
int j __attribute__((section("my_section"))) = 3;
int k __attribute__((section("my_section"))) = 5;
extern int __start_my_section;
extern int __stop_my_section;
int main(void)
{
int *p = &__start_my_section;
printf("%d\n", *p++); /* print k value */
printf("%d\n", *p++); /* print j value */
printf("%d\n", *p); /* print i value */
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.