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

無料レッスン

プログラムを実行せずに調べる

このレッスンのあとで: プログラムを実行せずに、file、strings、objdump で調べられる。

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

ソースがなくても中身は読める

リバースエンジニアリングとは、完成したプログラムそのものから、しくみを読み取る作業です。ソースコードがなくても、実行する前に分かることがたくさんあります。

使ってよいのは、ラボ用に作ったプログラムと、自分のコピーだけです。他人のソフトの保護やライセンス、ゲームには、決して使いません。

このレッスンのゴール

メモ

プログラムを実行せずに、file、strings、objdump で調べられる。

重要な言葉

ことばいみれい
バイナリ機械語の命令が入った、実行できるファイル/tmp/rev1
ELFLinux のプログラムのファイル形式
文字列プログラムの中に入っている、読める文字の並びmomiji
逆アセンブル機械語の命令を、読めるアセンブリに戻すこと
シンボル関数などにつけた名前
ストリップシンボルを消すこと。命令は残る

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

このモジュールの約束

重要

目的は、欠陥がどう見えるかを知り、見つけて直せるようになることです。対象は、ラボ用のプログラムと、自分の練習用のプログラムだけです。他人のソフト、ライセンス、ゲーム、保護の仕組みは、決して対象にしません。

練習用のプログラムを作る

まず、合言葉を調べる短い C のプログラムを自分で作ります。ソースは作ったあとすぐ消し、バイナリだけを調べます。

合言葉は、あなた自身が決めた momiji です。ラボの5つのプログラムの鍵とは、関係がありません。

ソースを書く

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

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

プログラムを作る

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

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

ソースを消す

コマンド
rm /tmp/rev1.c

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

file はファイルの種類を答える

file は、ファイルの先頭を読んで、種類を答えます。プログラムは実行しません。

答えには、形式、プロセッサ、シンボルが残っているかが入ります。ELF は Linux のプログラムの形式です。

ファイルの種類を見る

コマンド
file /tmp/rev1

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

strings は読める文字を取り出す

プログラムは、画面に出す言葉や比べる言葉を、そのままの文字で中に持っています。strings は、読める文字が4つ以上続く部分を、順に出します。

短い2文字の OK や NG は、初期設定では出ません。下の grep は、その長い出力から momiji だけを残します。

小さな strings を読む

コード: python
# 小さな strings: 読める文字が4つ以上続くところを取り出します。
data = "\x00\x01momiji\x00NG\x00\x02hello"
found = []
now = ""
for ch in data:
    if " " <= ch <= "~":
        now = now + ch
    else:
        if len(now) >= 4:
            found.append(now)
        now = ""
if len(now) >= 4:
    found.append(now)
print(found)
# 4 を 2 に変えて、もう一度実行しましょう。

合言葉を探す

コマンド
strings /tmp/rev1 | grep momiji

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

objdump は命令を読める形にする

objdump -d は、機械語の命令をアセンブリに戻して、1行に1命令で見せます。--disassemble=main で、main だけに絞れます。

call は、別の関数を呼ぶ命令です。cmp は、2つの値を比べる命令です。次のレッスンで、読み方を学びます。

call と cmp を探す

コマンド
objdump -d -M intel --no-show-raw-insn /tmp/rev1 --disassemble=main | grep -E "call|cmp"

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

調べる道具と分かること

道具実行する?分かること
fileしない種類、プロセッサ、シンボルの有無
stringsしない中に入っている読める文字
objdump -dしない命令の並びと、呼んでいる関数
プログラム自身する入力に対する答え。ただし中身は見えない

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

よくある間違い

注意

ソースを消してコンパイルすれば、中身は隠れると思いがちです。実際は、文字列も呼ぶ関数の名前も、命令の順番も残ります。プログラムが動くために知るべきことは、読む人にも読めます。秘密を中に持たせてはいけません。

間違えた合言葉で実行

コマンド
/tmp/rev1 hoge

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

見つけた合言葉で実行

コマンド
/tmp/rev1 momiji

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

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

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