Help us understand the problem. What is going on with this article?

gdb-peda超入門

More than 1 year has passed since last update.

まずはgdbを使えるようになろう

https://qiita.com/miyagaw61/private/4a4514e2de0b458c2589

環境

Ubuntu 16.04 LTS

gdb-pedaをいれてみよう

git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit

使ってみよう

gdb超入門の記事と同じバイナリを使用して練習してみます。

$ gdb test
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"...
Reading symbols from test...(no debugging symbols found)...done.
gdb-peda$

プロンプトが白文字の(gdb)から赤文字のgdb-peda$に変わりました。

関数の中を見るコマンドはgdbではdisassでしたが、gdb-pedaでは先頭にpを付けてpdisassというコマンドを使ってみましょう。

gdb-peda$ pdisass main
Dump of assembler code for function main:
   0x0000000000400596 <+0>:     push   rbp
   0x0000000000400597 <+1>:     mov    rbp,rsp
   0x000000000040059a <+4>:     sub    rsp,0x30
   0x000000000040059e <+8>:     mov    rax,QWORD PTR fs:0x28
   0x00000000004005a7 <+17>:    mov    QWORD PTR [rbp-0x8],rax
   0x00000000004005ab <+21>:    xor    eax,eax
   0x00000000004005ad <+23>:    mov    DWORD PTR [rbp-0x24],0xa
   0x00000000004005b4 <+30>:    movabs rax,0x67202c6f6c6c6548
   0x00000000004005be <+40>:    mov    QWORD PTR [rbp-0x20],rax
   0x00000000004005c2 <+44>:    mov    DWORD PTR [rbp-0x18],0x216264
   0x00000000004005c9 <+51>:    lea    rax,[rbp-0x20]
   0x00000000004005cd <+55>:    mov    rdi,rax
   0x00000000004005d0 <+58>:    call   0x400460 <puts@plt>
   0x00000000004005d5 <+63>:    mov    eax,0x0
   0x00000000004005da <+68>:    mov    rdx,QWORD PTR [rbp-0x8]
   0x00000000004005de <+72>:    xor    rdx,QWORD PTR fs:0x28
   0x00000000004005e7 <+81>:    je     0x4005ee <main+88>
   0x00000000004005e9 <+83>:    call   0x400470 <__stack_chk_fail@plt>
   0x00000000004005ee <+88>:    leave
   0x00000000004005ef <+89>:    ret
End of assembler dump.

色が付いてちょっと見やすくなっています。

startしてみます。

gdb-peda$ start
[----------------------------------registers-----------------------------------]
RAX: 0x400596 (<main>:  push   rbp)
RBX: 0x0
RCX: 0x0
RDX: 0x7fffffffe0b8 --> 0x7fffffffe38e ("XDG_SESSION_ID=9152")
RSI: 0x7fffffffe0a8 --> 0x7fffffffe375 ("/home/miyagaw61/tmp/test")
RDI: 0x1
RBP: 0x7fffffffdfc0 --> 0x4005f0 (<__libc_csu_init>:    push   r15)
RSP: 0x7fffffffdfc0 --> 0x4005f0 (<__libc_csu_init>:    push   r15)
RIP: 0x40059a (<main+4>:        sub    rsp,0x30)
R8 : 0x400660 (<__libc_csu_fini>:       repz ret)
R9 : 0x7ffff7de7ab0 (<_dl_fini>:        push   rbp)
R10: 0x846
R11: 0x7ffff7a2d740 (<__libc_start_main>:       push   r14)
R12: 0x4004a0 (<_start>:        xor    ebp,ebp)
R13: 0x7fffffffe0a0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x400591 <frame_dummy+33>:   jmp    0x400510 <register_tm_clones>
   0x400596 <main>:     push   rbp
   0x400597 <main+1>:   mov    rbp,rsp
=> 0x40059a <main+4>:   sub    rsp,0x30
   0x40059e <main+8>:   mov    rax,QWORD PTR fs:0x28
   0x4005a7 <main+17>:  mov    QWORD PTR [rbp-0x8],rax
   0x4005ab <main+21>:  xor    eax,eax
   0x4005ad <main+23>:  mov    DWORD PTR [rbp-0x24],0xa
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdfc0 --> 0x4005f0 (<__libc_csu_init>:   push   r15)
0008| 0x7fffffffdfc8 --> 0x7ffff7a2d830 (<__libc_start_main+240>:       mov    edi,eax)
0016| 0x7fffffffdfd0 --> 0x0
0024| 0x7fffffffdfd8 --> 0x7fffffffe0a8 --> 0x7fffffffe375 ("/home/miyagaw61/tmp/test")
0032| 0x7fffffffdfe0 --> 0x1f7ffcca0
0040| 0x7fffffffdfe8 --> 0x400596 (<main>:      push   rbp)
0048| 0x7fffffffdff0 --> 0x0
0056| 0x7fffffffdff8 --> 0x4902b0c0c9343526
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Temporary breakpoint 1, 0x000000000040059a in main ()

