Get thread start address

后端 未结 1 440
灰色年华
灰色年华 2021-01-22 18:53

I\'m writing a process viewer, its 99% complete, I just need get the start address of a process\' thread, but I don\'t know how do it. Can anyone help-me? :/ Thx

相关标签:
1条回答
  • You can use the NtQueryInformationThread function passing the ThreadQuerySetWin32StartAddress value of the THREAD_INFORMATION_CLASS enumeration as parameter.

    check this sample app

    {$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.
    

    Note : to get access to some system process you will need set SeDebugPrivilege privilege in your app.

    0 讨论(0)
提交回复
热议问题