どの IL で動作しているのか確かめる

前回に引き続き、IL ネタです。
動作しているプロセスが、どの IL で動作しているのか確かめてみたいと思います。
これは、そんなに難しいことではなく、GetTokenInformation() を使うことで簡単に取得できます。
ただし、Vista (or 2008)対応の SDK が必要ですので、注意してください。

BOOL GetTokenInformation(
    HANDLE TokenHandle,  // アクセストークンのハンドル
    TOKEN_INFORMATION_CLASS TokenInformationClass,  // 取得したい情報のタイプ
    LPVOID TokenInformation,  // 取得したい情報のアドレス
    DWORD TokenInformationLength,  // 情報バッファのサイズ
    PDWORD ReturnLength  // 必要なバッファサイズを保持するアドレス
);

ここの第二引数 TokenInformationClass に TokenIntegrityLevel を指定します。
実はこれだけです。
TOKEN_INFORMATION_CLASS::TokenIntegrityLevel は、Vista (or 2008)対応の SDK にある WinNT.h に定義があるのです。

プロセスハンドルを渡すと、IL を取得するヘルパー関数を作成してみました。
なお、取得できる IL は、WinNT.h に定義がある以下のものです。

// WinNT.h より
/*
#define SECURITY_MANDATORY_UNTRUSTED_RID            (0x00000000L)
#define SECURITY_MANDATORY_LOW_RID                  (0x00001000L)
#define SECURITY_MANDATORY_MEDIUM_RID               (0x00002000L)
#define SECURITY_MANDATORY_HIGH_RID                 (0x00003000L)
#define SECURITY_MANDATORY_SYSTEM_RID               (0x00004000L)
#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID    (0x00005000L)
*/

DWORD GetILInfomation(HANDLE hProcess, DWORD *pdwILLevel)
{
    DWORD dwErr = ERROR_SUCCESS;
    PTOKEN_MANDATORY_LABEL pTIL = NULL;
    HANDLE hToken;

    __try
    {
        BOOL b = OpenProcessToken(hProcess, TOKEN_QUERY_SOURCE | TOKEN_QUERY, &hToken);
        if (!b)
        {
            dwErr = GetLastError();
            __leave;
        }

        DWORD dwLengthNeeded;
        // 整合性レベルの取得
        b = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS::TokenIntegrityLevel, NULL, 0, &dwLengthNeeded);
        if (!b)
        {
            dwErr = GetLastError();
            if (dwErr == ERROR_INSUFFICIENT_BUFFER)
            {
                pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwLengthNeeded);
                if (pTIL == NULL)
                {
                    b = FALSE;
                    dwErr = ERROR_NOT_ENOUGH_MEMORY;
                    __leave;
                }

                b = GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwLengthNeeded, &dwLengthNeeded);
                if (!b)
                {
                    dwErr = GetLastError();
                    __leave;
                }
            }
            else
            {
                __leave;
            }
        }

        if (pTIL)
        {
            SID* sid = static_cast<SID*>(pTIL->Label.Sid);
            // ここで RID を取得する
            DWORD rid = sid->SubAuthority[0];

            *pdwILLevel = rid;
        }
        else
        {
            // ここには来ないはずだけど…
        }
    }
    __finally
    {
        CloseHandle(hToken);
        if (pTIL)
        {
            LocalFree(pTIL);
            pTIL = NULL;
        }
    }

    return dwErr;
}

まあ、自前で IL を確認する用途があるかは微妙ですが…。
ちなみに、Sysinternals の Process Monitor や Process Explorer を使っても IL を確認することができます。

では、今回はこの辺で。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。