現在のレジスタやスタックの中身や前後の命令が常に表示され、とても見やすくなっていることがわかると思います。
nextiコマンドでいくつか命令を進んでみてください。省略記法であるniコマンドでもできます。
同じコマンドを連続で行う時は、エンターを押すだけで大丈夫です。

gdb-peda$ ni
gdb-peda$ エンター
gdb-peda$ エンター
gdb-peda$ エンター

puts関数まで進みます。gdb-pedaでは、nextcallコマンドで次のcall命令まで進むことができます。

gdb-peda$ nextcall
[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffdfa0 ("Hello, gdb!")
RBX: 0x0
RCX: 0x0
RDX: 0x7fffffffe0b8 --> 0x7fffffffe38e ("XDG_SESSION_ID=9152")
RSI: 0x7fffffffe0a8 --> 0x7fffffffe375 ("/home/miyagaw61/tmp/test")
RDI: 0x7fffffffdfa0 ("Hello, gdb!")
RBP: 0x7fffffffdfc0 --> 0x4005f0 (<__libc_csu_init>:    push   r15)
RSP: 0x7fffffffdf90 --> 0x0
RIP: 0x4005d0 (<main+58>:       call   0x400460 <puts@plt>)
R8 : 0x400660 (<__libc_csu_fini>:       repz ret)
R9 : 0x7ffff7de7ab0 (<_dl_fini>:        push   rbp)
R10: 0x846
R11: 0x7ffff7a2d740 (<__libc_start_main>:       push   r14)
R12: 0x4004a0 (<_start>:        xor    ebp,ebp)
R13: 0x7fffffffe0a0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4005c2 <main+44>:  mov    DWORD PTR [rbp-0x18],0x216264
   0x4005c9 <main+51>:  lea    rax,[rbp-0x20]
   0x4005cd <main+55>:  mov    rdi,rax
=> 0x4005d0 <main+58>:  call   0x400460 <puts@plt>
   0x4005d5 <main+63>:  mov    eax,0x0
   0x4005da <main+68>:  mov    rdx,QWORD PTR [rbp-0x8]
   0x4005de <main+72>:  xor    rdx,QWORD PTR fs:0x28
   0x4005e7 <main+81>:  je     0x4005ee <main+88>
Guessed arguments:
arg[0]: 0x7fffffffdfa0 ("Hello, gdb!")
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdf90 --> 0x0
0008| 0x7fffffffdf98 --> 0xa00000000 ('')
0016| 0x7fffffffdfa0 ("Hello, gdb!")
0024| 0x7fffffffdfa8 --> 0x216264 ('db!')
0032| 0x7fffffffdfb0 --> 0x7fffffffe0a0 --> 0x1
0040| 0x7fffffffdfb8 --> 0xd12909d07dfe9c00
0048| 0x7fffffffdfc0 --> 0x4005f0 (<__libc_csu_init>:   push   r15)
0056| 0x7fffffffdfc8 --> 0x7ffff7a2d830 (<__libc_start_main+240>:       mov    edi,eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

真ん中らへんで、

Guessed arguments:
arg[0]: 0x7fffffffdfa0 ("Hello, gdb!")

とputs関数に渡される引数を推測してくれています。

RBPレジスタに格納されているアドレスよりも8*4バイト上位のアドレスから5ワード分(x64環境では5*8バイト)のデータを表示してみましょう。

gdb-peda$ tel $rbp-8*4 5
0000| 0x7fffffffdfa0 ("Hello, gdb!")
0008| 0x7fffffffdfa8 --> 0x216264 ('db!')
0016| 0x7fffffffdfb0 --> 0x7fffffffe0a0 --> 0x1
0024| 0x7fffffffdfb8 --> 0xd12909d07dfe9c00
0032| 0x7fffffffdfc0 --> 0x4005f0 (<__libc_csu_init>:   push   r15)

gdb-pedaでは、telコマンドを使うことでこのように見やすくパースして表示することができます。

終了します。

gdb-peda$ q
$

その他よく使うコマンド一覧

・vmmap
・find
・set

などなど

おわり

gdb-pedaの基本は以上となります。
gdb-pedaは大変素晴らしいツールで、他にも数々のコマンドが存在します。
もっと深くgdb-pedaを知りたい方は、こちらのBlackHatの発表資料を読むと良いでしょう!
また、現在Exgdbという更に動的解析を効率化するための拡張プラグインを開発中です。使い方はリポジトリのREADME.mdを参照ください。

enjoy your gdb-peda life!

miyase256
SoftwareDvelopment, LinuxKernelReading, MalwareAnalysis, Exploit, AtCoder / seccamp'17'18, SecHack365'18, GlobalCybersecurityCamp'18
https://miyase256.github.io
ipfactory
情報科学専門学校 情報技術サークル「IPFactory」のOrganizationです。それぞれのアウトプット活動を促進するために発足されました。
https://twitter.com/_ipfactory_
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away