Trao đổi với tôi

http://www.buidao.com

4/17/10

[Programming] How to create and kill threads in NT Native Mode applications.

От: vasketsovhttp://ntprog.by.ru
Дата: 08.01.03 11:47
Оценка:33 (3) -1
Как обычно, 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;
}
Васкецов Сергей






reflink: http://rsdn.ru/forum/src/167206.1.aspx