実行中のプロセスのユーザ名を取得

[戻る]
シャノン 2004/07/31(土) 14:07:14
OS は WinXP Pro SP1 です。

実行中の全プロセスについて、実行しているユーザ名を取得したいです。
現在、以下のような手順で行っているのですが…

SE_DEBUG_NAME 特権を取得
Process32First / Next でプロセスを列挙
OpenProcessToken でプロセスのトークンを開く
GetTokenInformation で TOKEN_USER 構造体を取得
LookupAccountSid でユーザ名を取得
(手順は一部省略してあります)

Administrator でログインしていて、Administrator と SYSTEM で実行されている
プロセスについては取得できるのですが、LOCAL_SERVICE や NETWORK_SERVICE で
実行されているプロセス(サービス?)について取得できません。
OpenProcessToken でアクセスを拒否されてしまいます。

タスクマネージャでは表示できているので、何らかの方法はあると思います。
どうすればよいのでしょうか?
どなたかご存知でしたら、ご教示願います。

シャノン 2004/07/31(土) 15:20:33
もうひとつ便乗質問。

特権を取得する際に、TOKEN_PRIVILEGES 構造体を使いますよね。
この Privileges メンバは、要素数 1 の配列として宣言されていますが
複数の特権を取得したいときはどう書けばいいんでしょう?
#なんでポインタにしといてくれなかったんだ…

LUID_AND_ATTRIBUTES luidAndAttrs[ 2 ];
tokenPrivileges.PrivilegeCount = 2;
tokenPrivileges.Privileges[ 0 ] = luidAndAttrs[ 0 ];

ってやっても、最初の(luidAndAttrs[ 0 ])しか有効になりませんでした
(まぁ、当たり前と言えば当たり前なんですが)。

tokenPrivileges.Privileges[ 1 ] = luidAndAttrs[ 1 ];

って書いたら、スタックぶち壊しエラーで落ちちゃいました。

BYTE temp[ sizeof( DWORD ) + sizeof( LUID_AND_ATTRIBUTES ) * 2 ];
TOKEN_PRIVILEGES *pTokenPrivileges = ( TOKEN_PRIVILEGES * )temp;
pTokenPrivileges->PrivilegeCount = 2;
pTokenPrivileges->Privileges[ 0 ] = luidAndAttrs[ 0 ];
pTokenPrivileges->Privileges[ 1 ] = luidAndAttrs[ 1 ];

などという苦しいコードを書かねばならんのでしょうか?

あいる 2004/08/02(月) 11:38:47
もう解決しちゃったかな?
一つ目ので、Code Projectにあった気がするので検索・・・

ヒットしましたw
http://www.codeproject.com/system/RunUser.asp

ドキュメント上は LOCAL_SERVICE や NETWORK_SERVICE も取れてるっぽい事書いてあるので
参考になるかなぁ〜?
(流し読み程度ですが・・・)

二つ目のは・・・PrivilegeCheckの事かな??

だとすれば、PPRIVILEGE_SET 内で LUID_AND_ATTRIBUTES が ANYSIZE_ARRAY 分の配列
になっているので、PrivilegeCount 分までなら参照できるんじゃないかなぁ〜と・・・

MSDNだとこの辺り・・・
http://www.microsoft.com/japan/msdn/library/default.asp?
url=/japan/msdn/library/ja/jpsecupf/html/_win32_PrivilegeCheck.asp

# 関係なかったらごめんねぇ〜(><

あいる 2004/08/02(月) 11:45:05
て、ANYSIZE_ARRAY が 1 なのか・・・
んっと・・・

-----抜粋

PrivilegeCheck 関数は、有効になっている特権だけを調べます。
アクセストークンが保持している有効、および無効の特権すべてのリストを取得するには、
GetTokenInformation 関数使います。

-----

とあるので、GetTokenInformation かな??

http://www.microsoft.com/japan/msdn/library/default.asp?
url=/japan/msdn/library/ja/jpsecupf/html/_win32_gettokeninformation.asp

あいる 2004/08/02(月) 12:12:38
う・・・そもそも関係なかった・・・書き方の問題かぁ〜

