【问题标题】:Process handles instead of file handles for a process [closed]进程句柄而不是进程的文件句柄[关闭]
【发布时间】:2014-01-18 10:25:03
【问题描述】:

Iain's Code 中查找进程的句柄,它被配置为只获取“文件”句柄,但我还需要“进程”句柄但不能。有人能指出我正确的方向吗. 谢谢

【问题讨论】:

  • 标签矛盾。 [C#] 不能用于编写 [非托管] 代码。请说明你想要哪一个。
  • 我讨厌没用的cmets ^
  • 我讨厌自私的人,他们认为他们的问题应该只对他们自己有帮助。这不是 SO 的哲学。请修复您的标签,并为该网站的可搜索性做出贡献。
  • 我的应用程序是使用非托管代码用 C# 编写的。
  • 使用这样的代码来获取进程句柄是没有意义的。破解文件句柄是被禁止的知识,因为它总是用于随机且无法诊断地损坏文件。或者恶意地,句柄回收攻击是一个未解决的问题。进程没有任何禁忌,.NET Process 类为您提供所需的一切。像 GetProcessById() 和 Handle 属性。

标签: c# winapi unmanaged


【解决方案1】:

只需修改代码,在行后添加更多逻辑

if (GetHandleType(handle, handleEntry.OwnerPid, out handleType) && handleType == SystemHandleType.OB_TYPE_FILE)

如果您想处理 process 类型的句柄,请使用类似:

bool result = GetHandleType(handle, handleEntry.OwnerPid, out handleType);
if (result)
{
    switch (handleType)
    {
        case SystemHandleType.OB_TYPE_FILE:
        {
            // Existing code:
            string devicePath;
            ....
        }           
        break;

        case SystemHandleType.OB_TYPE_PROCESS:
        {
            // Your code here
            ....
        }           
        break;
    }
}

谢谢,还有没有办法从 如果 switch case 是 Process 类型,则处理值?

当然可以。但是您必须深入了解 Win32 API 以及句柄的工作原理。基本上,您想复制在您自己的进程中拥有该句柄的另一个进程的句柄,使用DuplicateHandle(这样您就可以访问它)。然后您需要分配非托管内存,使用良好参数调用NtQueryObject,这样它就会用字节填充您的非托管内存,然后您必须将这些字节编组回包含有关您的(进程)句柄信息的结构。

深入查看您链接的代码,所有内容都写在那里。尤其是GetFileNameFromHandle 函数。

1) 在我们自己的进程中复制句柄

processHandle = NativeMethods.OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId);
if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS))
{
    handle = objectHandle.DangerousGetHandle();
}

2) 分配非托管内存...(稍后您必须销毁它)

ptr = Marshal.AllocHGlobal(length);

3)...然后使用权限参数将其传递给NtQueryObject

NT_STATUS ret = NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);

4) 封送回已知结构。在原始代码中,它是一个简单的字符串。

fileName = Marshal.PtrToStringUni((IntPtr)((int)ptr + 8), (length - 9) / 2);

在您的情况下,正确的结构是 SYSTEM_HANDLE_ENTRY。谷歌为此提供了使用示例。

【讨论】:

  • 谢谢,如果switch case是进程类型,还有没有办法从句柄值中找到进程名称?
  • @Robert 我提供了更多细节。见编辑
猜你喜欢
  • 2012-08-14
  • 1970-01-01
  • 2015-08-25
  • 2014-10-23
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
相关资源
最近更新 更多