簡體   English   中英

在 C 程序中,函數框架的返回地址是否指向 .text 部分?

[英]In a C program, does return address of a function frame point to the .text section?

我正在嘗試做一個小的 ctf,並且我正在嘗試溢出返回地址以注入 shellcode。 我希望返回地址非常低,因為它應該指向指令(因此我假設 .text 段)。

使用格式字符串漏洞我探索了內存並發現了 1f7ffd 范圍內的一些值。 我認為它可能是返回地址,據我所知,它之前的地址應該是從前一個函數幀存儲的 ebp 的值。 因此,我用 ebp + 一些偏移量覆蓋了返回地址。 然而,似乎覆蓋存儲的 ebp 會導致程序立即崩潰,而覆蓋返回地址似乎只會在 1 次循環迭代后使代碼崩潰。

這讓我懷疑這是否是我要壓倒一切的正確事情。 所以我想我應該問一下:

  • 返回地址確實應該屬於 .text
  • 堆棧地址、bss 地址和文本地址的大致范圍是多少? (我認為堆棧大約是 7fffffff,bss 大約是 55555555,一切都比文本低得多。(假設系統是一些 Linux 風格和 32 位)

返回地址確實應該屬於 .text

並非總是如此,但很可能是的。 通常,程序的所有可執行代碼都駐留在可執行文件的.text部分中。 正如Peter Cordes在下面的評論中指出的那樣,在某些情況下,程序的.text部分中定義的函數不會在.text中返回。 例如,如果該函數被用作某個庫函數(例如qsort )的回調,或者它是一個信號處理程序、一個atexit()處理程序等。然而,這些在普通 C 中很少發生。

為什么要猜呢? 您可以在調試器(例如 GDB)下檢查程序並親自查看:

$ gdb ./program

(gdb) b some_function
(gdb) run

Beakpoint 1, 0xAAABBB in some_function from ./program
(gdb) backtrace
#0  0xAAABBB in some_function from ./program
#1  0xCCCDDD in some_other_function from ./program  <== here's the return address
...

(gdb) info inferior
  Num  Description       Executable
* 1    process 11107     ./program

(gdb) !cat /proc/11107/maps
555555554000-555555558000 r--p 00000000 103:05 1443328 ./program
555555558000-55555556b000 r-xp 00004000 103:05 1443328 ./program <=== .text
55555556b000-555555574000 r--p 00017000 103:05 1443328 ./program
555555575000-555555576000 r--p 00020000 103:05 1443328 ./program
555555576000-555555577000 rw-p 00021000 103:05 1443328 ./program
...

堆棧地址、bss 地址和文本地址的大致范圍是多少?

如果不檢查程序並且不確切知道您正在運行程序的系統及其配置,這是不可能回答的。 如果我們談論的是在 Linux 上運行的 ELF,我將在這里假設它是最常見的情況,那么您可以嘗試像這樣弄清楚它:

  1. 了解您正在使用的 ELF 是共享對象 ( ET_DYN ) 還是簡單的可執行文件 ( ET_EXEC )。 這可以使用readelf -h program來完成,它將顯示如下內容:

     Type: DYN (Shared object file)
  2. 如果你正在處理一個共享對象( DYN ),那么你不運行它就無法知道它的基本虛擬地址,因為這將由內核決定。 內核將在加載時計算一個適當的地址,如果ASLR為 ON(默認情況下應該是),則可能是隨機的。

    對於 Linux x86 32 位,ELF 在虛擬內存中的大致位置(以及它的.text部分)應該在0x56555000左右,而不考慮 ASLR。 另請參閱我關於“為什么 Linux 偏愛 0x7f 映射?”的另一個答案。 ,它解釋了 x86-64 背后的邏輯(同樣也適用於 x86 32 位)。

    正如您可能猜到的那樣,ASLR 使事情變得更加復雜,因為您需要找到一種方法來計算運行時所需的確切地址。 在您的場景中,最簡單的方法可能是使用您的格式字符串漏洞泄漏一些已經在堆棧上的返回地址,然后做一些簡單的數學運算(減法/加法)來找出您想要返回的地址。

  3. 相反,如果您正在處理一個可執行文件 ( EXEC ),那么即使在運行程序之前,基本虛擬地址也將是固定的並且是已知的。 readelf -WS program的輸出將告訴您.text部分的地址,如果符號可用, readelf -Ws program還將告訴您程序中定義的任何函數的虛擬地址。

暫無
暫無

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

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