繁体   English   中英

任何人都有使用 GetAppContainerNamedObjectPath 的经验?

[英]Anyone has experience on using GetAppContainerNamedObjectPath?

最近我遇到了一个名为GetAppContainerNamedObjectPath的 Windows API。 但我不知道如何使用它。

我找到了这个 api 的 msdn 页面( https://docs.microsoft.com/en-us/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath )。 但是没有正确的例子和备注,参数写的不好。

最后我收到ERROR_INVALID_PARAMETER(87)错误,这告诉我我输入的参数有问题。 这是我尝试过的。

#define TokenIsAppContainer 29
#define TokenAppContainerSid 31
#define TokenAppContainerNumber 32

typedef struct _TOKEN_APPCONTAINER_INFORMATION {
    PSID TokenAppContainer;
} TOKEN_APPCONTAINER_INFORMATION, *PTOKEN_APPCONTAINER_INFORMATION;

void GetAppContainerProcessInfo(CString & procName)
{
    DWORD dwSize = 0;
    DWORD dwResult;
    HANDLE hToken;
    PTOKEN_APPCONTAINER_INFORMATION pAppCoInfo; 
    WCHAR wcsDebug[1024] = {0,};
    WCHAR * pwSID = NULL;

    typedef BOOL (WINAPI *_LPGETAPPCONTAINERNAMEOBJECTPATH)(HANDLE, PSID, ULONG, LPWSTR, PULONG);

    static _LPGETAPPCONTAINERNAMEOBJECTPATH lpGetAppContainerNamedObjectPath = NULL;

    if (0 == lpGetAppContainerNamedObjectPath)
    {
        HMODULE hKernel32 = LoadLibraryExW(L"kernel32.dll", NULL, 0);
        if (hKernel32)
        {
            lpGetAppContainerNamedObjectPath = reinterpret_cast<_LPGETAPPCONTAINERNAMEOBJECTPATH>(GetProcAddress(hKernel32, "GetAppContainerNamedObjectPath"));
        }
    }

    if (lpGetAppContainerNamedObjectPath)
    {
        DWORD processId = (DWORD)_ttoi((LPCTSTR)procName);
        //HANDLE hProcess = GetProcessHandleByProcessName(procName);
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);

        if(!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
        {
            dwResult = GetLastError();
            swprintf_s( wcsDebug, _countof(wcsDebug), L"OpenProcessToken Error(%u) PID(%d)\n", dwResult, processId );
            AfxMessageBox(wcsDebug);
            return;
        }

        if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) TokenAppContainerSid, NULL, dwSize, &dwSize))
        {
            dwResult = GetLastError();
            if( dwResult != ERROR_INSUFFICIENT_BUFFER ) 
            {
                swprintf_s( wcsDebug, _countof(wcsDebug), L"GetTokenInformation Error %u\n", dwResult );
                AfxMessageBox(wcsDebug);
                return;
            }
        }

        pAppCoInfo = (PTOKEN_APPCONTAINER_INFORMATION) GlobalAlloc( GPTR, dwSize );

        if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) TokenAppContainerSid, pAppCoInfo, dwSize, &dwSize))
        {
            dwResult = GetLastError();
            swprintf_s( wcsDebug, _countof(wcsDebug), L"GetTokenInformation Error %u\n", dwResult );
            AfxMessageBox(wcsDebug);
            return;
        }

        WCHAR wcsNamedObjectPath[MAX_PATH];
        ULONG ulRetlen = 0;

        BOOL bRet = lpGetAppContainerNamedObjectPath(hToken, pAppCoInfo->TokenAppContainer, _countof(wcsNamedObjectPath), wcsNamedObjectPath, &ulRetlen );
        if (bRet)
        {
            swprintf_s( wcsDebug, _countof(wcsDebug), L"GetAppContainerNamedObjectPath Path(%s)\n", wcsNamedObjectPath );
            AfxMessageBox(wcsDebug);
        }
        else
        {
            dwResult = GetLastError();
            swprintf_s( wcsDebug, _countof(wcsDebug), L"GetAppContainerNamedObjectPath Error %u\n", dwResult );
            AfxMessageBox(wcsDebug);
        }

        if (pwSID)
            LocalFree(pwSID);

        CloseHandle(hToken)
        CloseHandle(hProcess);
    }
}

作为旁注,我尝试使用wchar_t *并通过两次调用GetAppContainerNamedObjectPath动态分配内存缓冲区。 但是还是没有机会。 返回长度不返回有意义的值。

如果你调用RtlGetLastNtStatus(); 而是GetLastError(); GetAppContainerNamedObjectPath之后你会得到

STATUS_INVALID_PARAMETER_MIX -指定了无效的参数组合。

这给你更多的信息比较简单的无效参数。

然后寻找函数签名

BOOL
WINAPI
GetAppContainerNamedObjectPath(
    _In_opt_ HANDLE Token,
    _In_opt_ PSID AppContainerSid,
    _In_ ULONG ObjectPathLength,
    _Out_writes_opt_(ObjectPathLength) LPWSTR ObjectPath,
    _Out_ PULONG ReturnLength
    );

令牌AppContainerSid宣布与In_opt -这意味着,这个参数是可选的,你可以在它的一个地方传递0。 然后问你自己 - 你为TokenAppContainerSid查询什么令牌? 如果您将此令牌传递给 api,系统是否无法为您执行此操作? 明显可以。 所以你不需要自己做。 实际上,您需要将Token传递给 api,在这种情况下AppContainerSid必须为 0。或者您可以将AppContainerSid传递给 api,在这种情况下, Token必须为 0。当AppContainerSidToken都不为零时 - 您得到了STATUS_INVALID_PARAMETER_MIX

也作为旁注 - 如果您需要获取令牌,则不需要使用PROCESS_ALL_ACCESS打开进程。 PROCESS_QUERY_LIMITED_INFORMATION就足够了


真的api不会做大魔法。 它返回给你

AppContainerNamedObjects\\<Sid>

路径,其中应用程序容器 sid 的字符串形式。(有些像S-1-15-2-...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM