2016-12-28 6 views
2

特定のモジュール名に属するスレッドを閉じようとしています。これまでのところ、プロセス内のスレッドの開始アドレスを取得できますが、特定のモジュール名と一致させる方法はわかりません。これはどうすればできますか?スレッドの開始アドレスとモジュール名を一致させる方法は?

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. 

答えて

2

一つの方法は、ここで説明されています。https://msdn.microsoft.com/en-us/library/windows/desktop/ms684232.aspx

要約:

  1. コールEnumProcessModulesをプロセスにロードされたモジュールを列挙します。
  2. モジュールごとに、GetModuleInformationを呼び出して、モジュールのロードアドレスとリニアアドレスサイズを取得します。アドレスがその範囲のアドレスにある場合、これがターゲットモジュールです。

さらに別の方法として、ツールヘルプAPIを使用してプロセス内のモジュールを列挙し、同じ情報を見つけることができます。 CreateToolhelp32Snapshotを呼び出すときは、TH32CS_SNAPMODULEを使用します。

+0

興味深い。このアプローチについて知らなかった! – user7349982

+0

これは 'Module32First'、' Module32Next'を使った場合とは異なりますか? – user7349982

+0

同じことを達成する2つの方法 –

関連する問題