2016-06-27 5 views
0

特定のイメージ名を検出するようにPLOAD_IMAGE_NOTIFY_ROUTINEを設定しています。一致するものがあれば、終了します。私はKERNEL_APC_PENDING_DURING_EXIT BSODを取得しています。 BSOは、ObOpenObjectByPointerでカーネルハンドルを開き、そのハンドルでZwTerminateProcessを呼び出すだけで、私のKillProcess関数のどこかで起きています。KERNEL_APC_PENDING_DURING_EXIT BSOD

何が間違っている可能性がありますか?コードはルーチン外で正常に動作します。投稿する必要がありますか? KillProcessを呼び出すと、PLOD_IMAGE_NOTIFY_ROUTINEにBSODが表示されます。ここで

は私のKillProcess機能である:

NTSTATUS KillProcess(HANDLE ProcessId) 
{ 
PEPROCESS Process; 
HANDLE newProcessHandle = NULL; 
NTSTATUS status = PsLookupProcessByProcessId(ProcessId, &Process); 

do 
{ 
    if (!NT_SUCCESS(status)) 
    { 
#ifdef DEBUGPRINT 
     DbgPrint("Process with id %d does not exist\n", ProcessId); 
#endif 
     break; 
    } 

    if (NT_SUCCESS(status = ObOpenObjectByPointer(
     Process, 
     OBJ_KERNEL_HANDLE, 
     NULL, 
     PROCESS_TERMINATE, 
     *PsProcessType, 
     KernelMode, 
     &newProcessHandle 
    ))) 
    { 
     if (newProcessHandle != NULL) 
     { 
      status = ZwTerminateProcess(newProcessHandle, 0); 

      ZwClose(newProcessHandle); 
     } 
     else 
     { 
      ObDereferenceObject(Process); 
      break; 
     } 

     if (NT_SUCCESS(status)) 
     { 
#ifdef DEBUGPRINT 
      DbgPrint("Successfully killed process with id %d\n", ProcessId); 
#endif 
     } 
     else 
     { 
#ifdef DEBUGPRINT 
      DbgPrint("Failed to kill process with id %d\n", ProcessId); 
#endif 
     } 
    } 
    else 
    { 
#ifdef DEBUGPRINT 
     DbgPrint("Failed to open process with id %d\n", ProcessId); 
#endif 
    } 

    ObDereferenceObject(Process); 

} while (FALSE); 

return status; 
} 
+1

を終了さを変更したかどうかを確認、システムスレッドでは、グローバル変数

  • を設定し、PID
  • を保持するグローバル変数を作成します。エラーを特定するのは難しいでしょう。しかし、ルーチン内のすべてのロック、クリティカルセクションなどを解放していることを確認してください。 – Rohan

  • +0

    さて、あなたが正しいと私はそれを投稿しました。 – user1304765

    答えて

    0

    問題は、BSODにつながる独自のコンテキストでプロセスを終了しようとしていたことです。 ソリューション:

    1. は、グローバル変数が
    2. ないプロセスに
    +0

    シナリオにもよりますが、潜在的な競合状態があります。終了を必要とする2つのプロセスが同時に起動した場合、そのうちの1つのみを取得する可能性があります。単一の変数の代わりにキューを使用してこれを修正できます。できるだけ早く実行されるようにシステムスレッドの優先順位を上げるべきですが、マルチコアシステムでは、新しいプロセスが殺される前に実行されないことは絶対に保証されませんが(おそらく)。 –

    1

    documentation for PsSetLoadImageNotifyRoutineは言う:

    新しく作成されたプロセスのための主要な実行可能イメージがロードされると、負荷-画像がコンテキストでルーチンの実行を通知します新しいプロセスの

    (またDLLがロードされたとき、呼び出しがDLLをロードするプロセスのコンテキストで作られている可能性が高いようです。)

    だからの音から、あなたは、そのプロセスを終了していますあなたが実行しているコンテキストです。さらに、画像ロード操作のコールバック中に、特に脆弱な点でやっています。これがトラブルを引き起こすのは驚くべきことではない。

    documentation for ZwTerminateProcessは、ドライバそれは資源がカーネルスタックから解放されていることを保証することを提供し、現在のプロセスを終了することができますが、私はそれがこのような状況で適用されるとは思わないことを意味します。 (また、どうしたらいいか分かりません)

    代わりに、プロセスを中断し、システムスレッドから後で終了させることができます。

    +0

    代わりに、私はExitProcess()を呼び出すDLLを注入しようとします。 – user1304765

    +0

    これも機能するかもしれません。それが懸念されている場合、実行可能ファイルが実行を開始する前に終了するかどうかはわかりません。 –

    +0

    私はAPCをキューに入れ、その方法で注入することを考えていましたが、32ビットシステムでのみ動作し、ZwSuspendProcessはどこにも書かれていないことに気がつきました。通常は使用するのが良い方法ではありません。異なる注入方法。私はおそらく新しい質問を投稿するでしょう。 – user1304765

    関連する問題