麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

gdb使用

2019-11-17 05:15:49
字體:
來源:轉載
供稿:網友

  1.簡介
GNU 的調試器稱為 gdb,該程序是一個交互式工具,工作在字符模式。在 X Window 系統中,有一個 gdb 的前端圖形工具,稱為 xxgdb。gdb 是功能強大的調試程序,可完成如下的調試任務:

* 設置斷點;
* 監視程序變量的值;
* 程序的單步執行;
* 修改變量的值。
在可以使用 gdb 調試程序之前,必須使用 -g 選項編譯源文件。可在 makefile 中如下定義CFLAGS 變量:

CFLAGS = -g
運行 gdb 調試程序時通常使用如下的命令:

gdb PRogname

在 gdb 提示符處鍵入help,將列出命令的分類,主要的分類有:

* aliases:命令別名
* breakpoints:斷點定義;
* data:數據查看;
* files:指定并查看文件;
* internals:維護命令;
* running:程序執行;
* stack:調用棧查看;
* statu:狀態查看;
* tracepoints:跟蹤程序執行。

鍵入 help 后跟命令的分類名,可獲得該類命令的具體清單。

2.gdb 的常用命令
表 1-4 常用的 gdb 命令
命令 解釋
break NUM 在指定的行上設置斷點。
BT 顯示所有的調用棧幀。該命令可用來顯示函數的調用順序。
clear 刪除設置在特定源文件、特定行上的斷點。其用法為:clear FILENAME:NUM。
continue 繼續執行正在調試的程序。該命令用在程序由于處理信號或斷點而
導致停止運行時。
display EXPR 每次程序停止后顯示表達式的值。表達式由程序定義的變量組成。
file FILE 裝載指定的可執行文件進行調試。
help NAME 顯示指定命令的幫助信息。
info break 顯示當前斷點清單,包括到達斷點處的次數等。
info files 顯示被調試文件的具體信息。
info func 顯示所有的函數名稱。
info local 顯示當函數中的局部變量信息。
info prog 顯示被調試程序的執行狀態。
info var 顯示所有的全局和靜態變量名稱。
kill 終止正被調試的程序。
list 顯示源代碼段。
make 在不退出 gdb 的情況下運行 make 工具。
next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。
print EXPR 顯示表達式 EXPR 的值。

3.gdb 使用范例

-----------------
清單 一個有錯誤的 C 源程序 bugging.c
-----------------
#include <stdio.h>
#include <stdlib.h>

