1

我正在使用Java JNA以访问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;
}

PROCESS_ALL_ACCESS 由于它引起的问题,我已经不使用了。

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

4

1 回答 1

1

我撰写了您在 2017 年引用的答案,并在去年了解到我错过了一些关键。我可能应该编辑那个较旧的答案来更新它,但我已经忘记了。请参阅此答案以获取我将编辑到您引用的上一个代码的更正版本的代码。

的 APIAdjustTokenPrivileges()有点破损,因为它会给出错误的成功指示:

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

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

很可能你仍然得到一个误导性的成功迹象,但需要检查GetLastError()它是否真的有效。

于 2021-01-16T23:18:57.223 回答