バイナリファイルを取得し、そのパスワード(宿題)を解読することになっています。与えられた関数(バイナリファイルの一部である関数)もありました。その関数は、入力文字列が正しいパスワードと1文字ずつ比較され、文字が間違っているとすぐにfalseを返すことを示していました(これは安全な方法ではありません)時間のリークがあり、次のように正しいパスワードの長さを把握しているためです。例)。しかし、私たちの先生は結果を返すランダムタイマーを追加し(正しい/間違っています)、少し難しくしています...
とにかく、私はすでにリバースエンジニアリングでそれを成功させており、正しいパスワードを取得しています。今、私はそれをコマンドラインで遊んでいます:
/usr/bin/time -v ./program_name enter_password
このコマンドを使用すると、システム時間、スワップ、実行時間などの多くの情報が得られます。しかし、私にとって最も興味深いのは、「自発的なコンテキストスイッチ」です。なぜなら、入力するパスワードの正しい文字が多いほど、「自発的なコンテキストスイッチ」が少なくなるからです。 「なるほど!
入力する文字が間違っているほど、「自発的なコンテキストスイッチ」が多くなります。
そのコマンドを入力して文字を入力し、「自発的なコンテキストスイッチ」を観察するだけで、パスワードを解読するのに約2時間かかりました。 1文字が正しかったときはいつでも、「自発的なコンテキスト切り替え」が1つ減少しました。
私の質問、「自発的なコンテキストスイッチ」とは正確に何であり、なぜパスワードのクラックに役立ちましたか?
time
のマニュアルページ は、自発的および非自発的なコンテキストスイッチの概念を説明しています。
_The resource specifiers [...] are:
c Number of times the process was context-switched involuntarily
(because the time slice expired).
w Number of times that the program was context-switched voluntarily,
for instance while waiting for an I/O operation to complete.
_
(引用は私のDebianシステムからのものです。リンクされたmanページには少し異なるテキストがあります)
つまり、プロセスが他に何もしないためにCPUを離れた場合(外部で何かが発生するのを待っている間)、コンテキストの切り替えは自発的です。何らかの計算を続行したいが、OSが他のプロセスに切り替えるときだと判断した場合は、非自発的です。
これがパスワードチェックプログラムとどのように関連するかは、プログラムが実際に何をするかによって異なります。
コメントにリンクされているソースコードから、プログラムは一致しない文字ごとにusleep()
を1回呼び出し、その後、次の文字の比較ループを継続していることがわかります。スリープは、CPUを譲るのと同じくらい自発的であるため、これらの呼び出しは、一致しない各キャラクターの自発的なコンテキストスイッチとして表示されます。
Linuxでは、strace
での呼び出しも確認できるはずです。
最後の遅延は、T * (Rand() % 3)
のランダムなスリープ、つまり定数の0、1、または2倍から生じます。これはかなり粗い粒度であるため、同じパスワードで複数の試行を行うことにより、簡単に平均化できます。