Anti-Debugging OutputDebugString

안상준·2025년 6월 9일

Anti-Debugging

목록 보기
7/7

OutputDebugString

디버깅 상태에서 OutputDebingString 호출 시 디버거가 해당 문자열을 읽는다.
디버거가 연결된 경우 Sleep() 등 시간 지연 발생 -> 이를 이용해 디버거 탐지 가능

#include <windows.h>
#include <stdio.h>

int main() {
    LARGE_INTEGER freq, start, end;
    QueryPerformanceFrequency(&freq);

    QueryPerformanceCounter(&start);
    OutputDebugStringA("디버거 감지 테스트 문자열");
    QueryPerformanceCounter(&end);

    double delta = (double)(end.QuadPart - start.QuadPart) * 1000.0 / freq.QuadPart;

    printf("Time = %.6f ms\n", delta);

    if (delta > 0.05) {
        MessageBoxA(NULL, "디버거 탐지됨", "안티디버깅", MB_OK);
    } else {
        MessageBoxA(NULL, "디버거 없음", "안티디버깅", MB_OK);
    }

    return 0;
}

코드를 해석하면 타이머의 초당 주기를 설정해 준다. 타이머를 시작하고 OutputDebugStringA를 사용하여 디버깅 문자열을 출력한다. 이후 다시 타이머를 종료하여 시간을 계산해 준다. 조금 복잡해 보이는데 그 이유가 코드를 실행해본 결과 ms단위가 아니면 측정이 불가능 하였다. 측정된 값이 임계값을 초과하면 디버거가 있다고 간주한다. 코드를 실행해 보면

디버거가 없다고 뜨는 것을 볼 수 있고 시간을 보면 0.04 ms가 뜨는 것을 볼 수 있다. 이전 방식과 다르게 이건 Debugger에 attach를 시켜야 탐지 가능한 방법이기 때문에 OllyDbg로 실행파일을 attach 시켜서 확인해 보았다.

실행 결과 디버거가 탐지 됐다고 뜨는 것을 볼 수 있었다. 시간도 보면 41.36 ms가 측정된 것을 볼 수 있다.

로그도 확인해 보면 잘 뜨는 것을 볼 수 있다.
디버거마다 시간은 다른 것 같다. x64dbg로 확인한 결과

0.28 ms밖에 나오지 않은 것을 확인할 수 있었다.

장단점

  • 장점 : 윈도우 디버거 환경이면 거의 항상 작동
  • 단점 : 측정이 정확하지 않음

두 가지 디버거로 비교한 결과를 보면 알 수 있듯이 디버거에 따라 실행 시간이 다르다. 또한 같은 디버거로 실행하더라도 실행할 때 마다 시간이 다르게 측정된다. 우회 또한 측정값의 임계값만 수정한다면 쉽게 우회가 가능할 것 같다.

0개의 댓글