2012-04-15 40 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