c# - C#获取外部进程的线程起始地址

标签 c# windows memory-address

我已经设置了一个简单的 C# 程序。 我从 kernel32.dll 导入了 OpenProcess , ReadProcessMemoryWriteProcessMemory .

我已将一个外部进程获取到 Process 中类。

我怎样才能得到 StartAddress对于 Thread #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,其余的都是一样的,都是负数?

最佳答案

在线程对象(结构 _ETHREAD )中存在 2 个不同的起始地址 - StartAddress - 这是线程在通过 LdrInitializeThunk 遍历 DLL 后开始执行的地址.也存在第二个地址 - Win32StartAddress .这个地址的意义——当我们通过 win32 函数创建线程时 Create[Remothe]Thread (或 it shell)- win32 级别设置公共(public)线程 StartAddressntdll.RtlThreadThreadStart (此函数的名称取决于 Windows 版本,比如 xp - 另一个名称)并且实际的 lpStartAddress 被传递给 Create[Remothe]Thread作为参数。 RtlThreadThreadStart已经调用了实际的 lpStartAddresslpStartAddress 并存储在 Win32StartAddress 中.

因为大多数线程都是通过 win32 创建的 Create[Remothe]Thread - 他们都有相同的StartAddress (对于另一个 StartAddress,我们需要直接调用低级 API,如 RtlCreateUserThread。也在 System 进程中 - StartAddress 是内核中的实际线程起始地址)

当你使用代码时

foreach (ProcessThread thread in process.Threads) {
    Console.WriteLine(thread.StartAddress);
}

你得到了 StartAddress - 在大多数情况下,您提供相同的地址是绝对正常的。在某些情况下,您可能会得到 0 或其他不正确的值 - 因为在某些版本的窗口中 StartAddress与另一个成员联合保存,可以被覆盖。

获取Win32StartAddress您必须使用 THREAD_QUERY_LIMITED_INFORMATION 打开线程句柄或 THREAD_QUERY_INFORMATION并调用ZwQueryInformationThreadThreadQuerySetWin32StartAddress

    PVOID pv;
    ZwQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &pv, sizeof(pv), 0);

关于all negative?

因为你错误地打印了线程地址 - 指针。您将其打印为有符号整数。但你必须用 %p 以十六进制打印它作为指针格式

关于c# - C#获取外部进程的线程起始地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46145300/

相关文章:

c++ - 如何使用 C++ 和 Windows API 将击键/消息发送到 Windows 7?

java - 为什么我的cmd程序总是自动暂停?

c++ - 将字符串转换为指针

c++将值设置为特定地址

c# - 将参数传递给同一应用程序的另一个实例

c# - ASP.NET 核心 "CreatedAtRoute"失败

c# - 把方法放在哪里。存储库上的服务层 ( BL )?

c# - 将 lambda 表达式作为方法参数传递

windows - 适用于 Windows 的 Web 开发文本/代码编辑器

c - 如何初始化和操作地址指针