问题描述
我使用 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()
以查看它是否确实有效。