如何通过 PID 和线程 ID 找到 Windows 服务?
How to find Windows service by PID and thread ID?
在我的 C# 应用程序中,我有一个 Windows 服务的 PID 和线程 ID。我怎样才能找到它是哪个服务(注意:例如,svchost.exe 的单个实例可以托管多个服务)?直接在 C# 中或调用其他实用程序对我来说都很好。
Process Hacker 可以显示服务名称(进程属性 -> 选项卡线程 -> 列服务)。
到目前为止我已经找到了进程和线程:
var p = Process.GetProcessById(pid);
var t = p.Threads.Cast<ProcessThread>().SingleOrDefault(t => t.Id == threadId);
如何进行?备选方案?
一般来说,你不能。线程和服务之间没有1:1关系。单个线程可以 运行 多个服务,单个服务可以(通常确实)有多个线程。
Process Hacker 可能使用某种启发式方法,例如,跟踪线程的调用堆栈并识别 svchost.exe
是 运行 的 DLL。或者它可能假设该线程与调用 ServiceMain() 的线程相同;可能有一种未记录的方法来识别那个。
我查看了 Process Hacker 的源代码。没有 Harry Johnston 建议的启发式方法。取而代之的是:
1) 使用NtQueryInformationThread
查找线程的基地址。
检查 Get StartAddress of win32 thread from another process 以了解如何从 C# 调用。
2) 通过NtQueryInformationThread
和NtOpenProcess
.
获取进程句柄
3) NtReadVirtualMemory
用于从位置 FIELD_OFFSET(TEB, SubProcessTag)
处打开的进程中的线程内存中读取(不确定如何转换为 C#)。这就是所谓的ServiceTag
.
4) 使用 advapi32.dll
中的 I_QueryTagInformation
从 ServiceTag
中获取服务名称。
所以没有诡计也没有魔法,但让它在 C# 上工作似乎有点工作。
在我的 C# 应用程序中,我有一个 Windows 服务的 PID 和线程 ID。我怎样才能找到它是哪个服务(注意:例如,svchost.exe 的单个实例可以托管多个服务)?直接在 C# 中或调用其他实用程序对我来说都很好。
Process Hacker 可以显示服务名称(进程属性 -> 选项卡线程 -> 列服务)。
到目前为止我已经找到了进程和线程:
var p = Process.GetProcessById(pid);
var t = p.Threads.Cast<ProcessThread>().SingleOrDefault(t => t.Id == threadId);
如何进行?备选方案?
一般来说,你不能。线程和服务之间没有1:1关系。单个线程可以 运行 多个服务,单个服务可以(通常确实)有多个线程。
Process Hacker 可能使用某种启发式方法,例如,跟踪线程的调用堆栈并识别 svchost.exe
是 运行 的 DLL。或者它可能假设该线程与调用 ServiceMain() 的线程相同;可能有一种未记录的方法来识别那个。
我查看了 Process Hacker 的源代码。没有 Harry Johnston 建议的启发式方法。取而代之的是:
1) 使用NtQueryInformationThread
查找线程的基地址。
检查 Get StartAddress of win32 thread from another process 以了解如何从 C# 调用。
2) 通过NtQueryInformationThread
和NtOpenProcess
.
3) NtReadVirtualMemory
用于从位置 FIELD_OFFSET(TEB, SubProcessTag)
处打开的进程中的线程内存中读取(不确定如何转换为 C#)。这就是所谓的ServiceTag
.
4) 使用 advapi32.dll
中的 I_QueryTagInformation
从 ServiceTag
中获取服务名称。
所以没有诡计也没有魔法,但让它在 C# 上工作似乎有点工作。