윈도우 GUI를 이용한 안티디버깅 : FindWindow, OutputDebugString 기법 분석
FindWindow API는 실행 중인 위도우의 클래스명 또는 타이틀로 윈도우 핸들을 검색한다.
이를 통해 디버깅 도구(OllyDbg, x64dbg, WinDbg 등)를 탐지 가능하다.
#include <windows.h>
#include <stdio.h>
int main() {
HWND hwnd = FindWindow(NULL, "OllyDbg - [CPU]");
if (hwnd != NULL) {
MessageBox(NULL, "디버거 탐지됨! (OLLYDBG 창 존재)", "안티디버깅", MB_OK);
return 1;
} else {
MessageBox(NULL, "디버거 없음", "안티디버깅", MB_OK);
}
return 0;
}
FindWindow를 통해 현재 실행중인 윈도우 창의 이름을 찾아 MessageBox를 띄우는 코드인데

OllyDbg를 실행한 창을 보면 윈도우 이름을 볼 수 있다. OllyDbg - [CPU]라고 뜨는 것을 볼 수 있다. 실행 결과를 보면

잘 뜨는 것을 볼 수 있다.
위 예시 코드와 단점에서도 언급 했듯이, 이름이 정확하지 않거나, 타이틀을 바꾸면 우회가 가능하다. 타이틀 변경의 경우, OllyDbg는 플러그인과 후킹으로 수정이 가능하다고 한다.
먼저 개선 방법은, 현재 모든 창을 가져온 후 "OllyDbg"라는 문자열이 포함된 창이 있는지 확인하는 방법으로 해보았다.
#include <windows.h>
#include <stdio.h>
#include <string.h>
BOOL ContainsOllyDbg(HWND hwnd) {
char title[256];
GetWindowTextA(hwnd, title, sizeof(title));
if (strstr(title, "OllyDbg") != NULL) {
return TRUE;
}
return FALSE;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
if (IsWindowVisible(hwnd)) {
if (ContainsOllyDbg(hwnd)) {
MessageBoxA(NULL, "OllyDbg 창 감지됨!", "안티디버깅", MB_OK);
ExitProcess(1);
}
}
return TRUE;
}
int main() {
EnumWindows(EnumWindowsProc, 0);
MessageBoxA(NULL, "디버거 없음", "안티디버깅", MB_OK);
return 0;
}
EnumWindowProc을 통해서 현재 시스템의 모든 탑레벨 윈도우를 열거한다. ContainsOllyDbg 함수를 통해 문자열 "OllyDbg"가 포함돼 있는지 확인한다. 결과를 Message Box로 띄워준다. 매우 간단하며, 결과를 보면

잘 되는 것을 볼 수 있다.