必要に応じて適切な特権にエスカレートすることについて私が見つけたものはすべて、私の現在の方法と一致していますが、問題は存在します。誰かが Windows Vista/Windows 7 の内部の経験を持ち、暗闇しかないところに光を当てることができることを願っています。長くなると思いますが、ご了承ください。
環境
現在のマシン上の他のプロセスのメモリにアクセスする必要があるアプリケーションに取り組んでいます。これには、明らかに管理者権限が必要です。また、必要SeDebugPrivilege
です (いいえ、スペルミスではありませんSetDebugPrivilege
)。これは正しく取得していると思いますが、これ以上の特権が必要ないのか、それが問題の原因なのか疑問に思います。これまでのところ、コードは Windows XP のすべてのバージョン、および私のテスト用の Vista 32 ビット環境と Windows 7 64 ビット環境で正常に動作しています。
プロセス
- プログラムは常に管理者権限で実行されます。これは、この投稿全体で想定できます。
Access Token
現在のプロセスのインクルードSeDebugPrivilege
権をエスカレートしています。EnumProcesses
システム上の現在の PID のリストを作成するために使用する- アクセス権を使用
OpenProcess
してハンドルを開くPROCESS_ALL_ACCESS
ReadProcessMemory
他のプロセスのメモリを読み取るために使用します。
問題:
開発中および個人的なテスト中 (Windows XP 32 & 64、Windows Vista 32、および Windows 7 x64 を含む) はすべて正常に動作しています。ただし、同僚の Windows Vista (32 ビット) と Windows 7 (64 ビット) の両方のマシンへのテスト展開中に、一般的なエラーでOpenProcess
失敗する特権/権利の問題があるようです。Access Denied
これは、制限付きユーザーとして実行している場合 (予想どおり) と、管理者として明示的に実行している場合 (右クリック →管理者として実行、および管理者レベルのコマンド プロンプトから実行した場合) の両方で発生します。
ただし、この問題は、私のテスト環境では再現できませんでした。私は問題を直接目撃したので、問題が存在すると信じています。実際の環境とテスト環境で識別できる唯一の違いは、UAC プロンプトでドメイン管理者アカウントを使用すると実際のエラーが発生するのに対し、私のテスト (エラーなしで動作) ではローカル管理者アカウントを使用することです。 UAC プロンプト。
OpenProcess
使用されている資格情報により、UAC は「管理者として実行」できますが、プロセスは別のプロセスで実行できる正しい権限をまだ取得していないようです。私は、Vista/Windows 7 の内部構造に精通していないため、これが何であるかを知ることができません。誰かが原因を突き止めてくれることを願っています。
キッカー
RunWithDebugEnabled
このエラーを報告した人で、その環境で定期的にこのバグを再現できる人は、自分の権限をエスカレートし、渡された実行可能ファイルを起動するように見える小さなブートストラップ プログラムに沿って名前が付けられた小さなアプリケーションを持っていますエスカレートされた特権)。UAC プロンプトで同じドメイン管理者の資格情報を使用してこのプログラムを実行すると、プログラムは正常に動作し、意図したとおりに正常に呼び出しOpenProcess
て動作することができます。
したがって、これは間違いなく正しい権限を取得する際の問題であり、ドメイン管理者アカウントは正しい権限にアクセスできるはずの管理者アカウントであることがわかっています。(もちろん、このソース コードを入手できれば素晴らしいことですが、それが可能であれば私はここにいません)。
ノート
前述のとおり、失敗したOpenProcess
試行によって報告されるエラーは次のとおりAccess Denied
です。のMSDNドキュメントによるとOpenProcess
:
呼び出し元が SeDebugPrivilege 特権を有効にしている場合、セキュリティ記述子の内容に関係なく、要求されたアクセスが許可されます。
これにより、これらの条件下では、(1) 取得SeDebugPrivileges
または (2) MSDN ドキュメントで言及されていない他の権限の要求のいずれかで問題が発生し、ドメイン管理者アカウントとローカル管理者の間で異なる可能性があると思われます。アカウント
サンプルコード:
void sample()
{
/////////////////////////////////////////////////////////
// Note: Enabling SeDebugPrivilege adapted from sample
// MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
// Enable SeDebugPrivilege
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tokenPriv;
LUID luidDebug;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
{
if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
{
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luidDebug;
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
{
// Always successful, even in the cases which lead to OpenProcess failure
cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
}
else
{
cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
}
}
}
CloseHandle(hToken);
// Enable SeDebugPrivilege
/////////////////////////////////////////////////////////
vector<DWORD> pidList = getPIDs(); // Method that simply enumerates all current process IDs
/////////////////////////////////////////////////////////
// Attempt to open processes
for(int i = 0; i < pidList.size(); ++i)
{
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pidList[i]);
if(hProcess == NULL)
{
// Error is occurring here under the given conditions
cout << "Error opening process PID(" << pidList[i] << "): " << GetLastError() << endl;
}
CloseHandle(hProcess);
}
// Attempt to open processes
/////////////////////////////////////////////////////////
}
ありがとう!
上記の条件下でWindows VistaおよびWindows 7で別のプロセスを正しく開くために欠落している可能性のある許可、特権、権利などについて誰かが洞察を持っている場合(実行可能ファイルが適切に「管理者として実行」されていると仮定) 、それは非常に高く評価されます。
完全に困惑していなければ、私はここにいないでしょうが、グループの経験と知識が再び輝きを放つことを願っています. この長い文章を読んでいただき、ありがとうございます。善意だけでもありがたいです。スタック オーバーフローをすべての人にとって便利なものにしてくれていることに感謝します。