んっと、Delphi でのサンプルがあったので眺めていましたら・・・
(http://www.thedelphimagazine.com/Samples/1577/1577.htm)

-----抜粋

    // allocate a buffer large enough to hold two 
    // privileges, note that TPrivilegeSet already has room 
    // for one TLuidAndAttributes so we only have to 
    // allocate one additional one. 
    PrivSet := AllocMem(SizeOf(TPrivilegeSet) + (1 * SizeOf
(TLuidAndAttributes))); 

    // we are specifying two privileges 
    PrivSet.PrivilegeCount := 2; 

    // and we want both of them to be enabled 
    PrivSet.Control := PRIVILEGE_SET_ALL_NECESSARY; 

    // get the LUID for the SE_TCB_NAME privilege 
    Win32Check(LookupPrivilegeValue(nil, SE_TCB_NAME, PPrivilegesArray
(@PrivSet.Privilege)^[0].Luid)); 

    // get the LUID for the SE_LOAD_DRIVER_NAME privilege 
    Win32Check(LookupPrivilegeValue(nil, SE_LOAD_DRIVER_NAME, PPrivilegesArray( 
@PrivSet.Privilege)^[1].Luid)); 

    // perform the check 
    Win32Check(PrivilegeCheck(TokenHandle, PrivSet, Result)); 
-----
と、やっちゃってますねぇ〜・・・

PRIVILEGE_SET の配列にして、1個目の要素の PrivilegeCount と Control をセット・・・
Luid はそれぞれセット・・・てとこかなぁ?

シャノン 2004/08/02(月) 13:48:31
[[解決]]
貴重な手がかりをありがとうございます。
やっぱり CodeProject はすごいっすねぇ…

早速サンプル(TokenMan)を試してみましたが、動作がデバッガで追えない。
何をしているのかと思ったら、システムプロセスをごにょごにょいじってから、
自身を "SYSTEM" アカウントで再起動している模様。なんつートリッキーな。

後でゆっくり解析してみようと思います。
ありがとうございました。

#ちなみに RunAsEx は DDK がないとコンパイルできないみたいです(泣

シャノン 2004/08/02(月) 14:40:43
2つ目の方は…「特権の取得」って言い方が拙かったかな?
トークンがどの特権を持っているか取得するんじゃなくて、
むしろ、トークンに特権を付与する時の話なんです。
AdjustTokenPrivileges っていう関数を使うんですが、そのときに
TOKEN_PRIVILEGES 構造体を使うんですわ。

あいる 2004/08/02(月) 15:29:14
私は、詰まったら即 CodeProject してしまいますw
CodeGuru もたまに行きますが、情報量を考えると圧倒的ですから・・・
# 大概はソースみなくても、その説明文(?)で解決してしまうことが多いので
# その下の BBS に、結構有用な情報があったりするしで、ありがたい情報源です。

2つ目ですが・・・よ〜くコードみると・・・

> BYTE temp[ sizeof( DWORD ) + sizeof( LUID_AND_ATTRIBUTES ) * 2 ];
> TOKEN_PRIVILEGES *pTokenPrivileges = ( TOKEN_PRIVILEGES * )temp;
> pTokenPrivileges->PrivilegeCount = 2;
> pTokenPrivileges->Privileges[ 0 ] = luidAndAttrs[ 0 ];
> pTokenPrivileges->Privileges[ 1 ] = luidAndAttrs[ 1 ];

と、同じ事してましたです・・・(^^;
で、AdjustTokenPrivileges の Delphi サンプルがまたたくさんあったので、覗いてみると
・・・やっぱり同じでした(/_;)

てなわけで、MSDNを検索・・・どうやら、TList というサンプルに何か手がかりがあるらしい
手元にそんなサンプルはなかったので、DL・・・130MBですか・・・(--;
DL も終わり、中身をみると・・・役に立たないし・・・

ん〜・・・ソースがあれば一発なんだけどねぇ・・・
てなわけで、2つ目は力になれそうにありませんm(__

シャノン 2004/08/02(月) 16:23:09
ATL に、特権周りをラップした CTokenPrivileges ってクラスがありました。
内部では TOKEN_PRIVILEGES 構造体を malloc で確保してましたね。
#だからポインタにしてよ、MS さん…

古いスレッドには追加発言できません。