8

スレッドにフックを設定してマクロを記録する Delphi モジュールを準備しています。

FHandleRec  := SetWindowsHookEx(WH_JOURNALRECORD, FRecordProc, HInstance, 0);
FHandlePlay := SetWindowsHookEx(WH_JOURNALPLAYBACK, FPlayProc, HInstance, 0);

これは WinXP では問題なく動作しますが、Vista/Windows 7 では で失敗しERROR_ACCESS_DENIEDます。Google ( this ) で ( that )を参照しているのを見つけました。引用:

権限の低いプロセスは、次のことができません。 … ジャーナル フックを使用して、権限の高いプロセスを監視します。

成功せずに試しました:

  1. アプリケーションを管理者として実行します。おそらくスレッドはメイン スレッドよりも低い権限で開始されます (100% 確実ではありませんが)。
  2. 管理者セキュリティ コンテキストでスレッドを偽装することも役に立ちません。

コードサンプル:

if LogonUser(PWideChar(sAdminUser), PWideChar(sDomain), PWideChar(sPwd),
             LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then 
begin  
  if not ImpersonateLoggedOnUser(hToken) then
    raise Exception.Create('Error impersonating the user');
end;
FHandleRec := SetWindowsHookEx(WH_JOURNALRECORD, FRecordProc, HInstance, 0);

LogonUserImpersonateLoggedOnUserエラーなしで実行します。

試す他の可能性:

  1. UAC を永久にオフにします。これは役に立ちますが、モジュールのユーザーに強制することはできません。
  2. モジュールの顧客はアプリケーションに署名し、信頼できる場所に置きます。試したことはありませんが、ユーザーにとってモジュールの使用が根本的に複雑になります。
  3. モジュールを署名付きアプリケーションに入れ、EXE を配布します。これにより、一部のコア機能が壊れます。

Visa/Windows 7 でフックを設定しているコードを表示するか、有効な解決策を提案していただけますか?

4

1 に答える 1

9

その記事の「ユーザー インターフェイス特権の分離」セクションをもう一度よく読んでください。ユーザー権限ではなく、整合性レベルを参照しています。そのため、別のユーザーになりすましても問題は解決しません。整合性レベルは、プロセスが最初に開始されたときに確立され、コードで動的に変更することはできません。

ユーザー インターフェイス特権の分離 (UIPI) は、完全な管理者として実行されているプロセスを、同じ対話型デスクトップで管理者よりも低いアカウントとして実行されているプロセスから分離するのに役立つメカニズムの 1 つです。UIPI は、ウィンドウとユーザー インターフェイス コントロールをサポートする、USER と呼ばれるウィンドウおよびグラフィック サブシステムに固有のものです。UIPI は、権限の低いアプリケーションが Windows メッセージを使用して、あるプロセスから権限の高いプロセスに入力を送信するのを防ぎます。あるプロセスから別のプロセスに入力を送信すると、ユーザーがキーボードまたはマウスのアクションを提供しなくても、プロセスは別のプロセスに入力を挿入できます。

Windows Vista は、一連のユーザー インターフェイス特権レベルを階層的に定義することによって UIPI を実装します。レベルの性質上、高い特権レベルは、低いレベルで実行されているアプリケーションにウィンドウ メッセージを送信できます。ただし、下位レベルは、上位レベルで実行されているアプリケーション ウィンドウにウィンドウ メッセージを送信できません。

ユーザー インターフェイスの特権レベルはプロセス レベルです。プロセスが初期化されると、ユーザー サブシステムはセキュリティ サブシステムを呼び出して、プロセスのセキュリティ アクセス トークンに割り当てられたデスクトップ整合性レベルを決定します。デスクトップ整合性レベルは、プロセスの作成時にセキュリティ サブシステムによって設定され、変更されません。したがって、ユーザー インターフェイスの特権レベルも、プロセスの作成時にユーザー サブシステムによって設定され、変更されません。

標準ユーザーが実行するすべてのアプリケーションには、同じユーザー インターフェイス特権レベルがあります。UIPI は、同じ特権レベルのアプリケーション間のウィンドウ メッセージングの動作に干渉したり変更したりしません。 UIPI は、管理者グループのメンバーであり、標準ユーザーとしてアプリケーションを実行している可能性があるユーザー (フィルターされたアクセス トークンを使用するプロセスと呼ばれることもあります) に対して有効になります。デスクトップ。UIPI は、以下に示す動作をブロックすることで、権限の低いプロセスが権限の高いプロセスにアクセスするのを防ぎます。

  • ジャーナル フックを使用して、より高い権限のプロセスを監視します。

この記事によると、アプリには と の両方requestedExecutionLevel=requireAdministratorを指定する UAC マニフェストが必要ですuiAccess=True。UIAccess 権限は重要です。

requestedPrivileges 属性で UIAccess=”true” を指定することにより、アプリケーションは UIPI 制限をバイパスする要件を示しています ... UIAccess 権限で起動されるプロセス:

  • ジャーナルフックをセットできます。
于 2012-02-07T02:21:40.900 に答える