gdb/pwndbg的使用

gdb/pwndbg的使用

Scroll Down

gdb/pwndbg的使用

工欲善其事必先利其器,今天整理下gdb插件pwndbg的基础用法,方便查阅。

gdb

0x01 安装

$ git clone https://github.com/pwndbg/pwndbg
$ cd pwndbg
$ ./setup.sh

0x02 启动

  • gdb+文件名或者gdb打开之后file 文件名.(只讨论命令行模式,不开启酷炫的GUI模式了)
$ gdb hello
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
******
Your encoding (ANSI_X3.4-1968) is different than UTF-8. pwndbg might not work properly.
You might try launching gdb with:
    LC_ALL=en_US.UTF-8 PYTHONIOENCODING=UTF-8 gdb
Make sure that en_US.UTF-8 is activated in /etc/locale.gen and you called locale-gen
******
pwndbg: loaded 172 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from hello...done.
pwndbg>

0x03 断点

  • 使用break或者b命令来下断点,值可以是函数名,行号或者源文件加序号
break main		//main函数下断点
break 5			//在当前文件第五行下断点
break hello.c	//在hello.c的第五行下断点
  • info breakpoints命令可以打印出当前的断点信息,或者简写为i b
pwndbg> b main
Breakpoint 1 at 0x40052a: file 1.c, line 5.
pwndbg> i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040052a in main at 1.c:5
  • delete breakpoints删除所有断点.clear+位置值删除特定断点
pwndbg> b 3
Breakpoint 5 at 0x40052a: file 1.c, line 3.
pwndbg> b 4
Note: breakpoint 5 also set at pc 0x40052a.
Breakpoint 6 at 0x40052a: file 1.c, line 4.
pwndbg> b 5
Note: breakpoints 5 and 6 also set at pc 0x40052a.
Breakpoint 7 at 0x40052a: file 1.c, line 5.
pwndbg> i b
Num     Type           Disp Enb Address            What
5       breakpoint     keep y   0x000000000040052a in main at 1.c:3
6       breakpoint     keep y   0x000000000040052a in main at 1.c:4
7       breakpoint     keep y   0x000000000040052a in main at 1.c:5
pwndbg> clear 1.c:3
Deleted breakpoint 5
pwndbg> i b
Num     Type           Disp Enb Address            What
6       breakpoint     keep y   0x000000000040052a in main at 1.c:4
7       breakpoint     keep y   0x000000000040052a in main at 1.c:5
pwndbg> delete breakpoints
pwndbg> i b
No breakpoints or watchpoints.
  • enable或disable+断点编号来启用或禁用断点
pwndbg> i b
Num     Type           Disp Enb Address            What
8       breakpoint     keep y   0x000000000040052a in main at 1.c:5
pwndbg> disable 8
pwndbg> i b
Num     Type           Disp Enb Address            What
8       breakpoint     keep n   0x000000000040052a in main at 1.c:5

0x04 步进

  • next/n执行下一条命令,遇到函数不进入.step/s同,遇到函数进入

  • continue/c断续执行到断点

  • 只敲一下回车键将重复最后输入的命令

0x05 检查变量

  • print/p显示某个值.display/disp会在每一步都显示那个值,pwndbg显示的内容实在是太多了,不推荐用这个
pwndbg> print $rax
$1 = 13
pwndbg>
  • printf类似于c语言的printf函数,可以格式化输出内容
pwndbg> printf "%d\n",$rax
4195622
pwndbg> printf "%08x\n",$rax
00400526

0x06 输出格式

  • 一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。
x  按十六进制格式显示变量。
d  按十进制格式显示变量。
u  按十六进制格式显示无符号整型。
o  按八进制格式显示变量。
t  按二进制格式显示变量。
a  按十六进制格式显示变量。
c  按字符格式显示变量。
f  按浮点数格式显示变量。
(gdb) p i
$21 = 101   
(gdb) p/a i
$22 = 0x65
(gdb) p/c i
$23 = 101 'e'
(gdb) p/f i
$24 = 1.41531145e-43
(gdb) p/x i
$25 = 0x65
(gdb) p/t i
$26 = 1100101

0x07 查看内存

  • 使用examine/x来查看内存地址中的值
