【注意】このサイトに記載されていることを他人に試すことは「不正アクセス禁止法」に該当する場合があります。詳しくはこちらから

最初の一歩:GDBを「安全に」触ってみる(第3回/全8回)

黒ネコと学ぶ、GDBを使ったエクスプロイト開発への第一歩

GDBが難しいと感じる一番の原因は、やっぱり「壊しそう」とか「戻れなさそう」という不安ですね。
でも結論はこうです。
でも、GDBは「見る道具」です。正しく使えば何も壊れません。
 
今回のゴールは次の3つです。
・安全ルールを知る。(安心して触れる)
・基本操作:run / break / list / next / step / continueを体験する。
・「止める→少し進める→見る」を自分の手で回す。
※イメージです。

 GDBを安全に触るための3ルール

 安全に触るための3ルールとは
1.自分で作ったプログラムだけを対象にする。
2."-g"付きでコンパイルして「見える化」する。
3.変更せず観測(止める・進める・見る)に徹する。
 
GDBの基本サイクルは
・止める(break)
  ↓
・見る(list / print / info)
  ↓
・少し進める(next / step)
  ↓
・再開(continue)
 
このサイクルが回せれば、GDBはもう怖くありません。
 
 

Kaliで準備:安全な練習用プログラムを作る

 1.nonoツールを利用して、C言語で簡単なプログラムを作成します。
プログラム名は"gdb01-03"です。
nano gdb01-03.c
※実行後、nanoエディタが立ち上がります。
 
2.ソース
-----
#include <stdio.h>
 
int add(int x, int y) {
    int z = x + y;
    return z;
}
 
int main() {
    int a = 5;
    int b = 7;
    int c = add(a, b);
    printf("Result: %d\n", c);
    return 0;
}
-----
 
3.プログラム入力完了後
「Ctrl」+ o で、プログラムの書き込み
「Ctrl」+ x で、nanoエディター終了です。
 
4.コンパイルします。
gcc -g gdb01-03.c -o gdb01-03
 
今回は命令に"add()"を用意しました。
これで、"next"と"step"の違いを確認してみましょう。
 

Kaliで手を動かす①:安全に「止める→見る→進める」

 1.GDBを起動します。
gdb ./gdb01-03
 
2.mainで止めます。
break main
run
 
3.今どこ?(コードを見ます。)
list
 
4.変数を確認します。
但し、mainで止まっているため処理はまだ未実行です。
よって、未確定の値が表示されています。
print a
print b
 
5.1行進め、変数を確認します。
next
print a
print b
※"a"に"5"が確認できました。
 
"next" は「今の行の処理を行い、次の行へ」という命令でした。
※"continue"、"quit"でGDBを終了させてください。
 
 

Kaliで手を動かす②:next と step の違いを体感する

ここが今回の核心です。
 
next と step の違い
・next:関数呼び出しを「まとめて」1行として進む。(中に入らない)
・step:関数呼び出しの「中に入って」1行ずつ追う。
 
※GDBを起動させてくだそす。
 
1."add()"の呼び出し行にブレークを置く。
※"list"で行番号を確認します。
 
main内の "c = add(a, b);" の行番号が11なので
break gdb01-03.c:11
run
 
止まったら、ここで試します。
2."next"を試します。(addの中へ入らない)
next
 次の行(printfの行)へ進みます。
つまり、addの関数のは処理したあとに、"printf"の命令の先頭に位置づけされています。
 
3.もう一度同じ場所に戻って"step"を試します。
最も簡単なのは、再実行です。
run
※処理途中で
The program being debugged has been started already.
Start it from the beginning? (y or n) と表示されます。
GDBデバッグ中にプログラムを最初から再実行する際、現在の実行状態を破棄してメイン関数から再開する指示です。'y'を入力するとプログラムが再起動します。
と聞いてくるので"y"を入力します。
 
4.先ほど設定した、同じブレークで止まります。
今度は"step"を入力します。
step
 今度は"add()"関数の中("int z = x + y;")へ入りました。
これが"step"の動きです。
 
5.現在の位置を確認しながら進めます。
list
next
print z
 
6.確認が完了すれば、終了します。
continue
quit
 
 

最初の一歩:GDBを「安全に」触ってみるのまとめ

 GDBを「安全に」触るコツは、壊す操作を避けて「観測」に徹することです。
自分で作った小さなプログラムを、"-g"付きでコンパイルし、"break"で止めてから"list"で現在地を確認し、"next/step"で少しずつ進めながら、"print"で値を見ます。
特に重要なのは"next"と"step"の違いで、"next"は関数呼び出しを一行として進め(中に入らない)、"step"は関数の中へ入って一行ずつ追えます。
この差を体感すると、どこで何が起きているかを自分の目で確かめられるようになります。つまりGDBは怖い道具ではなく、止める→見る→進めるのサイクルで理解を積み上げる「安全な顕微鏡」なのです。