簡體   English   中英

試圖從“剝削藝術”中理解char_array2.c的例子

[英]Trying to understand example char_array2.c from “the art of exploitation”

好的,所以我真的想了解這個“剝削藝術”第二版的例子。 我試圖通過密切關注本書中GDB的輸出來確切了解該示例的內容。 我最大的問題是最后一部分,我把整個事情都包括在內,這樣每個人都可以看到發生了什么。 當然,我只有非常(非常)基本的匯編代碼知識。 我確實理解基本的C.在最后一部分中,作者說第二次運行程序與strcpy()指向的地址中的最后一次運行存在細微的差別,我只是看不到它。

該計划很簡單

#include<stdio.h>
#include<string.h>

int main() {

  char str_a[20];
  strcpy(str_a, "Hello, world!\n");
  printf(str_a);
  }

在我使用必要的選項編譯它以便能夠調試它之后,我將它加載到GDB上並包含以下內容:

(gdb) break 6
Breakpoint 1 at 0x80483c4: file char_array2.c, line 6.
(gdb) break strcpy

Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (strcpy) pending.
(gdb) break 8
Breakpoint 3 at 0x80483d7: file char_array2.c, line 8.
(gdb)

我對此沒有任何問題,我的理解是調試器只能使用用戶定義的函數來執行此類操作。 我也知道如何使用gcc選項來解決這個問題。 我也知道,當程序運行時,strcpy斷點得到解決。 讓我繼續

(gdb) run
Starting program: /home/reader/booksrc/char_array2
Breakpoint 4 at 0xb7f076f4
Pending breakpoint "strcpy" resolved

Breakpoint 1, main() at char_array2.c:7
7   strcpy(str_a, "Hello, world!\n");
(gdb) i r eip
eip 0x80483c4   0x80483c4 <main+16>
(gdb) x/5i $eip
0x80483c4   <main+16>:  mov    DWORD PTR [esp+4],0x80484c4
0x80483cc   <main+24>:  lea    eax,[ebp-40]
0x80483cf   <main+27>:  mov    DWORD PTR [esp],eax
0x80483d2   <main+30>:  call   0x80482c4 <strcpy@plt>
0x80483d7   <main+35>:  lea    eax,[ebp-40]
(gdb) continue
Continuing.


Breakpoint 4, 0xb7f076f4 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) i r eip
eip    0xb7f076f4    0xb7f076f4 <strcpy+4>
(gdb) x/5i $eip
0xb7f076f4 <strcpy+4>:  mov   esi,DWORD PTR [ebp+8]
0xb7f076f7 <strcpy+7>:  mov   eax,DWORD PTR [ebp+12]
0xb7f076fa <strcpy+10>: mov   ecx,esi
0xb7f076fc <strcpy+12>: sub   ecx,eax
0xb7f076fe <strcpy+14>: mov   edx,eax
(gdb) continue
Continuing.

Breakpoint 3, main () at char_array2.c:8
8
printf(str_a);
(gdb) i r eip
eip    0x80483d7    0x80483d7 <main+35>
(gdb) x/5i $eip
0x80483d7 <main+35>:   lea    eax,[ebp-40]
0x80483da <main+38>:   mov    DWORD PTR [esp],eax
0x80483dd <main+41>:   call   0x80482d4 <printf@plt>
0x80483e2 <main+46>:   leave
0x80483e3 <main+47>:   ret
(gdb)

這是程序的第二次運行,其中strcpy的地址與另一地址不同。

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/reader/booksrc/char_array2
Error in re-setting breakpoint 4:
Function "strcpy" not defined.

Breakpoint 1, main () at char_array2.c:7
7
strcpy(str_a, "Hello, world!\n");
(gdb) bt
#0 main () at char_array2.c:7
(gdb) cont
Continuing.

Breakpoint 4, 0xb7f076f4 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7f076f4 in strcpy () from /lib/tls/i686/cmov/libc.so.6
#1 0x080483d7 in main () at char_array2.c:7
(gdb) cont
Continuing.

Breakpoint 3, main () at char_array2.c:8
8
printf(str_a);
(gdb) bt
#0 main () at char_array2.c:8
(gdb)

區別在哪里? 我錯誤地認為0xb7f076f4是strcpy的地址嗎? 在第二次運行,如果我是正確的,一切都表明地址是0xb7f076f4。

還有,是什么? 我在本書前面的任何地方都找不到解釋。 如果有人能夠從上到下向我解釋這一點,我將非常感激,因為我不知道現實生活中的任何專家可以幫助我。 我發現解釋是模糊的,他解釋變量和循環,就像他向5歲時解釋它一樣,但留下了大部分匯編代碼讓我們自己弄明白,我在這方面並不是很成功。 任何幫助將不勝感激。

顯然gdb關閉了調試進程的ASLR ,使(會話到會話)調試更容易。

來自https://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html

set disable-randomization
set disable-randomization on
    This option (enabled by default in GDB) will turn off the native 
    randomization of the virtual address space of the started program. 
    This option is useful for multiple debugging sessions to make the 
    execution better reproducible and memory addresses reusable across
    debugging sessions.

gdb.gdbinit文件中設置set disable-randomization off並再次嘗試。 現在,每次運行二進制文件時,Libc都應該加載到不同的地址。

運行watch -n 1 cat /proc/self/maps也很高興看到二進制文件和庫如何映射到“隨機”地址。

正如@Voo在上面的評論中所說,這本書可能是指ASLR(地址空間布局隨機化),這是一個安全功能。 它改變了地址空間用於每次執行的方式,因此您不能總是在同一個地方查找內容。

如果你沒有在gdb中看到它意味着你關閉了ASLR。 全局或本地gdb 您可以使用cat /proc/sys/kernel/randomize_va_space檢查前者,后者使用show disable-randomization命令在gdb提示符下檢查。

暫無
暫無

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

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