对于某些访问被拒绝的用户,OpenProcess() 失败

问题描述

我使用 text-align JNA 来访问进程在 Java 上的内存。我的代码如下所示:

Windows

我已经没有使用 static WinNT.HANDLE openProcessHandle(int processId) { val processAccessRights = PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_TERMINATE | PROCESS_NAME_NATIVE | PROCESS_SUSPEND_RESUME | PROCESS_QUERY_informatION | PROCESS_QUERY_LIMITED_informatION; val processHandle = Kernel32.INSTANCE.OpenProcess(processAccessRights,false,processId); if (processHandle == null) { val lastError = Native.getLastError(); val formatMessageFromLastErrorCode = Kernel32Util.formatMessageFromLastErrorCode(lastError); val message = "OpenProcess() Failed to open process id " + processId + ": " + formatMessageFromLastErrorCode; throw new IllegalStateException(message); } return processHandle; } due to the problems it causes

根据this的回答,我还需要为我的进程启用调试权限。但是,尽管在 PROCESS_ALL_ACCESS 之前成功调用了此代码(例如所有返回值都表示成功),但仍有一些用户收到错误消息 OpenProcess()。我的应用程序管理员身份运行。为什么它适用于我和大多数没有管理员权限的用户而不是所有用户?究竟是什么导致了这种不一致?我更愿意专门理解和解决这个问题,而不是让所有用户都以管理员身份运行我的软件,因为我的软件通常不需要这些额外的权限。

解决方法

您在 2017 年引用的答案是我撰写的,去年我发现我遗漏了一些关键的东西。我可能应该编辑那个旧的答案来更新它,但我已经忘记了。请参阅 this answer 以获取我将编辑到您引用的上一个代码中的更正代码版本。

AdjustTokenPrivileges() 的 API 有一些问题,因为它会给出成功的错误指示:

如果函数成功,则返回值非零。要确定函数是否调整了所有指定的权限,请调用 GetLastError,它返回 ... ERROR_SUCCESS ... ERROR_NOT_ALL_ASSIGNED 之一。

如果您尝试调整非管理员用户的权限,您实际上无法这样做,并且其他用户将无法OpenProcess() 为其他用户的进程。我认为除了使用必要的管理权限 (SE_DEBUG_PRIVILEGE) 运行您的程序外,没有其他解决方法,该权限必须在某个时候由管理员分配。

您可能仍会收到误导性的成功指示,但需要检查 GetLastError() 以查看它是否确实有效。