ウィンドウデバッグ迂回防止


デバッグ防止とは?


デバッグ防止は、デバッグと分析プログラムをブロックすることを意味します.アンチデバッグテクノロジーが適用されていると疑われるプログラムがデバッグ中である場合、エラーなどが発生してデバッグが妨げられます.デバッグ防止を学ぶ理由は、その名の通り、デバッグを防止し、デバッグ防止技術を応用したプログラムを再デバッグし、分析するためです.
代表的なデバッグ防止方法は、プロセス情報を含む構造体(PEB)のbeingDebuggedバイトをチェックして、プロセスがデバッグモードにあるかどうかを確認し、デバッグが時間遅延をもたらすかどうかを確認することです.実行中に一度だけチェックする場合は静的デバッグ防止と呼ばれ、実行中にチェックを継続する場合は動的デバッグ防止と呼ばれます.TLSコールバック関数はEntry Pointコードより先に実行され、デバッグ防止にも使用できます.

デバッグの適用


このセクションで作成するコードは、環境によって異なる場合があります.
まず、次のコードを作成します.MSVC x 86バージョンに基づいて作成されます.
#include <stdio.h>
#include <windows.h>

int isdebug(void) {
	__asm {
		mov eax, fs:[0x30]
		mov eax, [eax + 2]
	}
}

int isdbg(void) {
	if(isdebug() == 0xFFFF0401) {
		return 1;
	} else {
		return 0;
	}
}

int main(void) {
	if(isdbg()) {
		puts("debugger detected - 0");
	} else if(IsDebuggerPresent()) {
		puts("debugger detected - 1"); 
	} else {
		puts("execve completed");
	}
	return 0;
}
上記のコードには、デバッグを防止する2つの方法があります.まず,PEBに直接アクセスして検査を行い,次にウィンドウから提供されるIsDebuggerPresent()関数を用いて検査を行う.しかし、どちらの方法もPEBを使用しています.
第1の方法では、FSレジスタはTEBを指し、FS:[0 x 30]の位置はPEBを指す.BeingDebuggedバイトを参照します.しかし、このような直接的な接触は環境によって異なりやすい.
2つ目の方法はwindowsです.hで定義されたウィンドウで提供されるIsDebuggerPresent()関数を使用します.実際,この方法は最終的にこの関数においてPEBを参照して把握される.

デバッグの回避


実際、上記のコードでデバッグ防止を迂回する場合は、最終的にデバッグ防止関数が呼び出されif文を使用してチェックされるため、条件分岐を変更するだけです.

ここではx 96 dbgツールを使用してデバッグしました.まずmain関数の場所を検索する方法はいろいろありますが、ここでは右クリック->次の(S)->すべてのモジュール->文字列参照(S)を使用して文字列参照を検索します.

文字列からさらに下に下がり、プログラムが終了する前にブレークポイントを設定します.これはプログラムが直接閉じて結果が確認できないようにするためです.

直接実行すると、デバッグ防止機能がデバッグを検出したと表示されます.アセンブリ機能を使用して迂回します.

迂回する関数は以下のようになります.

各ブランチをjmpに変換すると、無条件にジャンプするため、デバッグ防止を迂回できます.

両者とも上記のように変更した.

最終的にファイル→ファイルパッチ→ファイルパッチを選択して保存します.

保存したファイルでデバッグすると、デバッグが正常に迂回したことがわかります.