我正在尝试关闭属于特定模块名称的线程。到目前为止,我可以在进程中获取线程的起始地址,但不知道如何将其与特定模块名称相匹配。如何才能做到这一点?
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.
答案 0 :(得分:2)
此处描述了一种方式:https://msdn.microsoft.com/en-us/library/windows/desktop/ms684232.aspx
总结:
EnumProcessModules
枚举加载到流程中的模块。 GetModuleInformation
以获取模块的加载地址和线性地址大小。如果您的地址位于该地址范围内,则这是目标模块。 另一种方法是使用工具帮助API枚举流程中的模块,从而找到相同的信息。在致电TH32CS_SNAPMODULE
时,您会使用CreateToolhelp32Snapshot
。