アンチデバッグおよび抗抗デバッグ
アンチデバッグは何ですか?抗抗デバッグは何ですか?
静的なアンチデバッギング
特徴:一般的なブロックデバッガ、デバッグだけで試運転の開始時に1回の休憩の後に理由を見つける必要があるかもしれません
PEB
⭐BeginDebug
:デバッグフラグ
// 通过检查 PEB.BeingDebuged 字段判断是否被调试 // 可以在目标程序运行之前修改对应的字段为 0 进行反反调试 bool CheckBeingDebugged() { __asm { ; 获取到 PEB 的内容 mov eax, fs:[0x30] ; 获取 PEB 内偏移为 2 大小为 1 字节的字段 movzx eax, byte ptr[eax + 2] } } int main() { if (CheckBeingDebugged()) printf("当前处于[被]调试状态\n"); else printf("当前处于[非]调试状态\n"); system("pause"); return 0; }
// 使用 IsDebuggerPresent 原理同样是判断 PEB.BeingDebuged // 通过 HOOK 函数和修改对应字段的方式可以进行反调试 int main() { if (IsDebuggerPresent()) printf("当前处于[被]调试状态\n"); else printf("当前处于[非]调试状态\n"); system("pause"); return 0; }
Ldr
メモリ状態Heap
(Flags
、Force Flags
):ヒープの状態NtGlobalFlag
:カーネルのグローバルマークPEB.NtGlobalFlag
デバッグ状態にあるときに、デバッグするかどうかを決定PEB.NtGlobalFlag
されて格納された0x70
、抗-抗デバッグすることができるフラグを変更します
bool CheckNtGlobalFlag() { __asm { ; 获取到 PEB, 保存在 FS :[0x30] mov eax, fs : [0x30] ;获取到 NtGlobalFlag 字段的内容 mov eax, [eax + 0x68] } } int main() { if (CheckNtGlobalFlag()) printf("当前处于[被]调试状态\n"); else printf("当前处于[非]调试状态\n"); system("pause"); return 0; }
TEB
StaticUnicodeString
:静的バッファ
オリジナル
API
NtQuerySystemInformationProcess()
ProcessDebugPort(0x07)
:デバッグポートを取得します。ProcessDebugObjectHandle(0x1E)
:ハンドルのデバッグを取得ProcessDebugFlag(0x1F)
:デバッグフラグを取得します。
NtQuerySystemInformation()
:SystemKernelDeBuggerInformation(0x23)
:取得システムのデバッグ状態(デュアル)
NtQueryObject()
:横断システムのカーネル
攻撃デバッガ
NtSetInformationThread()
ThreadHideFormDebugger(0x11)
検査工程を開きます
SetDebugPrivilege
プロセスがデバッグ権限を持っているかどうかをチェック➡️
使用する
TLS
コールバック関数を通常の使用
API
- 親プロセスをチェック
- プロセスが正常に開いている場合、それは親プロセスである必要があり
Explorer.exe
、それは、リソースマネージャであるとの判断がされていない場合は、あなたは参照を提供するために、テストすることができます。
- プロセスが正常に開いている場合、それは親プロセスである必要があり
bool CheckParentProcess() { struct PROCESS_BASIC_INFORMATION { ULONG ExitStatus; // 进程返回码 PPEB PebBaseAddress; // PEB 地址 ULONG AffinityMask; // CPU 亲和性掩码 LONG BasePriority; // 基本优先级 ULONG UniqueProcessId; // 本进程PID ULONG InheritedFromUniqueProcessId; // 父进程PID }stcProcInfo; // 查询到目标进程的对应信息,主要是 父进程 ID NtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &stcProcInfo, sizeof(stcProcInfo), NULL); // 查询资源管理器对应的 PID DWORD ExplorerPID = 0; DWORD CurrentPID = stcProcInfo.InheritedFromUniqueProcessId; GetWindowThreadProcessId(FindWindow(L"Progman", NULL), &ExplorerPID); // 比对两个 PID 的值,相同就OK,不同就可能被调试 return ExplorerPID == CurrentPID ? false : true; } int main() { if (CheckParentProcess()) printf("当前处于[被]调试状态\n"); else printf("当前处于[非]调试状态\n"); system("pause"); return 0; }
- ウィンドウ名をチェック
- 原則は、対応するウィンドウの名前が存在して検索し、ウィンドウクラスまたはウィンドウを通じて、デバッガやその他の分析ツールをチェックすることです。【欠点は通常固定されていないウィンドウの名前であり、非常に不便チェック]
- また、デバッガやその他のツールは、プロセスを横断によって存在するかどうかを確認することができます。【欠点は、exeファイル名の名前を変更することにより、プロセスを変更することができることです]
int main() { if (FindWindow(NULL, L"OllyDbg")) printf("存在调试器\n"); else printf("没检测到调试器\n"); return 0; }
- プロセス名を確認してください
- 原理は、クエリである
EPROCESS
あなたがすることはできませんので、関連分野の構造R3
変更R0
データを、私たちができるだけでHOOK
- 原理は、クエリである
bool CheckProcessDebugPort() { int nDebugPort = 0; NtQueryInformationProcess( GetCurrentProcess(), // 目标进程句柄 ProcessDebugPort, // 查询信息类型(7) &nDebugPort, // 输出查询信息 sizeof(nDebugPort), // 查询类型大小 NULL); // 实际返回数据大小 // 如果返回的是 -1 ,那么就被调试了 return nDebugPort == 0xFFFFFFFF ? true : false; } int main() { if (CheckProcessDebugPort()) printf("当前处于[被]调试状态\n"); else printf("当前处于[非]调试状态\n"); system("pause"); return 0; }
- ファイル名やファイルパスをチェック
- レジストリチェッカー
- ...
- 親プロセスをチェック
ダイナミックアンチデバッギング
- 特徴:デバッグを必要と頻繁にトリガすることができ、デバッグプロセスにおける一般的なブロックデバッガデバッグのプロセスに目を保ちます
- 使用
SEH
- 異常な
- ブレークポイント
SetUnhandleedExceptionFilter()
- タイム・チェック
- シングルステップの検査
- パッチをチェック
- ファンファンのコンパイル
- コードを盗みます
- ページの保護
- シェル
- 仮想マシン
OllyDbg
プラグインの作成
- どのように通常存在するプラグイン?
通常でDLL
道の存在が、拡張子が変更されることがあり
- プラグインアプリケーションをすべて検索するには?
すべてのプラグインは、特定のパスに保護されなければなりません
- あなたは、アプリケーションがその要件を満たしているか知っていますか?
- プラグインその機能を説明するために、情報を名前を指定し提供しなければならない、プラグインはまた、機能によって、特定の機能を提供する必要があるの名前に対応