[static 안티디버깅] 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
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 하여 접근한다.)