INT 3命令

いまどきのアセンブラプログラミング―Windowsプログラム解析・開発の独習
をなにげなく読んでいて見つけた命令。

INT 3

という特殊な割り込み命令をプログラム中に埋め込むことでブレイクポイントをつくれるらしい。
これは(0xcc)という1バイト命令で通常のソフトウェア割り込みとは若干異なるみたい。

実験してみる

#include <stdio.h>
int main()
{
  puts("hello");
  puts("world");
  return 0;
}

というコードにブレークポイントを仕込んでみる。
2つ目のputsを呼び出す箇所で1バイト分0xccを上書きしてみた。

% gcc test.c
% objdump -d a.out  <- 逆アセンブルしたコードを見て
% vim -b a.out <- バイナリファイルを直接編集
... 0408 e8ff feff  ...
          | (callをしている箇所)
          v
... 0408 ccff feff ...

実行

% ./a.out
hello
[1]    4122 trace trap  ./a.out

SIGTRAPが送出された。ということはデバッガはこのシグナルをキャッチして処理を行っているんだな〜なるほど。

まさかプログラムを直接書き換えてブレイクポイントを実現しているのだとは知らなかった。ブレイクした後から再開するためには上書きされた1バイトを復元してそこから実行すればいいという事だろう。

メモリにロードされたプログラムを書き換える方法とかはまだ知らないけれどいろいろ面白い事ができそうだな〜。ブレイクしてレジスタ等を読み取って、それを書き換えて続きを実行するとか。


ブレイクポイントと言えば他にメモリアクセスに対してかけることもできるけどこれはどう実現しているんだろう?興味があるなぁ。