16

次のアセンブリ コードがアンチデバッグ ツールであるのはなぜですか?

l1:
call l3
l2:
;some code
l3:
mov al, 0c3h
mov edi, offset l3
or ecx, -1
rep stosb

私はC3hがであることを知っており、 がオフセットに従ってオペコードとして値RETNを書き込むことを知っています。stobsalediecxrep

また、Intel アーキテクチャで元の形式としてプリフェッチされた場合に実行されるstobsという事実も認識しています。stosw

プログラムをデバッグモードで実行すると、プリフェッチは無関係で、l2 ラベルが実行されます (シングルステップであるため)。それ以外の場合、デバッガーがない場合、l1 と l3 の間でピンポンになります。

4

2 に答える 2

14

プログラムがデバッグされるとき (つまり、単一ステップ)、プリフェッチ キューは各ステップでフラッシュされます (割り込みが発生したとき)。ただし、正常に実行された場合は発生しませんrep stosbrep movs古いプロセッサは、 と を除いて変更された自己変更コードをサポートするために、キャッシュ領域へのメモリ書き込みがあった場合でも、それをフラッシュしませんでしたrep stosb。(IIRC は最終的に i7 プロセッサで修正されました。)

そのため、デバッガー (シングル ステップ) がある場合、コードが正しく実行され、rep stosbが置き換えられたときにret l2が実行されます。デバッガーがない場合rep stosbは続行されますが、ecx可能な限り最大であるため、最終的に書き込むべきではない場所に書き込み、例外が発生します。

このアンチデバッグ手法については、このホワイト ペーパーで説明しています。

于 2012-04-10T14:50:25.440 に答える
2

ここでデバッガーが行う唯一のことは、時間遅延を追加することです。それが、これがどのように機能するかの鍵かもしれません。Intel (および AMD と思われます) のマニュアルでは、変更された命令を含むキャッシュ ラインが変更されたことをプログラムが CPU に通知しない限り、自己変更コードは「機能する」ことは保証されないと明示的に述べています。これは、プリフェッチ ロジックを安価にするためです。チップ設計者は、命令キャッシュラインのすべてのバイトがまだ有効であることを継続的にテストするハードウェアを望んでいません。

したがって、デバッガーで何が起こるかは、l1 が l3 を呼び出し、rep stosb の後に戻り値が格納され、単一のステップ実行でデバッガーによって引き起こされる長い遅延のために戻り値が実行され、変更後に l3 を含むキャッシュラインが強制的に再フェッチされることだと思います。

デバッガーがなければ、stosb が実行された後の命令 (表示されていません) を推測します。「デバッガーなし」へのジャンプである場合、ジャンプの成功は、シングルステップ デバッガーが使用されていないことを示します。

アプリケーションでこのコードを見つけた場合、実行を拒否します。

于 2012-04-10T14:59:12.867 に答える