2013-03-15 9 views
5

私のC#コードは、P /呼び出しを経由して偽装されたコードからの例外が検出されないのはなぜですか?

internal class Win32Native 
{ 
    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern int ImpersonateLoggedOnUser(IntPtr token); 

    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern int RevertToSelf(); 
} 

try { 
    var token = obtainTokenFromLogonUser(); 
    Win32Native.ImpersonateLoggedOnUser(token); 
    throw new Exception(); // this is for simulation 
    Win32Native.RevertToSelf() 
} catch(Exception e) { 
    LogException(e); 
    throw; 
} 

をWin32関数を呼び出すことで偽装を使用しても、私はAppDomain.CurrentDomain.UnhandledExceptionハンドラはまた、すべての未処理の例外をログに記録することをインストールされています。

例外をログに記録するコードは、なりすましの有無にかかわらず正常に動作することが確信しています。

ここで問題は、上記のコードではcatchが入力されておらず、UnhandledExceptionも呼び出されていないということです。例外の唯一のトレースは、イベントビューアのエントリです。

私はこのようなfinallyを追加する場合:

try { 
    var token = obtainTokenFromLogonUser(); 
    Win32Native.ImpersonateLoggedOnUser(token); 
    try { 
     throw new Exception(); // this is for simulation 
    } finally { 
     Win32Native.RevertToSelf() 
    } 
} catch(Exception e) { 
    LogException(e); 
    throw; 
} 

は例外がcatchからとUnhandledExceptionハンドラの両方から大丈夫記録されます。

何が起こっているかスレッドが偽装されると、通常の例外処理が妨げられますか?

+0

「LogException」にブレークポイントを設定すると、そこに着きますか? –

+0

@MarcGravell:わかりませんが、これが再現されるデバッガはありません。 'LogException()'自体に何らかの問題があるかもしれませんが、これまでのところ依存しているコードは偽装されていても偽装されていなくても正常に動作しています。 – sharptooth

+0

ここで推測する:.NETは実行コンテキストを追跡しているので、例外処理では、コンテキストが変更されたことを認識し、復帰が最初に実行されない限り例外ハンドラが実行されないようにします。そうしないと、コードが偽装されたユーザーで実行された場合、特権が昇格されます... –

答えて

3

LogExceptionのコードは表示されませんが、わかりませんが、偽装された/ログオンしているユーザーのコンテキストで何をしているのか、そのユーザーにはユーザーがいない可能性がありますあなたが何をしているのかを実行する権利ファイルへの書き込みなど、その時点でコードがクラッシュすることがあります。あなたのコードが "Revertted to Self"の後にしか動かないという事実は、これを実証しているようです。

私はそれを言うつもりですが、あなたの例外はキャッチによって実際に捕まえられている可能性がありますが、間違ったユーザーのコンテキストで作業しようとしているためLogExceptionが失敗しています。

これをテストするには、LogException内で、ロギングを試みる前に現在のコンテキストを強制的に "Self"にして、最初のスニペットが動作するかどうかを確認してください。

1

この問題は、コードをロギングしていたことが分かりました。ある時点で、現在のプロセス開始時刻(Process.StartTime)を取得するコードを追加し、偽装されたスレッドから呼び出されたときにそのコードはAccess deniedになります。

Access is denied 
System.ComponentModel.Win32Exception 
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited) 
at System.Diagnostics.Process.GetProcessTimes() 
at System.Diagnostics.Process.get_StartTime() 
//our logging code here 

ロギングコードもProcess.StartTimeでコードを呼び出す前System.Diagnostics.Trace.WriteLine()と呼ばれ、「トレースリスナー」成功を通じて書き込み、後者のみのコードが失敗して書き込みます。

したがって、偽装の有無にかかわらず例外をキャッチするのに違いはありません。例外フィルタをインストールして、権限昇格の可能性がある偽装コードのセキュリティコンテキストで呼び出されるようにすることも可能です。 Details for the latter here

関連する問題