[BlueLeaf1336]> PROBLEMS> 探求其之壱>
| history | TOP |
2006/02/07:作成
| システム系のプロセスの情報取得に失敗する | TOP |
すでに何度か書いていますが、いくつかのプロセスの情報取得に失敗したままです。もちろんタスクマネージャでは表示しているのに、です。たとえばこんなプロセスです。
| イメージ名(Exe名) | その説明 | 備考 |
|---|---|---|
| [System Process] | − | タスクマネージャでは System Idle Process |
| csrss.exe | Client Server Runtime Process | − |
| svchost.exe | Generic Host Process for Win32 Services | 5つのプロセスが動いているうち2つは取得できている |
| sqlservr.exe | SQL Server Windows NT | Visual Studio 2005 Express Edition |
| wdfmgr.exe | Windows User Mode Driver Manager | − |
| alg.exe | Application Layer Gateway Service | − |
基本的には、C:¥Windows¥System32¥ に置いてある Exe がほとんどです。単純にそのプロセスの情報を覗くための権限が足りないんだろうと思われるわけで。
そこまで考えると、以前、Windows をシャットダウンするために権限付与が必要だったことに思い至りました。OpenProcessToken・LookupPrivilegeValue・AdjustTokenPrivileges といった API や、「シャットダウン権限の付与」などで検索してみると、いくらでもヒットします。以下はそのうちの2つです。
ひとつは、まさに権限を付与するための関数を Delphi で書いたもの、もうひとつは、それぞれの権限の意味を日本語で説明してくれているものです。
| まさにその権限付与関数そのもの | TOP |
あまりにそのままでも仕方がないので、コメントを日本語に直してみましたが意味不明でした。Platform SDK を参照して追記すべき情報を拾ったり...してないし。
// Torry's Delphi Pages
// http://www.swissdelphicenter.ch/torry/showcode.php?id=1177
// Windows NT 系のシステムでは、正しい権限を与えないと使えない関数が
// あります。たとえば、ExitWindowsEx を使用したシステムのシャットダ
// ウンや再起動、システム時刻の変更などです。
// 以下のコードは、権限を調整するための関数です。
// AdjustTokenPrivileges() は、指定したアクセストークン(?)で、権限を
// 与えたり取り消したりします。
unit NTPrivilege;
interface
uses
Windows, SysUtils;
// NT Defined Privileges from winnt.h
// winnt.h で定義されている権限
const
SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
SE_SECURITY_NAME = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME = 'SeBackupPrivilege';
SE_RESTORE_NAME = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
SE_DEBUG_NAME = 'SeDebugPrivilege';
SE_AUDIT_NAME = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
SE_UNDOCK_NAME = 'SeUndockPrivilege';
SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
SE_MANAGE_VOLUME_NAME = 'SeManageVolumePrivilege';
//-----------------------------------------------------------------------------
// 権限の付与と取り消し
function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
implementation
//-----------------------------------------------------------------------------
// 権限の付与と取り消し
function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
// Windows NT/2000/XP 以降でないと意味なし
Result := True;
if not (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;
// プロセストークンを取得する
if OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
try
// locally unique identifier (LUID) を取得する
if LookupPrivilegeValue(nil, PChar(sPrivilege),
TokenPriv.Privileges[0].Luid) then
begin
// one privilege to set
TokenPriv.PrivilegeCount := 1;
// 権限を付与するための設定
if (bEnabled) then
begin
TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
end
// 取り消すための設定
else
begin
TokenPriv.Privileges[0].Attributes := 0;
end;
// replaces a var parameter
ReturnLength := 0;
PrevTokenPriv := TokenPriv;
// 権限を適用する
AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
finally
CloseHandle(hToken);
end;
end;
// AdjustTokenPrivileges() の成功判定
Result := GetLastError = ERROR_SUCCESS;
end;
end.
| いろいろと権限を付与してみよう | TOP |
さて、この関数をそのまま使って、定義済みの権限をひとつずつ、起動時に付与、終了時に解除してみました。ところで、付与と解除、とか、付与と取り消し、とか勝手に呼んでますが、合ってるんでしょうか?
その結果を書くにあたって、もうひとつの参考サイトの表をぱくって拡張することにします。
| 権利名 | 意味(感謝) | 結果あるいは発生した例外 |
|---|---|---|
| SE_ASSIGNPRIMARYTOKEN_NAME | プロセスのプライマリ・トークン割り当て | 参照された特権のうち、一部の特権が呼び出し側に割り当てられていません。 |
| SE_AUDIT_NAME | 監査ログ・エントリの作成 | 参照された特権のうち、一部の特権が呼び出し側に割り当てられていません。 |
| SE_BACKUP_NAME | バックアップ操作の実行 | 変化なし |
| SE_CHANGE_NOTIFY_NAME | ファイルやディレクトリの変更通知の受信 | 変化なし |
| SE_CREATE_PAGEFILE_NAME | ページ・ファイルの作成 | 変化なし |
| SE_CREATE_PERMANENT_NAME | 永続的オブジェクトの作成 | 参照された特権のうち、一部の特権が呼び出し側に割り当てられていません。 |
| SE_CREATE_TOKEN_NAME | プライマリ・トークンの作成 | 参照された特権のうち、一部の特権が呼び出し側に割り当てられていません。 |
| SE_DEBUG_NAME | プロセスのデバッグ | これ!! [System Process] 以外のプロセス情報が取得できるようになった |
| SE_INC_BASE_PRIORITY_NAME | プロセスの基本優先順位の上昇 | 変化なし |
| SE_INCREASE_QUOTA_NAME | プロセスに割り当てられているクォータの増加 | 変化なし |
| SE_LOAD_DRIVER_NAME | デバイス・ドライバのロードおよびアンロード | 変化なし |
| SE_LOCK_MEMORY_NAME | メモリの物理ページのロック | 変化なし |
| SE_MACHINE_ACCOUNT_NAME | システム名の変更 | 参照された特権のうち、一部の特権が呼び出し側に割り当てられていません。 |
| SE_PROF_SINGLE_PROCESS_NAME | 単一プロセスのプロファイル情報の収集 | 変化なし |
| SE_REMOTE_SHUTDOWN_NAME | ネットワーク要求によるシャットダウン | 変化なし |
| SE_RESTORE_NAME | バックアップ復元操作の実行 | 変化なし |
| SE_SECURITY_NAME | セキュリティ関連関数の実行 | 変化なし |
| SE_SHUTDOWN_NAME | ローカル・システムのシャットダウン | 変化なし |
| SE_SYSTEM_ENVIRONMENT_NAME | 不揮発性RAM内のシステム設定情報の変更 | 変化なし |
| SE_SYSTEM_PROFILE_NAME | システム全体のプロファイル情報の収集 | 変化なし |
| SE_SYSTEMTIME_NAME | システムの時刻修正 | 変化なし |
| SE_TAKE_OWNERSHIP_NAME | オブジェクトの所有権の取得 | 変化なし |
| SE_TCB_NAME | 信頼コンピュータ・ベースの一部として識別 | 参照された特権のうち、一部の特権が呼び出し側に割り当てられていません。 |
| SE_UNSOLICITED_INPUT_NAME | 端末デバイスからの非要求入力の読み取り | 指定された特権は存在しません。 |
| SE_UNDOCK_NAME | 不明 | 変化なし |
| SE_SYNC_AGENT_NAME | 不明 | 変化なし |
| SE_ENABLE_DELEGATION_NAME | 不明 | 変化なし |
| SE_MANAGE_VOLUME_NAME | 不明 | 変化なし |
「変化なし」というのは、あくまで「今まで取得できていなかったプロセスの情報を取得できるようになったか」という点から見たものです。実際には何らかの変化がおきているはずですが、その変化を利用していないだけです。
そういうわけで、SE_DEBUG_NAME 権限を与えると、見事に取れるようになりました。じゃあ、最後のひとつはどうするんかという問題は残るんですが...
| 進捗状況 | TOP |
20060207TaskMan.zip(8,862Bytes) ソースコードと実行ファイルです。
今までできているべきだったことができるようになっただけです。しかも、基本的に自分では何もせずに。インターネットに感謝。
| EOF | TOP |