我已经设置了一个简单的C#程序。
我是从kernel32.dll
OpenProcess
,ReadProcessMemory
和WriteProcessMemory
导入的。
我已经在Process
课程中获得了一个外部流程。
如何为特定StartAddress
获取主题#0 的ProcessThread
?
Process process = Process.GetProcessesByName("Calculator")[0];
if (process == null) {
Console.WriteLine("Process not found");
return;
}
foreach (ProcessThread thread in process.Threads) {
Console.WriteLine(thread.StartAddress);
}
上面代码的结果是:
-157479632
-157479632
-157479632
-157479632
0
-157479632
-157479632
-157479632
-157479632
-157479632
-157479632
-157479632
为什么有一些0,其余都是相同的,都是否定的?
答案 0 :(得分:0)
_ETHREAD
)中的存在2个不同的起始地址 - StartAddress
- 这是通过LdrInitializeThunk
遍历DLL后线程开始执行的地址。也存在第二个地址 - Win32StartAddress
。感觉这个地址 - 当我们通过win32函数Create[Remothe]Thread
(或它的shell)创建线程时 - win32 level将公共线程StartAddress
设置为ntdll.RtlThreadThreadStart
(此函数的名称取决于windows版本,在xp上说 - 另一个名字),实际的 lpStartAddress 作为参数传递给Create[Remothe]Thread
。 RtlThreadThreadStart
已经调用了实际的 lpStartAddress 。 lpStartAddress 并存储在Win32StartAddress
中。
因为大多数线程是通过win32 Create[Remothe]Thread
创建的 - 所有线程都具有相同的StartAddress
(对于另一个StartAddress
我们需要直接调用低级别api,如RtlCreateUserThread
。在系统进程中 - StartAddress
是内核中的实际线程起始地址)
使用代码时
foreach (ProcessThread thread in process.Threads) {
Console.WriteLine(thread.StartAddress);
}
你得到StartAddress
- 绝对正常,你在大多数情况下给出相同的地址。在某些情况下,你可以得到0或另一个不正确的值 - 因为在某些版本的窗口StartAddress
与另一个成员联合保存并且可以被覆盖。
获取Win32StartAddress
您必须使用THREAD_QUERY_LIMITED_INFORMATION
或THREAD_QUERY_INFORMATION
打开广告句柄并使用ZwQueryInformationThread
致电ThreadQuerySetWin32StartAddress
PVOID pv;
ZwQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &pv, sizeof(pv), 0);
和约all negative?
因为你错误地打印了线程地址 - 指针。你打印它作为有符号整数。但是你必须用十六进制打印它作为%p
格式的指针