Anti-Debug NtCreateThreadEx

NtCreateThreadEx is a new API since Vista and it is very powerful. It is mostly used for DLL injection, but it can be used as an anti-debug trick aswell. No anti-anti-debug tool/plugin can defeat this.

NtCreateThreadEx lets you create a new thread, but the important feature is the CreateFlags parameter. The API declaration looks like this:

NTSYSCALLAPI
NTSTATUS
NTAPI
NtCreateThreadEx (
    _Out_ PHANDLE ThreadHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
    _In_ HANDLE ProcessHandle,
    _In_ PVOID StartRoutine,
    _In_opt_ PVOID Argument,
    _In_ ULONG CreateFlags,
    _In_opt_ ULONG_PTR ZeroBits,
    _In_opt_ SIZE_T StackSize,
    _In_opt_ SIZE_T MaximumStackSize,
    _In_opt_ PVOID AttributeList
);

The CreateFlags can be the following:

//SOURCE: http://processhacker.sourceforge.net/doc/ntpsapi_8h_source.html
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001
#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 // ?
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004
#define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 // ?
#define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 // ?
#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080

So with the THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER flag we can hide our newly created thread without calling NtSetInformationThread like demonstrated in my previous blog article.

Example code can look like this:

int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	HANDLE hThread = 0;
	NTSTATUS ntStat = NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS_VISTA, 0, NtCurrentProcess, (LPTHREAD_START_ROUTINE)ContinueExecution, 0, THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, 0, 0, 0, 0);
	if (ntStat >= 0)
	{
		WaitForSingleObject(hThread, INFINITE);
	}
	else
	{
		ShowMessageBox("NtCreateThreadEx failed!");
	}
	return 0;
}

void WINAPI ContinueExecution(LPVOID param)
{
	BOOLEAN check = FALSE;

	ShowMessageBox("This thread is hidden from debugger!");

	if (NtQueryInformationThread(NtCurrentThread, ThreadHideFromDebugger, &check, sizeof(BOOLEAN), 0) >= 0)
	{
		if (!check)
		{
			ShowMessageBox("Anti-Anti-Debug Tool detected!\n");
		}
		else
		{
			ShowMessageBox("Everything ok!\n");
		}
	}
	else
	{
		ShowMessageBox("Query ThreadHideFromDebugger not available!\n");
	}
}

Source code and binaries here:
https://bitbucket.org/NtQuery/teststuff/downloads/NtCreateThreadEx.rar
https://bitbucket.org/NtQuery/teststuff/src/7745ace377dfe6f63f455b51ab2917815c28e59b/NtCreateThreadEx.cpp?at=master

Leave a comment