GDB の x コマンド(メモリの表示)

reversing pwn gdb

GDB の x(examine)は、指定したアドレスのメモリを、指定した個数・サイズ・フォーマットで表示するコマンド。gdb-peda のほかのコマンドは「gdb-peda 便利コマンド集」のノートを参照。

書式

x/[個数][サイズ][フォーマット] <ADDRESS> | $<REGISTER> | &<VAR_NAME>
サイズ バイト数
b 1(byte)
h 2(halfword)
w 4(word)
g 8(giant)
フォーマット 表示形式
x 16 進数
d 10 進数(符号付き)
c 文字
a アドレス(近くのシンボル名 + オフセットも表示)
s ヌル終端の文字列
i 機械語命令(逆アセンブル)

使用例

コマンド 表示されるもの
x/20gx $rsp スタックの先頭($rsp が指すアドレス)から 8 バイト単位で 20 個、16 進数で
x/32bx $rsp $rsp が指すアドレスから 1 バイト単位で 32 個、16 進数で(スタックの生バイト)
x/gx $rbp+8 保存されたリターンアドレス
x/10i $rip 次に実行する命令から 10 命令分
x/s $rdi $rdi が指すヌル終端文字列
x/s 0x402004 指定したアドレスにある文字列
x/s &<VAR_NAME> 文字配列の変数に入っている文字列(変数が char * のポインタなら & を付けずに x/s <VAR_NAME>)
x $rbp-0x10 / 以降を省略すると、前回の x のサイズとフォーマットを引き継ぐ

補足

  • x の直後に Enter を押すと、続きのアドレスから同じ形式で表示される。
  • gx は 8 バイトをリトルエンディアンで数値に直して表示し、bx はメモリに並んでいる順のまま 1 バイトずつ表示する。同じ場所でも見え方が違うので、ペイロードがどう並んだかを確かめるときは bx、アドレスや値として読みたいときは gx を使う。
  • $rbp+8 がリターンアドレスになるのは、関数の先頭で push rbp; mov rbp, rsp を実行した後($rbp の位置に呼び出し元の rbp、その 8 バイト上にリターンアドレスがある)。関数の入口でまだ prologue を実行していないときや、フレームポインタを使わないビルドでは当てはまらない。
  • x86-64 の Linux(System V ABI)では、関数の第 1 引数は $rdi で渡される。puts や strcmp などの呼び出しで止めて x/s $rdi を実行すると、渡された文字列を確認できる。
  • 64bit のバイナリではレジスタ名に $rbp、$rsp、$rip を使う。$ebp などは 32bit のバイナリでの名前。
  • アドレスは x/s 0x402004 のように数値のまま渡す。* を付けると、そのアドレスに入っている値を読む式になる(break *0x401000 の * とは意味が違う)。
  • s と i は表示の単位が文字列・命令なので、通常はサイズを付けない。