Как обычно, 1) NT-only, 2) кому надо — юзайте.
Смысл сего кода — создавать и прибивать потоки с минимальными дополнительными затратами по времени и ресурсам. Более подробные комментарии и описания функций — по адресу
http://zw.nightmail.ru/_thread.htm.
Собственно код.
//функция создает поток и возвращает адрес DeallocationStack
NTSTATUS NTAPI NewThread(OUT PHANDLE phThread, IN HANDLE hProcess, IN PVOID StartRoutine, IN PVOID Argument OPTIONAL, OUT PVOID *pDeallocationStack OPTIONAL, OUT PCLIENT_ID ClientID OPTIONAL)
{
NTSTATUS ns = RtlCreateUserThread(hProcess, 0, 0, 0, 0, 0, StartRoutine, Argument, phThread, ClientID);
if ((ns == STATUS_SUCCESS) && (pDeallocationStack))
{
THREAD_BASIC_INFORMATION tbi;
if (ZwQueryInformationThread(*phThread, ThreadBasicInformation, &tbi, sizeof(THREAD_BASIC_INFORMATION), 0) == STATUS_SUCCESS)
if (tbi.TebBaseAddress)
{
if (hProcess == 0xFFFFFFFF)
{
*pDeallocationStack = ((PTEB)(tbi.TebBaseAddress))->DeallocationStack;
}
else
{
ULONG Dummy = 0;
if (ZwReadVirtualMemory(hProcess, (PVOID)((ULONG)(tbi.TebBaseAddress) + 0xE0C), pDeallocationStack, 4, &Dummy) != STATUS_SUCCESS)
*pDeallocationStack = NULL;
}
}
else
{
*pDeallocationStack = NULL;
}
}
return ns;
}
//Функция уничтожает поток и освобождает его DeallocationStack
NTSTATUS NTAPI KillThread(IN HANDLE hProcess, IN HANDLE hThread, IN PVOID DeallocationStack OPTIONAL)
{
NTSTATUS ns = ZwTerminateThread(hThread, 0);
if (DeallocationStack)
{
ULONG FreeSize = 0;
ZwFreeVirtualMemory(hProcess, &DeallocationStack, &FreeSize, MEM_RELEASE);
}
return ns;
}
//Функция потока
ULONG __stdcall ThreadRoutine(IN PVOID Argument)
{
//Работа потока
return ZwTerminateThread(0xFFFFFFFE,0);
}
//А вот тривиальный пример вызова всего этого безобразия
NTSTATUS NTAPI ExecuteThreadRoutine(IN PVOID Argument OPTIONAL, IN PLARGE_INTEGER Timeout OPTIONAL)
{
PVOID DeallocationStack;
HANDLE hThread;
CLIENT_ID CliID;
NTSTATUS ns = NewThread(&hThread, 0xFFFFFFFF, (PVOID)ThreadRoutine, Argument, &DeallocationStack, &CliID);
if (ns == STATUS_SUCCESS)
{
ZwWaitForSingleObject(hThread, FALSE, Timeout);
KillThread(0xFFFFFFFF, hThread, DeallocationStack);
ZwClose(hThread);
}
return ns;
}