디버거를 감지 하는 방법에는 어떠한 것들이 있을까?
그저 간단한 팁형식의 글이다.
1) IsDebuggerPresent() 함수를 이용하는 방법.
IsDebuggerPresent() 함수는 Kernel32.dll에 의해 export되어 지는 함수인데,
해당 함수를 호출한 프로세스가 디버깅 당하는 중이면 TRUE(1)을,
아닐 경우는 FALSE(0)을 반환하는 함수이다.
loop 속에 다음과 같은 코드를 추가시킴으로써 감지 할 수 있다.
if(IsDebuggerPresent())
{
OutputDebugString("Debugeed!!");
//디버깅 당하는 중일떄의 어떠한 처리
}
2) IsDebuggerPresent() 함수 직접 구현의 방법.
IsDebuggerPresent() 함수는 내부적으로 해당 프로세스의 PEB구조체에
BeingDebuged의 값을 리턴해 준다.
아래가 IsDebuggerPresent() 코드의 전부이다.
-------------------------------------------
7C813093 > 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
7C813099 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30]
7C81309C 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX+2]
-------------------------------------------
그럼으로 우리는 IsDebuggerPresent()를 호출 하는 것이 아니라,
직접 해당 코드를 루프 속에 넣음으로써 똑같은 기능을 낼 수 있다.
다음과 같이 코드를 작성해 주면 될 것이다.
BOOL Pesudo_IsDebuggerPresent()
{
BOOL Retval = 0;
__asm
{
push eax
mov eax,dword ptr fs:{0x18]
mov eax,dword ptr ds:[eax+0x30]
movzx eax,byte ptr ds:[eax+0x2]
mov Retval,eax
pop eax
}
return Retval;
}
3) CheckRemoteDebuggerPresent() 함수를 이용하는 방법.
CheckRemoteDebuggerPresent() 함수는 자신의 프로세스 뿐만 아니라,
원하는 프로세스가 디버깅 당하는 중인지 까지 확인이 가능한 함수이다.
다음과 같은 방식으로 코드를 작성할 수 있다.
BOOL CheckDebugger(HANDLE hProcess)
{
BOOL Retval = 0;
CheckRemoteDebuggerPresent(hProcess,&Retval);
return Retval;
}
* CheckRemoteDebuggerPresent()는 NTAPI의 ZwQueryInformationProcess()로
연결된다.
ZwQueryInformationProcess()는 다음과 같은 호출 인자를 갖는 함수인데,
NTSTATUS NTAPI ZwQueryInformationProcess(HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength);
첫번쨰는 질의 하고자 하는 대상 프로세스의 핸들.
두번쨰는 질의 하고자 하는 내용(디버깅 여부는 ProcessDebugPort)
세번쨰는 결과
네번쨰는 길이
다섯번쨰는 실반환 길이이다.
해당 함수를 직접 호출하는 것도 하나의 방법이 될 수 있을 것이다.
4) NtGlobalFlag 확인법.
디버거가 해당 프로세스를 디버깅 할떄,
셋되어 지는 Flag들이 있는데, NtGlobalFlag는 그중에 하나이다.
다음과 같은 방식의 체크 함수를 작성 가능하다.
BOOL CheckNtGlobalFlag()
{
BOOL Retval = 0;
__asm
{
push eax
mov eax,dword ptr fs:[0x30]
mov eax,0x68
mov eax,dword ptr ds:[eax]
cmp eax,0x70
pop eax
jne NotDebuged
mov Retval,1
NotDebugged :
nop
}
return Retval;
}
5)
그외에도 KTHREAD_DEBUG_ACTIVE를 체크하는 방법이라던지,
수많은 방법들이 존재하지만, 역시나 아무래도 간단한 Tip형식의 글이라,
모두 다루지는 않고 마치도록 하겠다. :)
Posted by Dual