static char buff [256];
static char* string;
int main ()
{

printf ("Please input a string: ");
gets (string);

printf ("
Your string is: %s
", string);
}
-----------------

上面這個程序非常簡單,其目的是接受用戶的輸入,然后將用戶的輸入打印出來。該程序使用了一個未經過初始化的字符串地址 string,因此,編譯并運行之后,將出現 Segment Fault 錯誤:

$ gcc -o test -g test.c
$ ./test
Please input a string: asfd
Segmentation fault (core dumped)

為了查找該程序中出現的問題,我們利用 gdb,并按如下的步驟進行:

1.運行 gdb bugging 命令,裝入 bugging 可執行文件;
2.執行裝入的 bugging 命令;
3.使用 where 命令查看程序出錯的地方;
4.利用 list 命令查看調用 gets 函數四周的代碼;
5.唯一能夠導致 gets 函數出錯的因素就是變量 string。用 print 命令查看 string 的值;
6.在 gdb 中,我們可以直接修改變量的值,只要將 string 取一個合法的指針值就可以了,為
此,我們在第 11 行處設置斷點;
7.程序重新運行到第 11 行處停止,這時,我們可以用 set variable 命令修改 string 的取值;
8.然后繼續運行,將看到正確的程序運行結果。



[目錄]

--------------------------------------------------------------------------------


gcc常用選項對代碼的影響

by alert7

2001-12-21
測試環境 redhat 6.2
★ 前言
本文討論gcc的一些常用編譯選項對代碼的影響。當然代碼變了,它的內存布局也就會變了,隨之exploit也就要做相應的變動。
gcc的編譯選項實在太多,本文檢了幾個最常用的選項。

★ 演示程序
[alert7@redhat62 alert7]$ cat > test.c
#include
void hi(void)
{
printf("hi");
}
int main(int argc, char *argv[])
{
hi();
return 0;
}



[目錄]

--------------------------------------------------------------------------------


一般情況

★ 一般情況
[alert7@redhat62 alert7]$ gcc -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11773 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483e4 : push %ebp
0x80483e5 : mov %esp,%ebp
0x80483e7 : call 0x80483d0
0x80483ec : xor %eax,%eax
0x80483ee : jmp 0x80483f0
0x80483f0 : leave
0x80483f1 : ret
....
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483d0 : push %ebp
0x80483d1 : mov %esp,%ebp
0x80483d3 : push $0x8048450
0x80483d8 : call 0x8048308
0x80483dd : add $0x4,%esp
0x80483e0 : leave
0x80483e1 : ret
0x80483e2 : mov %esi,%esi
End of assembler dump.
來看看部分的內存映象
(內存高址)
+--------+
bffffbc4 argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
00000001 argc的值
0xbffffb80 +--------+
400309cbmain的返回地址
0xbffffb7c +--------+ <-- 調用main函數前的esp
bffffb98 調用main函數前的ebp
0xbffffb78 +--------+ <-- main函數的ebp
080483ec hi()的返回地址
0xbffffb74 +--------+
bffffb78 調用hi()前的esp
0xbffffb70 +--------+
08048450 "hi"的地址
0xbffffb6c +--------+
......
(內存低址)
leave 指令所做的操作相當于MOV ESP,EBP 然后 POP EBP
ret 指令所做的操作相當于POP Eip


[目錄]

--------------------------------------------------------------------------------


-O 編譯選項

★ -O 編譯選項
With `-O', the compiler tries to redUCe code size and execution time.
When you specify `-O', the two options `-fthread-jumps' and
`-fdefer-pop' are turned on
優化,減少代碼大小和執行的時間
[alert7@redhat62 alert7]$ gcc -O -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11757 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483d8 : push %ebp
0x80483d9 : mov %esp,%ebp
0x80483db : call 0x80483c8
0x80483e0 : xor %eax,%eax
0x80483e2 : leave
0x80483e3 : ret
0x80483e4 : nop
...
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:

0x80483c8 : push %ebp
0x80483c9 : mov %esp,%ebp
0x80483cb : push $0x8048440
0x80483d0 : call 0x8048308
0x80483d5 : leave
0x80483d6 : ret
0x80483d7 : nop
End of assembler dump.
在main()中,把一條jmp指令優化掉了,很顯然,這條指令是可以不需要的。
在hi()中,把add $0x4,%esp優化掉了,這會不會使stack不平衡呢?

來看看部分的內存映象

(內存高址)
+--------+
bffffbc4 argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
00000001 argc的值
0xbffffb80 +--------+
400309cbmain的返回地址
0xbffffb7c +--------+ <-- 調用main函數前的esp
bffffb98 調用main函數前的ebp
0xbffffb78 +--------+ <-- main函數的ebp
080483e0 hi()的返回地址
0xbffffb74 +--------+
bffffb78 調用hi()前的esp
0xbffffb70 +--------+
08048440 "hi"的地址
0xbffffb6c +--------+
......
(內存低址)
leave指令所做的操作相當于把MOV ESP,EBP 然后 POP EBP??吹絣eave指令操作了沒有,先把ebp-->esp,再pop ebp,這樣即使在過程內堆棧的esp,ebp是不平衡的,但只要返回時候碰到leave指令就會平衡了,所以把add $0x4,%esp優化掉也是沒有問題的。





[目錄]

--------------------------------------------------------------------------------


-O2 編譯選項

★ -O2 編譯選項
-O2
Optimize even more. Nearly all supported optimizations that do
not involve a space-speed tradeoff are performed. Loop unrolling
and function inlining are not done, for example. As compared to -O,
this option increases both compilation time and the performance of
the generated code.
[alert7@redhat62 alert7]$ gcc -O2 -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11757 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483d8 : push %ebp
0x80483d9 : mov %esp,%ebp
0x80483db : call 0x80483c8
0x80483e0 : xor %eax,%eax
0x80483e2 : leave
0x80483e3 : ret
...
0x80483ef : nop
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483c8 : push %ebp
0x80483c9 : mov %esp,%ebp
0x80483cb : push $0x8048440
0x80483d0 : call 0x8048308
0x80483d5 : leave
0x80483d6 : ret
0x80483d7 : nop
End of assembler dump.
由于程序比較簡單,再優化也沒有好優化的了,所以跟-O出來的一樣。



[目錄]

--------------------------------------------------------------------------------


-fomit-frame-pointer 編譯選項

★ -fomit-frame-pointer 編譯選項
-fomit-frame-pointer
Don't keep the frame pointer in a register for functions
that don't need one. This avoids the instructions to save,
set up and restore frame pointers; it also makes an extra
register available in many functions. It also makes
debugging impossible on most machines.
忽略幀指針。這樣在程序就不需要保存,安裝,和恢復ebp了。這樣ebp也就是一個free的register了,在函數中就可以隨便使用了。


[alert7@redhat62 alert7]$ gcc -fomit-frame-pointer -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11773 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483e0 : call 0x80483d0
0x80483e5 : xor %eax,%eax
0x80483e7 : jmp 0x80483f0
0x80483e9 : lea 0x0(%esi,1),%esi
0x80483f0 : ret
....
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483d0 : push $0x8048450
0x80483d5 : call 0x8048308
0x80483da : add $0x4,%esp
0x80483dd : ret
0x80483de : mov %esi,%esi
End of assembler dump.
在main()和hi()中都去掉了以下指令
push %ebp
mov %esp,%ebp//這兩條指令安裝
leave//這條指令恢復
來看看部分的內存映象
(內存高址)
+--------+
bffffbc4 argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
00000001 argc的值
0xbffffb80 +--------+
400309cbmain的返回地址
0xbffffb7c +--------+
080483e5 hi()的返回地址
0xbffffb78 +--------+
08048450 "hi"字符串的地址
0xbffffb74 +--------+
......
(內存低址)
沒有保存上層執行環境的ebp.



[目錄]

--------------------------------------------------------------------------------


-fomit-frame-pointer && -O2

★ -fomit-frame-pointer && -O2
-fomit-frame-pointer編譯選項去掉了
push %ebp
mov %esp,%ebp//這兩條指令安裝
leave//這條指令恢復
-O2編譯選項去掉了
add $0x4,%esp
兩個加起來會不會這四條指令一起去掉,從而使stack不平衡呢?
[alert7@redhat62 alert7]$ gcc -fomit-frame-pointer -O2 -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11741 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483d8 : call 0x80483c8
0x80483dd : xor %eax,%eax
0x80483df : ret
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483c8 : push $0x8048430
0x80483cd : call 0x8048308
0x80483d2 : add $0x4,%esp
0x80483d5 : ret
0x80483d6 : mov %esi,%esi
End of assembler dump.
來看看部分的內存映象
(內存高址)
+--------+
bffffbc4 argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
00000001 argc的值
0xbffffb80 +--------+
400309cbmain的返回地址
0xbffffb7c +--------+
080483dd hi()的返回地址
0xbffffb78 +--------+
08048430 "hi"字符串的地址
0xbffffb74 +--------+
......
(內存低址)
此時就沒有把add $0x4,%esp優化掉,假如優化掉的話,整個stack就
會變的不平衡,從而會導致程序出錯。


[目錄]

--------------------------------------------------------------------------------


-fPIC 編譯選項

★ -fPIC 編譯選項
-fPIC If supported for the target machine, emit position-independent
code, suitable for dynamic linking,even if branches need large

displacements.
產生位置無關代碼(PIC),一般創建共享庫時用到。
在x86上,PIC的代碼的符號引用都是通過ebx進行操作的。

[alert7@redhat62 alert7]$ gcc -fPIC -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11805 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483f8 : push %ebp
0x80483f9 : mov %esp,%ebp
0x80483fb : push %ebx
0x80483fc : call 0x8048401
0x8048401 : pop %ebx//取得該指令的地址
0x8048402 : add $0x1093,%ebx//此時ebx里面存放著是GOT表的地址
0x8048408 : call 0x80483d0
0x804840d : xor %eax,%eax
0x804840f : jmp 0x8048411
0x8048411 : mov 0xfffffffc(%ebp),%ebx
0x8048414 : leave
0x8048415 : ret
...
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483d0 : push %ebp
0x80483d1 : mov %esp,%ebp
0x80483d3 : push %ebx
0x80483d4 : call 0x80483d9
0x80483d9 : pop %ebx
0x80483da : add $0x10bb,%ebx
0x80483e0 : lea 0xffffefdc(%ebx),%edx
0x80483e6 : mov %edx,%eax
0x80483e8 : push %eax
0x80483e9 : call 0x8048308
0x80483ee : add $0x4,%esp
0x80483f1 : mov 0xfffffffc(%ebp),%ebx
0x80483f4 : leave
0x80483f5 : ret
0x80483f6 : mov %esi,%esi
End of assembler dump.
來看看部分的內存映象

(內存高址)
+--------+
bffffbc4 argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
00000001 argc的值
0xbffffb80 +--------+
400309cbmain的返回地址
0xbffffb7c +--------+ <-- 調用main函數前的esp
bffffb98 調用main函數前的ebp
0xbffffb78 +--------+ <-- main函數的ebp
401081ec 保存的ebx
0xbffffb74 +--------+
0804840d (存放過call 0x8048401的下一條指令地址)
0xbffffb70 +--------+
bffffb78 調用hi()前的esp
0xbffffb6c +--------+
08049494 GOT表地址
0xbffffb68 +--------+
08048470(存放過call 0x80483d9的下一條指令地址)
0xbffffb64 +--------+
......
(內存低址)



[目錄]

--------------------------------------------------------------------------------


-static 編譯選項

★ -static 編譯選項
-static
On systems that support dynamic linking, this prevents
linking with the shared libraries. On other systems,
this option has no effect.
把一些函數都靜態的編譯到程序中,而無需動態鏈接了。
[alert7@redhat62 alert7]$ gcc -o test -static test.c
[alert7@redhat62 alert7]$ wc -c test
962808 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80481b4 : push %ebp
0x80481b5 : mov %esp,%ebp
0x80481b7 : call 0x80481a0
0x80481bc : xor %eax,%eax
0x80481be : jmp 0x80481c0
0x80481c0 : leave
0x80481c1 : ret
...
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:

0x80481a0 : push %ebp
0x80481a1 : mov %esp,%ebp
0x80481a3 : push $0x8071528
0x80481a8 : call 0x804865c
0x80481ad : add $0x4,%esp
0x80481b0 : leave
0x80481b1 : ret
0x80481b2 : mov %esi,%esi
End of assembler dump.
[alert7@redhat62 alert7]$ ldd test
not a dynamic executable
-static出來的代碼已經沒有PLT了,GOT雖然有,已經全部為0了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 日日狠狠久久 | 全黄性性激高免费视频 | 香蕉久久久久 | 国产精品影视 | 蜜桃欧美性大片免费视频 | 国产亚洲精品综合一区91555 | 毛片免费观看视频 | 成人羞羞国产免费游戏 | 水多视频在线观看 | 涩涩99 | 性欧美大战久久久久久久免费观看 | 涩涩屋av | 9999久久久久久 | 成人羞羞国产免费游戏 | 海外中文字幕在线观看 | 欧美人xx | 亚洲午夜免费 | 国产亚洲美女精品久久久2020 | www.91操| 久久在现视频 | 欧美a∨一区二区三区久久黄 | 久久久久久久黄色片 | 久草在线资源福利站 | 国产一区二区三区视频免费 | 黄色特级毛片 | 欧美日韩电影 | 五月天影院,久久综合, | 欧美性激情视频 | 黄色av片在线观看 | 视频一区二区三区免费观看 | 午夜男人在线观看 | 精品国产乱码一区二区 | 96视频在线免费观看 | 国产三级在线视频观看 | 美国黄色小视频 | 最新欧美精品一区二区三区 | 日日草日日干 | 欧美激情综合网 | 精品国产一区二区三区天美传媒 | 久久精品欧美一区 | 毛片毛片免费看 |