如何在Windows上的Java上启动交互过程?

问题描述 投票:0回答:1

我需要在Windows上以另一个用户桌面上的管理员权限运行应用程序。

我以提升权限的管理员身份运行代码。

我发现了这篇文章(它描述了如何在.net上进行操作:]

https://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-32-and-64-bit-Archite

我将文章中的代码翻译为Java,但advapi32.CreateProcessAsUser返回false。有人看到我在这段代码中遗漏的内容吗?

pom依赖性

<dependencies>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.2.0</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

我的代码

import com.sun.jna.platform.win32.*;

public class Test {
    public static void main(String[] args) {
        // id of the process which we you as a pointer to the target desktop where we will open new application from current user
        int procId = 26100;

        String applicationName = "C:\\Windows\\System32\\cmd.exe";

        Kernel32 kernel32 = Kernel32.INSTANCE;

        int securityLevel = WinNT.READ_CONTROL;
        final int PROCESS_VM_READ=0x0010;
        final int PROCESS_QUERY_INFORMATION=0x0400;
        WinNT.HANDLE hProcess = kernel32.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, procId);
        System.out.println(hProcess);

        Advapi32 advapi32 = Advapi32.INSTANCE;

        // obtain a handle to the access token of the winlogon process
        WinNT.HANDLEByReference hPToken = new WinNT.HANDLEByReference();
        if (!advapi32.OpenProcessToken(hProcess, WinNT.TOKEN_DUPLICATE, hPToken)) {
            kernel32.CloseHandle(hProcess);
            throw new RuntimeException("1");
        }
        System.out.println(hPToken);

        // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
        // I would prefer to not have to use a security attribute variable and to just
        // simply pass null and inherit (by default) the security attributes
        // of the existing token. However, in C# structures are value types and therefore
        // cannot be assigned the null value.
        WinBase.SECURITY_ATTRIBUTES sa = new WinBase.SECURITY_ATTRIBUTES();
        sa.dwLength = new WinDef.DWORD(sa.size());

        WinNT.HANDLEByReference hUserTokenDup = new WinNT.HANDLEByReference();

        // copy the access token of the winlogon process;
        // the newly created token will be a primary token
        if (!advapi32.DuplicateTokenEx(hPToken.getValue(), securityLevel, sa,
                (int) WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                (int) WinNT.TOKEN_TYPE.TokenPrimary, hUserTokenDup)) {
            kernel32.CloseHandle(hProcess);
            kernel32.CloseHandle(hPToken.getValue());
            throw new RuntimeException("2");
        }
        System.out.println(hUserTokenDup);

        WinBase.STARTUPINFO si = new WinBase.STARTUPINFO();
        si.cb = new WinDef.DWORD(si.size());

        // interactive window station parameter; basically this indicates
        // that the process created can display a GUI on the desktop
        si.lpDesktop = "winsta0\\default";

        final int NORMAL_PRIORITY_CLASS = 0x0020;
        final int CREATE_NEW_CONSOLE    = 0x0010;

        // flags that specify the priority and creation method of the process
        int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;

        WinBase.PROCESS_INFORMATION procInfo = new WinBase.PROCESS_INFORMATION();

        // create a new process in the current User's logon session
        boolean result = advapi32.CreateProcessAsUser(
                hUserTokenDup.getValue(),  // client's access token
                null,             // file to execute
                applicationName,  // command line
                sa,           // pointer to process SECURITY_ATTRIBUTES
                sa,           // pointer to thread SECURITY_ATTRIBUTES
                false,            // handles are not inheritable
                dwCreationFlags,  // creation flags
                null,      // pointer to new environment block
                null,             // name of current directory
                si,           // pointer to STARTUPINFO structure
                procInfo      // receives information about new process
        );
        System.out.println(procInfo);
        System.out.println("result: " + result);
    }
}
java windows winapi jna
1个回答
0
投票

重复的令牌没有足够的权限。您仅指定READ_CONTROL的权限。

根据DuplicateTokenEx.dwDesiredAccess

要请求与现有令牌相同的访问权限,请指定零。

因此您需要将DuplicateTokenEx.dwDesiredAccess设置为零。

© www.soinside.com 2019 - 2024. All rights reserved.