I am trying to close a thread that belongs to a particular module name. So far I can get the start address of a thread in a process but don't know how to match it to a specific module name. How can this be done?
program Project1;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
Winapi.Windows,
TlHelp32;
type
HANDLE = NativeUInt;
type
_THREADINFOCLASS = DWORD;
THREADINFOCLASS = _THREADINFOCLASS;
type
NTSTATUS = LONGWORD;
const
ThreadQuerySetWin32StartAddress = 9;
THREAD_QUERY_INFORMATION = $0040;
STATUS_SUCCESS = $00000000;
function OpenThread(
dwDesiredAccess: DWORD;
bInheritHandle: BOOL;
dwThreadId: DWORD
): DWORD; WINAPI; external 'Kernel32.dll' name 'OpenThread';
function GetShellWindow: HWND; WINAPI; external 'User32.dll' name 'GetShellWindow';
function NtQueryInformationThread(
ThreadHandle: HANDLE;
ThreadInformationClass: THREADINFOCLASS;
ThreadInformation: PVOID;
ThreadInformationLength: ULONG;
ReturnLength: PULONG
): NTSTATUS; WINAPI; external 'Ntdll.dll' name 'NtQueryInformationThread';
function GetThreadStartAddress(ThreadID: DWORD): Pointer;
var
hThread: HANDLE;
begin
Result := 0;
hThread := OpenThread(THREAD_QUERY_INFORMATION, False, ThreadID);
if hThread > 0 then
NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, @Result, SizeOf(Result), nil);
CloseHandle(hThread);
end;
var
PId: Cardinal;
hSnapshot: HANDLE;
ThreadEntry: THREADENTRY32;
ThreadStartAddr: Pointer;
begin
GetWindowThreadProcessId(GetShellWindow, PId);
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, PId);
ThreadEntry.dwSize := sizeof(THREADENTRY32);
ThreadEntry.cntUsage := 0;
Thread32First(hSnapshot, ThreadEntry);
repeat
if ThreadEntry.th32OwnerProcessID = PId then
begin
ThreadStartAddr := GetThreadStartAddress(ThreadEntry.th32ThreadID);
// Match ThreadStartAddr to module name (kernel32.dll etc)?
end;
until not Thread32Next(hSnapshot, ThreadEntry);
Readln;
end.
One way is described here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684232.aspx
In summary:
EnumProcessModules
to enumerate the modules loaded into the process.GetModuleInformation
to obtain the load address and linear address size of the module. If your address lies in that range of addresses then this is the target module.Yet another way would be to use the tool help API to enumerate the modules in the process and so find the same information. You would use
TH32CS_SNAPMODULE
when callingCreateToolhelp32Snapshot
.