2

CreateProcess()withを使用してプロセスを作成し、リモート プロセス内に小さなコード パッチを作成して DLL をロードし、関数(CREATE_SUSPENDEDその DLL によってエクスポートされた) を呼び出します。コードで。VirtualAllocEx()..., MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITEWriteProcessMemory()FlushInstructionCache()

その後、CreateRemoteThread()呼び出してそのコードを呼び出し、hRemoteThread. リモート コードが意図したとおりに動作することを確認しました。注:LoadLibrary()このコードは単純に戻ります。と以外の API は呼び出しませんGetProcAddress()。その後、エクスポートされたスタブ関数を呼び出します。この関数は、現在は単純に値を返し、スレッドの終了ステータスとして渡されます。

PROCESS_INFORMATION::hThreadここで、奇妙な観察が行われます。 がまだ中断されていることを思い出してください。の終了コードを単に無視hRemoteThreadし、それが終了するのを待たない場合、すべてが「正常」になります。呼び出したルーチンがCreateRemoteThread()戻っPROCESS_INFORMATION::hThreadて再開され、(リモート) プログラムが実際に実行されます。

ただし、次のことを呼び出すWaitForSingleObject(hRemoteThread, INFINITE)か実行すると(同じ効果があります):

DWORD exitCode = STILL_ACTIVE;
while(STILL_ACTIVE == exitCode)
{
    Sleep(500);
    if(!GetExitCodeThread(hRemoteThread, &exitCode))
        break;
}

これが続くと、再開される前CloseHandle()に終了し、プロセスは単に「消えます」。プロセスを停止させずに何とか終了させれば十分です。hRemoteThreadPROCESS_INFORMATION::hThreadhRemoteThreadPROCESS_INFORMATION::hThread

これは、競合状態のように疑わしく見えます。コードをそのままにしても、特定の状況下でhRemoteThreadはまだ高速であり、プロセスが「消える」可能性が高いからです。

これは、プロセス内で最初に実行されるスレッドが自動的にプライマリ スレッドになり、そのプライマリ スレッドには特別なルールがあることを意味するのでしょうか?

特定のスレッドが終了したときではなく、最後のスレッドが終了したときにプロセスが終了するという印象を常に受け​​ていました。

また、注意してください:単純に戻り、戻るのを待っている間はまだ中断されているExitProcess()ため、ここに関与する呼び出しはありません。hRemoteThreadPROCESS_INFORMATION::hThreadhRemoteThread

これは、Windows XP SP3、32 ビットで発生します。

編集: Sysinternals Process Monitor を試して何が起こっているのかを確認したところ、以前からの観察結果を確認できました。挿入されたコードはクラッシュなどしません。代わりに、コードが挿入されたプログラムを閉じる前に、スレッドを待機しないとスレッドが終了しないことがわかります。への電話をCloseHandle(hRemoteThread)延期するか何か考えています...

編集 + 1:ではありませんCloseHandle()。テストのためだけにそれを省略した場合、スレッドが終了するのを待っているときの動作は変わりません。

4

2 に答える 2

1

最初に実行するスレッドは特別なものではありません。

たとえば、中断されたスレッドを作成し、(ExitThread を呼び出して) 元のスレッドを終了するコンソール アプリを作成します。このプロセスは決して終了しません (とにかく Windows 7 では)。

または、新しいスレッドを 5 秒間待機させてから終了します。予想どおり、プロセスは 5 秒間存続し、セカンダリ スレッドが終了すると終了します。

あなたの例で何が起こっているのかわかりません。競合を回避する最も簡単な方法は、新しいスレッドが元のスレッドを再開するようにすることです。

今推測すると、とにかくあなたがしていることは問題を引き起こす可能性が低いのではないかと思います. たとえばDllMain、暗黙的に読み込まれた DLL のすべての呼び出しはどうなるでしょうか? 間違ったスレッドで予期せず発生していませんか?スキップされていますか?それとも、コードが実行されてメイン スレッドが開始されるまで延期されていますか?

于 2012-03-14T03:56:57.023 に答える
0

main(または同等の) 関数を使用するスレッドがExitProcess(明示的に、またはそのランタイム ライブラリで) 呼び出す可能性は十分にあります。ExitProcess、まあ、すべてのスレッドを強制終了することを含め、プロセス全体を終了します。メイン スレッドは挿入されたコードを認識しないため、終了するまで待機しません。

あなたのスレッドが完了するまでメインスレッドを待機させる良い方法があるかどうかはわかりません...

于 2012-03-14T03:20:35.897 に答える