簡體   English   中英

在ELF文件中查找全局偏移表

[英]Locating the Global Offset Table in an ELF file

如何在我正在解析的ELF文件中找到.got部分的偏移量?

我不想按名稱搜索該部分,因為我不想依賴它。 當我用其他東西更改部分名稱時,二進制文件仍然有效。

簡答:在一般情況下,你不能。

鏈接視圖中的GOT

該過程的鏈接視圖由節頭表給出。 GOT可以通過以下方式找到:

$ readelf -S $elf
[...]
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [29] .got              PROGBITS         00000000003a2d80  001a2d80
       0000000000000278  0000000000000008  WA       0     0     8
  [30] .got.plt          PROGBITS         00000000003a3000  001a3000
       0000000000000078  0000000000000008  WA       0     0     8

您只能識別GOT,因為部分名稱(可能真的是任何東西)。 GOT條目使用SHT_PROGBITS(與ELF文件的許多其他位一樣),因此您無法使用節類型來識別它們。

此外,部分頭表在運行時不需要,並且不需要存在於ELF文件中。

執行視圖

我們可以使用執行視圖嗎?

執行視圖由程序頭表給出。 但是,在程序頭表中,沒有(非PLT)GOT的真實概念。 運行時不關心GOT條目的位置。 他們也可以分散在數據段*的任何地方。 重要的是,(運行時)重定位表中存在正確的重定位。

使用動態部分

需要告知動態鏈接器PLT GOT條目( .got.plt )在哪里。 這由動態部分的DT_PLTGOT條目給出。 但是,它只給出了GOT PLT表開頭的(運行時,虛擬內存)位置:你沒有它的大小。

使用重定位表

您可能會嘗試檢查重定位表:

  • 您應該能夠通過查看PLT重定位來推斷PLT GOT的大小;

  • 您可以通過查看非PLT重定位來推斷非PLT GOT的位置和大小。

如果我正在查看libc的非PLT重定位表(在x86_64上),我會得到一堆R_X86_64_GLOB_DAT條目:

$ readelf -r $elf
[...]
0000003a2da0  052c00000006 R_X86_64_GLOB_DAT 00000000003a4708 stderr + 0
0000003a2da8  061400000006 R_X86_64_GLOB_DAT 00000000003a85d0 error_one_per_line + 0
0000003a2db0  06eb00000006 R_X86_64_GLOB_DAT 00000000003a57d0 __malloc_initialize_ho + 0
0000003a2db8  07f300000006 R_X86_64_GLOB_DAT 00000000003a4720 __morecore + 0
0000003a2dc8  02a400000006 R_X86_64_GLOB_DAT 00000000003a8998 __key_encryptsession_p + 0
0000003a2dd0  061000000006 R_X86_64_GLOB_DAT 00000000003a3ec8 __progname_full + 0
0000003a2dd8  049c00000006 R_X86_64_GLOB_DAT 00000000003a4010 __ctype32_tolower + 0
0000003a2de0  011900000006 R_X86_64_GLOB_DAT 00000000003a5fb8 _environ + 0
0000003a2de8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 _rtld_global + 0
0000003a2df0  011000000006 R_X86_64_GLOB_DAT 00000000003a3ec0 __progname + 0
0000003a2df8  04ff00000006 R_X86_64_GLOB_DAT 00000000003a32c4 argp_err_exit_status + 0
0000003a2e08  04ce00000006 R_X86_64_GLOB_DAT 00000000003a8538 mallwatch + 0
0000003a2e10  00bc00000006 R_X86_64_GLOB_DAT 00000000003a87d8 __rcmd_errstr + 0
0000003a2e18  056400000006 R_X86_64_GLOB_DAT 00000000003a48e0 __vdso_clock_gettime + 0
[...]

我們幾乎找到了非PLT GOT的地址:

$ readelf -S $elf
[...]
  [29] .got              PROGBITS         00000000003a2d80  001a2d80
       0000000000000278  0000000000000008  WA       0     0     8

有4個缺少GOT條目(我不知道為什么......)。

注意

(*):這意味着甚至可能沒有任何(非PLT)GOT。

暫無
暫無

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

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