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

無料レッスン

ltrace と strace の使い方

このレッスンのあとで: ltrace と strace で、プログラムが探すファイルを見つけられる。

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

プログラムの呼び出しを一覧にする

ltrace と strace は、プログラムが呼ぶ関数と、OS に頼む操作を、実行しながら一覧にする道具です。コードを1行も読まなくても、どのファイルを開こうとしているかが分かります。

調べるのは、自分で作ったプログラムと、ラボのプログラムだけです。

このレッスンのゴール

メモ

ltrace と strace で、プログラムが探すファイルを見つけられる。

重要な言葉

ことばいみれい
ライブラリ呼び出し用意された関数を呼ぶことfopen
システムコールプログラムが OS の核に頼む操作openat
トレース実行中の呼び出しを、順に記録すること
ENOENTそのファイルがない、という誤りの名前
設定ファイルプログラムが起動時に読む、設定を書いたファイル

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

呼び出しには2つの層がある

プログラムは、fopen のようなライブラリの関数を呼びます。ライブラリは、その裏で OS の核に、openat のようなシステムコールで頼みます。

ltrace は上の層、strace は下の層を見せます。2つを並べると、何を頼み、何が起きたかが分かります。

設定ファイルを探すプログラム

次の練習用プログラムは、名前を受け取り、/tmp/rev6-名前.cfg を開こうとします。あれば loaded、なければ no config と出します。

ソースを作ってバイナリにし、ソースを消してから、呼び出しを追います。

ソースを書く

コマンド
printf '%s\n' '#include <stdio.h>' '#include <stdlib.h>' 'int main(int c, char **v) {' '    char p[64];' '    FILE *f;' '    if (c != 2) { puts("usage: rev6 NAME"); return 2; }' '    snprintf(p, sizeof p, "/tmp/rev6-%s.cfg", v[1]);' '    f = fopen(p, "r");' '    if (f) { fclose(f); puts("loaded"); return 0; }' '    puts("no config");' '    return 1;' '}' > /tmp/rev6.c

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

プログラムを作る

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

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

ソースを消す

コマンド
rm /tmp/rev6.c

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

ライブラリ呼び出しを追う

コマンド
ltrace /tmp/rev6 spring 2>&1 | grep fopen

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

fopen の行から道が読める

行の最初は呼んだ関数で、括弧の中は引数です。fopen("/tmp/rev6-spring.cfg", "r") は、その道のファイルを読むために開く、という意味です。

行の終わりの = nil は、開けなかったという意味です。ファイルの名前が、実行しながら作られていたことも分かります。

システムコールを追う

コマンド
strace -e trace=openat /tmp/rev6 spring 2>&1 | grep rev6

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

行の終わりの読み方

行の終わり意味
= 3開けた。3 はファイルの番号
= -1 ENOENTそのファイルがなかった
= -1 EACCES権限がなくて開けなかった
= nilfopen が開けなかった

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

ファイルを作ると結果が変わる

探されているファイルを作ってから、同じ操作をもう一度見ます。空のファイルで十分です。

今度は、行の終わりが = 3 になり、プログラムは loaded と答えます。トレースで道が分かったので、答えが変わりました。

探されているファイルを作る

コマンド
touch /tmp/rev6-spring.cfg

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

もう一度システムコールを追う

コマンド
strace -e trace=openat /tmp/rev6 spring 2>&1 | grep rev6

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

そのまま実行する

コマンド
/tmp/rev6 spring

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

作ったファイルを消す

コマンド
rm /tmp/rev6-spring.cfg

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

よくある間違い

注意

ltrace と strace は、同じものを見せると思いがちです。実際は、ltrace は関数の呼び出し、strace は OS への要求を見せます。fopen が1つあれば、その裏に openat が出ますが、数も名前も違います。

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

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