获取线程起始地址 [英] Get thread start address

查看:438
本文介绍了获取线程起始地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个进程查看器,其99%完成,我只需要获取一个进程的线程的起始地址,但我不知道该怎么做。
任何人都可以帮我吗? :/
Thx

解决方案

您可以使用 NtQueryInformationThread 函数传递 ThreadQuerySetWin32StartAddress 的值<一个href =http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/THREAD_INFORMATION_CLASS.html =nofollow noreferrer> THREAD_INFORMATION_CLASS 枚举为参数。



查看此示例应用程序

  {$ APPTYPE CONSOLE} 

{$ R * .res}

使用
TlHelp32,
Windows,
SysUtils;


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

type
NTSTATUS = LONG;
THREADINFOCLASS = DWORD;

函数NtQueryInformationThread(
ThreadHandle:THandle; ThreadInformationClass:THREADINFOCLASS;
ThreadInformation:Pointer; ThreadInformationLength:ULONG; ReturnLength:PULONG):NTSTATUS;标准外部'ntdll.dll';

函数OpenThread(dwDesiredAccess:DWord;
bInheritHandle:Bool;
dwThreadId:DWord):DWord;标准外部kernel32.dll;


函数GetThreadStartAddress(th32ThreadID:DWORD):指针;
var
hThread:THandle;
ThreadStartAddress:指针;
开始
结果:= 0;
hThread:= OpenThread(THREAD_QUERY_INFORMATION,false,th32ThreadID);
if(hThread = 0)then RaiseLastOSError;
尝试
如果NtQueryInformationThread(hThread,ThreadQuerySetWin32StartAddress,@ThreadStartAddress,SizeOf(ThreadStartAddress),nil)= STATUS_SUCCESS然后
结果:= ThreadStartAddress
else
RaiseLastOSError;
finally
CloseHandle(hThread);
结束
结束

函数GetThreadsList(th32ProcessID:DWORD):Boolean;
var
hSnapshot:THandle;
NextThread:Boolean;
TThreadEntry:TThreadEntry32;
begin
hSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); //获取所有线程的快照
结果:=(hSnapshot<> INVALID_HANDLE_VALUE);
如果结果然后
尝试
TThreadEntry.dwSize:= SizeOf(TThreadEntry);
NextThread:= Thread32First(hSnapshot,TThreadEntry); //获取第一个线程
,而NextThread则执行
begin
如果TThreadEntry.th32OwnerProcessID = th32ProcessID,则//检查所有者Pid PID请求
Writeln(Format('Thread Id%.8x Start Address%p',[TThreadEntry.th32ThreadID,GetThreadStartAddress(TThreadEntry.th32ThreadID)]));
NextThread:= Thread32Next(hSnapshot,TThreadEntry); //获取下一个线程
end;
finally
CloseHandle(hSnapshot);
结束
结束

begin
try
GetThreadsList(4028);
除了
在E:Exception do
Writeln(E.ClassName,':',E.Message);
结束
readln;
结束。

注意:要访问某些系统进程,您需要设置 SeDebugPrivilege 您的应用程式中的权限。


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

解决方案

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.

这篇关于获取线程起始地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