디버거를 탐지해내는 기법에 대한 설명입니다.
ntdll!NtQueryInformationProcess() API를 이용하면 프로세스의 디버깅 관련 정보를 비롯하여 매우 다양한 정보를 얻을 수 있습니다.
NTSTATUS WINAPI NtQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInforamtionClass,
__out PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
)
두 번재 파라미터 PROCESSINFOCLASS ProcessInformationClass에 원하는 정보형식을 입력한 후 NtQueryInformationProcess()를 호출하면 세번재 파라미터 PVOID ProcessInformation에 해당 정보가 세팅됩니다.
PROCESSINFOCLASS는 열거형(enum)으로써 다음과 같은 값을 가집니다.
enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessQuotaLimit,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessraisePriority
ProcessDebugPort = 7, // 0x7
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnalbeAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
MaxProcessInfoClass,
ProcessWow64Inforamtion = 26,
ProcessImageFileName = 27,
ProcessDebugObjectHandle = 30, // 0x1E
ProcessDebugFlags = 31, // 0x1F
}
위 코드에서 디버거 탐지에 사용 되는 것은 ProcessDebugPort(0x7), ProcessDebugObjectHandle(0x1E), ProcessDebugFlags(0x1F)
ProcessDebugPort(0x7)
프로세스가 디버깅 중일 때 DebugPort가 할당됩니다.
ProcessInformationClass파라미터에 ProcessDebugPort(0x7)값을 입력하면 DebugPort를 얻을 수 있습니다.
만약 프로스세가 디버깅 중이 아니라면 dwDebugPort 변수에 0이 세팅됩니다.
디버깅 중이라면 0xFFFFFFFF이 세팅됩니다.
// ProcessDebugPort(0x7)
DWORD dwDebugPort = 0;
pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugProt, &dwDebugPort,
sizeof(dwDebugPort), NULL);
if (dwDebugPort != 0x0) printf("Debugging !! \n");
else printf("Not Debugging !! \n");
ProcessDebugObjectHandle(0x1E)
프로세스가 디버깅될 때 Debug Object가 생성됩니다. ProcessDebugObjectHandle(0x1E)을 입력하면 DebugHandle을 구할 수 있습니다. 프로세스가 디버깅 중이라면 Debug Object Handle은 값이 존재할 것이고, 디버깅 중이 아니라면 Debug Object Handle은 NULL입니다.
// ProcessDeubgObjectHandle(0x1E)
Handle hDebugObject = NULL;
pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject,
sizeof(hDebugObjectHandle), NULL);
if (hDebugObject != 0x0) printf("Debugging !! \n");
else printf("Not Debugging !! \n");
ProcessDebugFlags(0x1F)
DebugFlags를 확인해서 프로세스의 디버깅 여부를 판별합니다.
ProcessDebugFlags(0x1F)를 입력하여 DebugFlags를 구합니다.
DebugFalgs값이 0이면 디버깅 상태이고, 1이면 디버깅이 아닙니다.
// ProcessDebugFlags(0x1F)
BOOL bDebugFlags = TRUE;
pNtQueryInformationProcess(GetCurrentProcess(), ProcessDeubgFlags, &bDebugFlags,
sizeof(bDebugFlags), NULL);
if (bDeubgFlags == 0x0) print("Debugging !! \n");
else print("Not Debugging !! \n");
'reversing' 카테고리의 다른 글
안티 디버깅 Dynamic (1) | 2022.10.05 |
---|---|
안티 디버깅 Static (2) | 2022.10.04 |
IA-32 Instruction 포맷 (0) | 2022.09.27 |
TEB (0) | 2022.09.16 |
TLS CALLBACK (0) | 2022.08.31 |
댓글