簡體   English   中英

如何在我的程序中獲取 _GLOBAL_OFFSET_TABLE_ 地址?

[英]How can I get the _GLOBAL_OFFSET_TABLE_ address in my program?

我想在我的程序中獲取 _GLOBAL_OFFSET_TABLE_ 的地址。 一種方法是在 Linux 中使用nm命令,可能會將輸出重定向到一個文件並解析該文件以獲取 _GLOBAL_OFFSET_TABLE_ 的地址。 然而,這種方法似乎非常低效。 有哪些更有效的方法呢?

這似乎有效:

// test.c
#include <stdio.h>

extern void *_GLOBAL_OFFSET_TABLE_;

int main()
{
    printf("_GLOBAL_OFFSET_TABLE = %p\n", &_GLOBAL_OFFSET_TABLE_);
    return 0;
}

為了獲得_GLOBAL_OFFSET_TABLE_一致地址,匹配nm的結果,您需要使用-fPIE編譯代碼以執行代碼生成,就像鏈接到與位置無關的可執行文件一樣。 (否則你會得到一個像0x2ed6這樣的小整數和-fno-pie -no-pie )。 大多數現代 Linux 發行版的 GCC 默認值是-fPIE -pie ,這將使 nm 地址只是相對於圖像庫的偏移量,並且運行時地址是 ASLRed。 (這通常有利於安全,但您可能不想要它。)

$: gcc -fPIE -no-pie test.c -o test

它給:

$ ./test
_GLOBAL_OFFSET_TABLE = 0x6006d0

然而, nm想法不同:

$ nm test | fgrep GLOBAL
0000000000600868 d _GLOBAL_OFFSET_TABLE_

或者 GCC 太老以至於根本不知道 PIE,更不用說將-fPIE -pie作為默認值, -fpic可以工作。

如果使用匯編語言,則無需get_pc_thunk即可獲取_GLOBAL_OFFSET_TABLE_地址。
這是棘手的方式。 :)


這是示例代碼:

$ cat test.s

.global main
main:
 lea HEREIS, %eax   # Now %eax holds address of _GLOBAL_OFFSET_TABLE_      

.section .got
HEREIS:

$ gcc -o test test.s

這是可用的,因為.got部分與<.got.plt>相鄰
因此符號HEREIS_GLOBAL_OFFSET_TABLE_位於相同的地址。


附注。 您可以檢查它是否適用於 objdump。

Disassembly of section .got:

080495e8 <HEREIS-0x4>:
 80495e8:   00 00                   add    %al,(%eax)
    ...

Disassembly of section .got.plt:

080495ec <_GLOBAL_OFFSET_TABLE_>:
 80495ec:   00 95 04 08 00 00       add    %dl,0x804(%ebp)
 80495f2:   00 00                   add    %al,(%eax)
 80495f4:   00 00                   add    %al,(%eax)

暫無
暫無

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

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