x/<n/f/u> <addr>
n、f、u是可选的参数。
n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i。
u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。
<addr>表示一个内存地址。

n/f/u三个参数可以一起使用。例如:

命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十进制显示。

pwndbg

0x01 上下文

  • 每次GDB停止时,打印当前执行上下文的有用摘要,显示所有的寄存器,栈,反汇编等,如果想显示源码需要在编译的时候加上-g选项.所有内存地址都按其所代表的内存类型进行颜色编码.
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────
 RAX  0xd
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3780 (_IO_stdfile_1_lock) ◂— 0x0
 RDI  0x1
 RSI  0x602010 ◂— 'hello world!\n'
 R8   0x602000 ◂— 0x0
 R9   0xd
 R10  0x7ffff7dd1b78 (main_arena+88) —▸ 0x602410 ◂— 0x0
 R11  0x246
 R12  0x400430 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe750 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe670 —▸ 0x400550 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffe660 —▸ 0x7fffffffe750 ◂— 0x1
 RIP  0x40053f (main+25) ◂— mov    eax, 0
──────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────
   0x40052e       <main+8>                   mov    dword ptr [rbp - 4], 1
   0x400535       <main+15>                  mov    edi, 0x4005d4
   0x40053a       <main+20>                  call   puts@plt <0x400400>

 ► 0x40053f       <main+25>                  mov    eax, 0
   0x400544       <main+30>                  leave
   0x400545       <main+31>                  ret
    ↓
   0x7ffff7a2d830 <__libc_start_main+240>    mov    edi, eax
   0x7ffff7a2d832 <__libc_start_main+242>    call   exit <0x7ffff7a47030>

   0x7ffff7a2d837 <__libc_start_main+247>    xor    edx, edx
   0x7ffff7a2d839 <__libc_start_main+249>    jmp    __libc_start_main+57 <0x7ffff7a2d779>

   0x7ffff7a2d83e <__libc_start_main+254>    mov    rax, qword ptr [rip + 0x3a8ecb] <0x7ffff7dd6710>
──────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────
In file: /1.c
   3 int main()
   4 {
   5    int a = 1;
   6    printf("hello world!\n");
   7
 ► 8   return 0;
   9 }
──────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe660 —▸ 0x7fffffffe750 ◂— 0x1
01:0008│      0x7fffffffe668 ◂— 0x100000000
02:0010│ rbp  0x7fffffffe670 —▸ 0x400550 (__libc_csu_init) ◂— push   r15
03:0018│      0x7fffffffe678 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
04:0020│      0x7fffffffe680 ◂— 0x0
05:0028│      0x7fffffffe688 —▸ 0x7fffffffe758 —▸ 0x7fffffffe956 ◂— 0x48006f6c6c65682f /* '/hello' */
06:0030│      0x7fffffffe690 ◂— 0x100000000
07:0038│      0x7fffffffe698 —▸ 0x400526 (main) ◂— push   rbp
────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────
 ► f 0           40053f main+25
   f 1     7ffff7a2d830 __libc_start_main+240

0x02 堆检查

  • arena
  • mp
  • bins
  • fastbins
  • unsortedin
  • smallbins
  • largebins
  • heap
  • malloc_chunk a
  • top_chunk

0x03 流程状态检查

  • 使用proinfo命令检查当前进程状态
pwndbg> procinfo
exe        '/hello'
pid        172
tid        172
ppid       169
uid        [0, 0, 0, 0]
gid        [0, 0, 0, 0]
groups     []
fd[0]      /dev/pts/0
fd[1]      /dev/pts/0
fd[2]      /dev/pts/0

0x04 搜索

  • 使用search查找字节,字符串或者是各种整数值和指针
pwndbg> search -s hello
hello           0x4005d4 push   0x6f6c6c65 /* 'hello world!' */
hello           0x6005d4 'hello world!'
warning: Unable to access 16000 bytes of target memory at 0x7ffff7bd4d04, halting search.
[stack]         0x7fffffffe958 0x4f48006f6c6c6568 /* 'hello' */
[stack]         0x7fffffffeff2 0x6f6c6c6568 /* 'hello' */

更多