【问题标题】:OpenProcess returns error code 6(ERROR_INVALID_HANDLE)OpenProcess 返回错误代码 6(ERROR_INVALID_HANDLE)
【发布时间】:2015-12-08 11:33:08
【问题描述】:

我尝试使用OpenProcess 函数获取正在运行的进程的句柄。但是,在检查错误代码时,我得到一个错误代码 6 (ERROR_INVALID_HANDLE)。

这是一个简化的示例:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Test
{
    class TestClass
    {
        [DllImport("kernel32.dll")]
        static extern uint GetLastError();

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess,
               bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress,
              byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);

        static void Main() 
        {
            var process = Process.GetProcessesByName("Sample")[0];
            var processHandle = OpenProcess(0x001F0FFF, false, process.Id);    
            Console.WriteLine(GetLastError());

            int bytesRead = 0;
            byte[] buffer = BitConverter.GetBytes(1095090201);

            WriteProcessMemory(
                (int)processHandle,
                0x21F3CAAC,
                buffer,
                buffer.Length, 
                ref bytesRead);

            Console.ReadKey();
        }
    }
}
}

我不太确定为什么它不起作用。 它只是返回错误代码 6。有什么建议吗?

不知何故,我觉得这是因为我正在访问的程序,但其他一切都运行良好,没有返回任何其他错误。

【问题讨论】:

  • 6INVALID_HANDLEGetLastError() 仅在OpenProcess() 失败时有效,即processHandle == 0 是这种情况吗? SetLastError = true应该添加到属性中,Sample是什么类型的进程? - 这是你的真实密码吗?就目前而言,它不会编译
  • @AlexK。首先,是的,processHandle 返回 0。示例是一个标准的 .exe 程序。不,这不是我真正的代码,因为我只是从中提取了一部分并试图保持它的小(它最初是一个 Windows 窗体应用程序)
  • 显示不能正确检查错误的假代码并不酷。请把它改正,不要再这样做了。在您这样做之前,我们很难相信这里写的任何内容。魔术常数也非常有用。我们真的要查找他们以找出您指定的访问权限。您的黄金法则是,您应该让我们尽可能轻松地为您提供帮助。我们的想法是您尽可能多地做腿部工作,而我们只做您不能做的部分。
  • @DirkVollmar 提问者说,“这不是我的真实代码”
  • @DirkVollmar 好的,好吧,如果您认为该问题具有明确回答所需的所有内容,并且该问题无法改进,那很好。我不同意。

标签: c# winapi openprocess


【解决方案1】:

您需要改进错误检查。在请求最后一个错误之前,您需要先检查OpenProcess 的返回码是否为空。请注意,DllImport 需要将 SetLastError 设置为 true 才能正常工作,GetLastError should not be used

[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr OpenProcess(int dwDesiredAccess,
       bool bInheritHandle, int dwProcessId);

processHandle = OpenProcess(0x001F0FFF, false, process.Id); 
if (processHandle == IntPtr.Zero)
{
    Console.WriteLine(Marshal.GetLastWin32Error());
}

理想情况下,您应该从本机错误代码创建托管异常。这样做的好处是您可以使用标准的 .NET 异常处理,并且您可以将错误代码和文本描述很好地包装在异常中:

processHandle = OpenProcess(0x001F0FFF, false, process.Id); 
if (processHandle == IntPtr.Zero)
{
    // calls Marhal.GetLastWin32Error and GetErrorMessage under the hood
    throw new Win32Exception();
}

当然,完成后别忘了致电CloseHandle

【讨论】:

  • 它仍在打印 6 并且在第二个示例中它返回的句柄无效,但不是为什么...
  • Unhandled Exception: System.ComponentModel.Win32Exception: The handle is invalid
  • @DirkVollmar 当您抛出该异常时,您期望发生什么。没有什么可以期待的。你能解释为什么ERROR_INVALID_HANDLE 会被返回吗?毕竟,这就是问题所在。
  • 对该答案的第一条评论与该假设相矛盾。这就是假代码的问题。我们看不到询问者正在运行的代码。也许它已经正确处理了错误,OpenProcess 确实在提供ERROR_INVALID_HANDLE。或者也许提问者的代码仍然错误处理错误。这就是问题的问题所在。我们最终试图推理一些我们看不到的东西。我们需要向询问者展示他们正在运行的代码,以及正确的错误处理,然后我们才能继续前进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
相关资源
最近更新 更多