首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CreateProcessAsUserW错误代码6无效句柄

CreateProcessAsUserW错误代码6无效句柄
EN

Stack Overflow用户
提问于 2021-07-07 12:27:52
回答 1查看 133关注 0票数 1

我正在使用JNA调用Windows。我想作为一个特定的用户启动一个进程(不管是哪个进程)。我使用的两个API调用是:

LogonUserW成功,但CreateProcessAsUserW由于错误6而失败。根据Windows系统错误代码Doc,这相当于"ERROR_INVALID_HANDLE“。

据我所知,我传入的唯一句柄是用户句柄。我不认为这会有什么问题。据LogonUserW医生说,

在大多数情况下,返回的句柄是一个主令牌,您可以在调用CreateProcessAsUser函数时使用它。但是,如果指定LOGON32_LOGON_NETWORK标志,LogonUser将返回一个模拟令牌,除非调用DuplicateTokenEx将其转换为主令牌,否则不能在CreateProcessAsUser中使用该令牌。

但是,我不使用LOGON32_LOGON_NETWORK。

有些struct参数有句柄,但我要么传递NULL,要么它们由API调用而不是由我填充。

这是我的代码的核心:

代码语言:javascript
复制
final PointerByReference userPrimaryToken =
    new PointerByReference();
System.out.printf(
    "ptr.peer = %d\n",
    Pointer.nativeValue(userPrimaryToken.getValue())
);

final boolean logonOk = MyWinBase.INSTANCE.LogonUserW(
    toCString(<my-username>), // hidden
    toCString("ANT"),
    toCString(<my-password>), // hidden
    /* This logon type is intended for batch servers, where
    processes may be executing on behalf of a user without their
    direct intervention. This type is also for higher
    performance servers that process many plaintext
    authentication attempts at a time, such as mail or web
    servers.*/
    WinBase.LOGON32_LOGON_BATCH,
    WinBase.LOGON32_PROVIDER_DEFAULT,
    userPrimaryToken
);
System.out.printf("ok = %b\n", logonOk);
System.out.printf(
    "ptr.peer = %d\n",
    Pointer.nativeValue(userPrimaryToken.getValue())
);

final STARTUPINFOW.ByReference startupInfoW =
    new STARTUPINFOW.ByReference();
startupInfoW.cb = startupInfoW.size();
startupInfoW.lpReserved = Pointer.NULL;
startupInfoW.lpDesktop = Pointer.NULL;
startupInfoW.lpTitle = Pointer.NULL;
startupInfoW.dwFlags
    = startupInfoW.dwX = startupInfoW.dwY
    = startupInfoW.dwXSize = startupInfoW.dwYSize
    = startupInfoW.dwXCountChars = startupInfoW.dwYCountChars
    = startupInfoW.dwFillAttribute
    = startupInfoW.wShowWindow
    = 0;
startupInfoW.cbReserved2  = 0;
startupInfoW.lpReserved2 = Pointer.NULL;
startupInfoW.hStdInput = startupInfoW.hStdOutput
    = startupInfoW.hStdError
    = Pointer.NULL;

final PROCESS_INFORMATION.ByReference processInformation =
    new PROCESS_INFORMATION.ByReference();
processInformation.hProcess = processInformation.hThread
    = Pointer.NULL;
processInformation.dwProcessId = processInformation.dwThreadId
    = 0;

final boolean createProcessOk = MyProcessThreadsApi.INSTANCE
    .CreateProcessAsUserW(
        userPrimaryToken.getPointer(),
        toCString("C:\\Windows\\System32\\cmd.exe"),
        // execute and terminate
        toCString("/c whoami > whoami.txt"),
        Pointer.NULL,
        Pointer.NULL,
        false,
        WinBase.CREATE_UNICODE_ENVIRONMENT,
        new PointerByReference(),
        Pointer.NULL,
        startupInfoW,
        processInformation
    );
System.out.printf("ok = %b\n", createProcessOk);
System.out.printf(
    "dwProcessId = %d\n", processInformation.dwProcessId
);
System.out.printf(
    "last err code = %d\n",
    ErrHandlingApi.INSTANCE.GetLastError()
);

这是我的输出:

代码语言:javascript
复制
ptr.peer = 0
ok = true
ptr.peer = 1040
ok = false
dwProcessId = 0
last err code = 6

有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-07 14:10:29

看看这段代码:

代码语言:javascript
复制
final PointerByReference userPrimaryToken = ...;

在线文档表示指向指针的指针C符号void**

https://java-native-access.github.io/jna/4.2.1/com/sun/jna/ptr/PointerByReference.html

在LogonUser的文档中,它需要一个指向句柄的PHALDLE指针,这与指向指针的指针类似,因为句柄类似于指针(它声明为typedef void *HANDLE;)。

https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonuserw

代码语言:javascript
复制
BOOL LogonUserW(
  ....
  DWORD   dwLogonProvider,
  PHANDLE phToken
);

但在CreateProcessAsUser文档中,指定此函数接受句柄,而不是PHANDLE。

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasuserw

代码语言:javascript
复制
BOOL CreateProcessAsUserW(
  HANDLE                hToken,
  LPCWSTR               lpApplicationName,
  ....
);

因此,我希望您通过而不是getValue而不是getPointer。通过使用getPointer,您可以得到指针本身,这就是,在您的情况下,很可能是指向指针的指针。我不知道JNA,但是期望来自WinAPI的知识

代码语言:javascript
复制
final boolean createProcessOk = MyProcessThreadsApi.INSTANCE
    .CreateProcessAsUserW(
        userPrimaryToken.getValue(),
        ....
    );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68286052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档