OS は WinXP Pro SP1 です。
実行中の全プロセスについて、実行しているユーザ名を取得したいです。
現在、以下のような手順で行っているのですが…
SE_DEBUG_NAME 特権を取得
Process32First / Next でプロセスを列挙
OpenProcessToken でプロセスのトークンを開く
GetTokenInformation で TOKEN_USER 構造体を取得
LookupAccountSid でユーザ名を取得
(手順は一部省略してあります)
Administrator でログインしていて、Administrator と SYSTEM で実行されている
プロセスについては取得できるのですが、LOCAL_SERVICE や NETWORK_SERVICE で
実行されているプロセス(サービス?)について取得できません。
OpenProcessToken でアクセスを拒否されてしまいます。
タスクマネージャでは表示できているので、何らかの方法はあると思います。
どうすればよいのでしょうか?
どなたかご存知でしたら、ご教示願います。
もうひとつ便乗質問。
特権を取得する際に、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 ];
などという苦しいコードを書かねばならんのでしょうか?
もう解決しちゃったかな?
一つ目ので、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
# 関係なかったらごめんねぇ~(><
て、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
う・・・そもそも関係なかった・・・書き方の問題かぁ~
んっと、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 はそれぞれセット・・・てとこかなぁ?
貴重な手がかりをありがとうございます。
やっぱり CodeProject はすごいっすねぇ…
早速サンプル(TokenMan)を試してみましたが、動作がデバッガで追えない。
何をしているのかと思ったら、システムプロセスをごにょごにょいじってから、
自身を SYSTEM アカウントで再起動している模様。なんつートリッキーな。
後でゆっくり解析してみようと思います。
ありがとうございました。
#ちなみに RunAsEx は DDK がないとコンパイルできないみたいです(泣
2つ目の方は…「特権の取得」って言い方が拙かったかな?
トークンがどの特権を持っているか取得するんじゃなくて、
むしろ、トークンに特権を付与する時の話なんです。
AdjustTokenPrivileges っていう関数を使うんですが、そのときに
TOKEN_PRIVILEGES 構造体を使うんですわ。
私は、詰まったら即 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(__
ATL に、特権周りをラップした CTokenPrivileges ってクラスがありました。
内部では TOKEN_PRIVILEGES 構造体を malloc で確保してましたね。
#だからポインタにしてよ、MS さん…