2012-04-15 57 views
2

我正在寫一個進程查看器,它的99%完成,我只需要獲取進程的線程的起始地址,但我不知道它是如何做到的。 任何人都可以幫助我嗎? :/ Thx獲取線程起始地址

回答

7

您可以使用NtQueryInformationThread函數傳遞THREAD_INFORMATION_CLASS枚舉的ThreadQuerySetWin32StartAddress值作爲參數。

檢查這個示例應用程序

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    TlHelp32, 
    Windows, 
    SysUtils; 


const 
    THREAD_QUERY_INFORMATION = $0040; 
    STATUS_SUCCESS    = $00000000; 
    ThreadQuerySetWin32StartAddress = 9; 

type 
    NTSTATUS = LONG; 
    THREADINFOCLASS = DWORD; 

function NtQueryInformationThread(
    ThreadHandle: THandle; ThreadInformationClass: THREADINFOCLASS; 
    ThreadInformation: Pointer; ThreadInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll'; 

function OpenThread(dwDesiredAccess: DWord; 
        bInheritHandle: Bool; 
        dwThreadId: DWord): DWord; stdcall; external 'kernel32.dll'; 


function GetThreadStartAddress(th32ThreadID : DWORD) : Pointer; 
var 
    hThread : THandle; 
    ThreadStartAddress : Pointer; 
begin 
    Result:=0; 
    hThread := OpenThread(THREAD_QUERY_INFORMATION , false, th32ThreadID); 
    if (hThread = 0) then RaiseLastOSError; 
    try 
    if NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, @ThreadStartAddress, SizeOf(ThreadStartAddress), nil) = STATUS_SUCCESS then 
     Result:=ThreadStartAddress 
    else 
    RaiseLastOSError; 
    finally 
     CloseHandle(hThread); 
    end; 
end; 

function GetThreadsList(th32ProcessID:DWORD): Boolean; 
var 
    hSnapshot  : THandle; 
    NextThread : Boolean; 
    TThreadEntry : TThreadEntry32; 
begin 
    hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); //Takes a snapshot of the all threads 
    Result := (hSnapshot <> INVALID_HANDLE_VALUE); 
    if Result then 
    try 
     TThreadEntry.dwSize := SizeOf(TThreadEntry); 
     NextThread := Thread32First(hSnapshot, TThreadEntry);//get the first Thread 
     while NextThread do 
     begin 
     if TThreadEntry.th32OwnerProcessID = th32ProcessID then //Check the owner Pid against the PID requested 
      Writeln(Format('Thread Id %.8x Start Address %p',[TThreadEntry.th32ThreadID, GetThreadStartAddress(TThreadEntry.th32ThreadID)])); 
     NextThread := Thread32Next(hSnapshot, TThreadEntry);//get the Next Thread 
     end; 
    finally 
     CloseHandle(hSnapshot); 
    end; 
end; 

begin 
    try 
    GetThreadsList(4028); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    readln; 
end. 

注:以訪問您將需要設置一些系統進程SeDebugPrivilege在您的應用程序的權限。

+0

嗨RRUZ,我得到這個錯誤:'調用操作系統函數失敗' – paulohr 2012-04-15 14:01:49

+0

您是否修改了示例代碼?您使用的是什麼版本的delphi? – RRUZ 2012-04-15 15:25:18

+0

嗨RRUz,我試圖只使用GetThreadStartAddress函數,因爲我已經有了GetThreadList函數 – paulohr 2012-04-15 15:34:41