This code below working fine to create separated threads without pass any parameter of data types. Now i want know how i can pass parameters to method that executes when ZwCreateThreadEx
is called?
For example, how pass a HANDLE type and a type UNICODE_STRING?
My actual code:
#include "stdafx.h"
#include <conio.h>
#include <windows.h>
#include <Winternl.h>
#pragma comment(lib,"ntdll.lib")
void WINAPI ContinueExecution(LPVOID param)
{
printf("This thread is hidden from debugger!");
}
NTSTATUS(NTAPI *ZwCreateThreadEx) (
_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
);
NTSTATUS(NTAPI *ZwClose)(IN HANDLE ObjectHandle);
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
0xFFFF)
#else
#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
0x3FF)
#endif
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004
#define ZwCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread = 0;
HMODULE hNtdll = GetModuleHandleA("ntdll");
ZwCreateThreadEx = (NTSTATUS(NTAPI *) (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, HANDLE, PVOID, PVOID, ULONG, ULONG_PTR, SIZE_T, SIZE_T, PVOID)) GetProcAddress(hNtdll, "ZwCreateThreadEx");
if (ZwCreateThreadEx == NULL) return FALSE;
ZwClose = (NTSTATUS(NTAPI *)(IN HANDLE ObjectHandle)) GetProcAddress(hNtdll, "ZwClose");
if (ZwClose == NULL) return FALSE;
{
NTSTATUS ntStat = ZwCreateThreadEx(&hThread, THREAD_ALL_ACCESS, 0, ZwCurrentProcess(), (LPTHREAD_START_ROUTINE)ContinueExecution, 0, THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, 0, 0, 0, 0);
if (ntStat >= 0)
{
WaitForSingleObject(hThread, INFINITE);
}
else
{
printf("NtCreateThreadEx failed!");
}
ZwClose(hThread);
}
_getch();
return 0;
}
If you want to pass more than one value to your thread function you will need a struct to hold those values. And depending on code design the struct instance may need to be dynamically allocated (if it were local to the function calling ZwCreateThreadEx it may well no longer be valid by the time the thread actually runs).
And as Martin James says you would then pass a pointer to that struct instance as the Argument parameter.