PPH_LIST QueryDotNetAppDomainsForPid_V4(
    _In_ BOOLEAN Wow64,
    _In_ HANDLE ProcessHandle,
    _In_ HANDLE ProcessId
    )
{
    HANDLE legacyPrivateBlockHandle = NULL;
    PVOID ipcControlBlockTable = NULL;
    LARGE_INTEGER sectionOffset = { 0 };
    SIZE_T viewSize = 0;
    OBJECT_ATTRIBUTES objectAttributes;
    UNICODE_STRING sectionNameUs;
    PPH_LIST appDomainsList = NULL;

    if (!PhStringRefToUnicodeString(&GeneratePrivateNameV4(ProcessId)->sr, &sectionNameUs))
        goto CleanupExit;

    InitializeObjectAttributes(
        &objectAttributes,
        &sectionNameUs,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
        );

    if (!NT_SUCCESS(NtOpenSection(
        &legacyPrivateBlockHandle,
        SECTION_MAP_READ,
        &objectAttributes
        )))
    {
        goto CleanupExit;
    }

    if (!NT_SUCCESS(NtMapViewOfSection(
        legacyPrivateBlockHandle,
        NtCurrentProcess(),
        &ipcControlBlockTable,
        0,
        viewSize,
        &sectionOffset,
        &viewSize,
        ViewShare,
        0,
        PAGE_READONLY
        )))
    {
        goto CleanupExit;
    }

    if (Wow64)
    {
        LegacyPrivateIPCControlBlock_Wow64* legacyPrivateBlock;
        AppDomainEnumerationIPCBlock_Wow64* appDomainEnumBlock;

        legacyPrivateBlock = (LegacyPrivateIPCControlBlock_Wow64*)ipcControlBlockTable;
        appDomainEnumBlock = &legacyPrivateBlock->AppDomainBlock;

        // Check the IPCControlBlock is initialized.
        if ((legacyPrivateBlock->FullIPCHeader.Header.Flags & IPC_FLAG_INITIALIZED) != IPC_FLAG_INITIALIZED)
        {
            goto CleanupExit;
        }

        // Check the IPCControlBlock version is valid.
        if (legacyPrivateBlock->FullIPCHeader.Header.Version > VER_LEGACYPRIVATE_IPC_BLOCK)
        {
            goto CleanupExit;
        }

        appDomainsList = EnumerateAppDomainIpcBlockWow64(
            ProcessHandle,
            appDomainEnumBlock
            );
    }
    else
    {
        LegacyPrivateIPCControlBlock* legacyPrivateBlock;
        AppDomainEnumerationIPCBlock* appDomainEnumBlock;

        legacyPrivateBlock = (LegacyPrivateIPCControlBlock*)ipcControlBlockTable;
        appDomainEnumBlock = &legacyPrivateBlock->AppDomainBlock;

        // Check the IPCControlBlock is initialized.
        if ((legacyPrivateBlock->FullIPCHeader.Header.Flags & IPC_FLAG_INITIALIZED) != IPC_FLAG_INITIALIZED)
        {
            goto CleanupExit;
        }

        // Check the IPCControlBlock version is valid.
        if (legacyPrivateBlock->FullIPCHeader.Header.Version > VER_LEGACYPRIVATE_IPC_BLOCK)
        {
            goto CleanupExit;
        }

        appDomainsList = EnumerateAppDomainIpcBlock(
            ProcessHandle,
            appDomainEnumBlock
            );
    }

CleanupExit:

    if (ipcControlBlockTable)
    {
        NtUnmapViewOfSection(NtCurrentProcess(), ipcControlBlockTable);
    }

    if (legacyPrivateBlockHandle)
    {
        NtClose(legacyPrivateBlockHandle);
    }

    return appDomainsList;
}
Example #2
0
PPH_LIST QueryDotNetAppDomainsForPid_V2(
    _In_ BOOLEAN Wow64,
    _In_ HANDLE ProcessHandle,
    _In_ HANDLE ProcessId
    )
{
    LARGE_INTEGER sectionOffset = { 0 };
    SIZE_T viewSize = 0;
    OBJECT_ATTRIBUTES objectAttributes;
    UNICODE_STRING sectionNameUs;
    HANDLE legacyPrivateBlockHandle = NULL;
    PVOID ipcControlBlockTable = NULL;
    PPH_LIST appDomainsList = NULL;

    __try
    {
        if (!PhStringRefToUnicodeString(&GeneratePrivateName(ProcessId)->sr, &sectionNameUs))
            __leave;

        InitializeObjectAttributes(
            &objectAttributes,
            &sectionNameUs,
            0,
            NULL,
            NULL
            );

        if (!NT_SUCCESS(NtOpenSection(
            &legacyPrivateBlockHandle,
            SECTION_MAP_READ,
            &objectAttributes
            )))
        {
            __leave;
        }

        if (!NT_SUCCESS(NtMapViewOfSection(
            legacyPrivateBlockHandle,
            NtCurrentProcess(),
            &ipcControlBlockTable,
            0,
            viewSize,
            &sectionOffset,
            &viewSize,
            ViewShare,
            0,
            PAGE_READONLY
            )))
        {
            __leave;
        }

        if (Wow64)
        {
            LegacyPrivateIPCControlBlock_Wow64* legacyPrivateBlock;
            AppDomainEnumerationIPCBlock_Wow64* appDomainEnumBlock;

            legacyPrivateBlock = (LegacyPrivateIPCControlBlock_Wow64*)ipcControlBlockTable;

            // NOTE: .NET 2.0 processes do not have the IPC_FLAG_INITIALIZED flag.

            // Check the IPCControlBlock version is valid.
            if (legacyPrivateBlock->FullIPCHeader.Header.Version > VER_LEGACYPRIVATE_IPC_BLOCK)
            {
                __leave;
            }

            appDomainEnumBlock = GetLegacyBlockTableEntry(
                Wow64,
                ipcControlBlockTable,
                eLegacyPrivateIPC_AppDomain
                );

            appDomainsList = EnumerateAppDomainIpcBlockWow64(
                ProcessHandle,
                appDomainEnumBlock
                );
        }
        else
        {
            LegacyPrivateIPCControlBlock* legacyPrivateBlock;
            AppDomainEnumerationIPCBlock* appDomainEnumBlock;

            legacyPrivateBlock = (LegacyPrivateIPCControlBlock*)ipcControlBlockTable;

            // NOTE: .NET 2.0 processes do not have the IPC_FLAG_INITIALIZED flag.

            // Check the IPCControlBlock version is valid.
            if (legacyPrivateBlock->FullIPCHeader.Header.Version > VER_LEGACYPRIVATE_IPC_BLOCK)
            {
                __leave;
            }

            appDomainEnumBlock = GetLegacyBlockTableEntry(
                Wow64,
                ipcControlBlockTable,
                eLegacyPrivateIPC_AppDomain
                );

            appDomainsList = EnumerateAppDomainIpcBlock(
                ProcessHandle,
                appDomainEnumBlock
                );
        }
    }
    __finally
    {
        if (ipcControlBlockTable)
        {
            NtUnmapViewOfSection(NtCurrentProcess(), ipcControlBlockTable);
        }

        if (legacyPrivateBlockHandle)
        {
            NtClose(legacyPrivateBlockHandle);
        }
    }

    return appDomainsList;
}