Reversing/Anti-Debugging

[static 안티디버깅] NtSetInformationThread()

string_ 2023. 6. 9. 14:12

'  NtSetInformationThread()  '

 

 

 

 

설명

스레드의 우선 순위를 설정합니다.

 

 

 

함수 원형

NtSetInformationThread()

 

 

NtSetInformationThread는 ZwSetInformationThread 의 wrapper function이며,

ring3 에서는 두 함수의 기능이 동일 하다.

 

NtSetInformationThread 2번째 파라미터에 ThreadHideFromDebugger를 전달 할 경우

첫번쨰 인자로 전달되는 ThreadHandle 과 디버거의 연결을 해제 (Dettach) 한다.

 

ThreadInformationClass는 enum (열거형)으로써 다음과 같다.

 

typedef enum _THREAD_INFORMATION_CLASS {
    ThreadBasicInformation,
    ThreadTimes,
    ThreadPriority,
    ThreadBasePriority,
    ThreadAffinityMask,
    ThreadImpersonationToken,
    ThreadDescriptorTableEntry,
    ThreadEnableAlignmentFaultFixup,
    ThreadEventPair,
    ThreadQuerySetWin32StartAddress,
    ThreadZeroTlsCell,
    ThreadPerformanceCount,
    ThreadAmILastThread,
    ThreadIdealProcessor,
    ThreadPriorityBoost,
    ThreadSetTlsArrayAddress,
    ThreadIsIoPending,
    ThreadHideFromDebugger
} THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;

 

 

 

 

ThreadHideFromDebugger (0x11)

디버거에서 실행 될 경우 첫번쨰 인자로 전달되는 ThreadHandle과 디버거의 연결을 해제(Dettach) 한다.

 

 

 

 

 

CODE

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

typedef DWORD(WINAPI* PFZWSETINFORMATIONTHREAD) (
	HANDLE		ThreadHandle,
	DWORD		ThreadInformationClass,
	PVOID		ThreadInformation,
	ULONG		ThreadInformationLength
	);

void anti_debug()
{
	PFZWSETINFORMATIONTHREAD pfZwSetInformationThread;
	pfZwSetInformationThread = (PFZWSETINFORMATIONTHREAD)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtSetInformationThread");
	pfZwSetInformationThread(GetCurrentThread(), 0x11, 0, 0);	// 0x11 : ThreadHideFromDebugger
	printf("Dettach");
}

int main(int argc, char** argv)
{
	anti_debug();
	return 0;
}

 

 

 

 

 

 

Disassemble

anti()

 

00A64929 Address 에서 call dword ptr ss:[ebp-0x8]

NtSetInformationThread(GetCurrentThread(),ThreadHideFromDebugger,0,0)가 호출된다.

 

00A64917 주소에서 PUSH 11 로 ThreadInformationClass 에 ThreadHideFromDebugger(0x11) 인자를 주는 것을

확인 할 수 있다.  NtSetInformationThread() 함수가 호출되고 나선

디버거와의 연결이 해제된다.

 

 

NtSetInformationThread() 를 호출 할 경우

더 이상 디버거는 Thread에 관련해 이벤트를 더 이상 받지 못하는 상태가 되므로

 

 

printf("Dettach"); 출력문까지 실행하지 못하게되고 프로그램이 디버깅이 중지 되고 죽게되 버린다.

 

 

디버거로 실행을 하지 않았을 경우에는 printf("Dettach"); 가 실행되어

Dettach 문자가 출력되게 된다.

 

 

 

 

 

 

실습

 

1. PUSH 11 로 ThreadInformationClass 에 ThreadHideFromDebugger(0x11) 가 전달되는데

이 2번쨰 인자를 00으로 수정한다.

 

2. NtSetInformationThread() 호출을 막는다.

 

3. 프로그램을 NtSetInformationThread() 호출 이후 상태로 접근한다.

(직접 실행 후 프로세스 Attatch 하여 접근한다.)