クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

gdb でプログラムを止めて中身を見る

このレッスンのあとで: gdb でプログラムを止め、比べている文字列を読める。

55分のレッスンコマンド7件リバースエンジニアリングのラボ:gdb、radare2、strace、ltrace でプログラムを読む

止めれば実行中の値が読める

gdb は、プログラムを途中で止めて、メモリとレジスタの中身を見せるデバッガです。実行中にしか存在しない値も、止めれば読めます。たとえば、計算で作った合言葉です。

ファイルを調べるだけの strings では、そのような値は見えません。

このレッスンのゴール

メモ

gdb でプログラムを止め、比べている文字列を読める。

重要な言葉

ことばいみれい
デバッガプログラムを止めて、中身を見せる道具gdb
ブレークポイント実行をそこで止める印break strcmp
引数関数に渡す値。1番目は rdi、2番目は rsi
x/sアドレスの先にある文字列を見せるコマンド
ローダー実行の前に、必要な部品をつなぐ部分

学生が入力するセルは、このプレビューでは空白です。

strings で見つからない合言葉

次の練習用プログラムは、合言葉を実行中に作ります。snprintf が、名前の kaede と数の 26 をつなげて、kaede26 にします。

ファイルの中にあるのは、kaede と、つなぎ方の %s%d だけです。完成した合言葉は、メモリの中にしかありません。

ソースを書く

コマンド
printf '%s\n' '#include <stdio.h>' '#include <string.h>' 'int main(int c, char **v) {' '    char key[32];' '    snprintf(key, sizeof key, "%s%d", "kaede", 26);' '    if (c == 2) {' '        if (strcmp(v[1], key) == 0) { puts("OK"); return 0; }' '    }' '    puts("NG");' '    return 1;' '}' > /tmp/rev4.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

プログラムを作る

コマンド
gcc -O0 -no-pie -o /tmp/rev4 /tmp/rev4.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

ソースを消す

コマンド
rm /tmp/rev4.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

strings で探す

コマンド
strings /tmp/rev4 | grep -E "kaede|%s"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

ブレークポイントで止める

break strcmp は、strcmp を呼ぶ直前で止める印です。止まった瞬間、rdi と rsi が、比べる2つの文字列の場所を指しています。

x/s $rdi は、rdi が指す先の文字列を見せます。x/s $rsi は、2つ目です。

最初に覚える gdb のコマンド

コマンド意味
break 名前その関数で止める印をつける
runプログラムを動かし始める
continue止まったところから続ける
x/s アドレスその場所の文字列を見る
info registersレジスタの値を一覧にする
btどの関数から呼ばれたかをたどる
quitgdb を終わる

学生が入力するセルは、このプレビューでは空白です。

なぜ main で一度止めるのか

ローダーも、関数の名前をつなぐために、strcmp を使います。だから、最初から break strcmp だけだと、その呼び出しで止まります。

LD_BIND_NOW=1 で名前を先にすべてつなぎ、break main で main まで進めます。それから break strcmp と continue で、自分の呼び出しで止めます。

間違えた合言葉で止める

コマンド
gdb -batch -ex 'set environment LD_BIND_NOW=1' -ex 'break main' -ex run -ex 'break strcmp' -ex continue -ex 'x/s $rdi' -ex 'x/s $rsi' --args /tmp/rev4 hoge 2>&1 | grep '^0x' | cut -f2

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

読んだ合言葉で止める

コマンド
gdb -batch -ex 'set environment LD_BIND_NOW=1' -ex 'break main' -ex run -ex 'break strcmp' -ex continue -ex 'x/s $rdi' -ex 'x/s $rsi' --args /tmp/rev4 kaede26 2>&1 | grep '^0x' | cut -f2

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

読んだ合言葉で実行

コマンド
/tmp/rev4 kaede26

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

最初に止まった strcmp が、自分のプログラムの比較だと思いがちです。実際は、ローダーやライブラリの比較で止まることもあります。止まったら x/s で中身を見て、自分が入力した文字が出ているか確かめましょう。

このラボとソースについて: リバースエンジニアリングのラボ:gdb、radare2、strace、ltrace でプログラムを読む

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。