3

Windows 8 でしか再現できない奇妙なクラッシュを調査していたところ、またはEBXの呼び出しからレジスタが復元されていないことがわかりました。Windows 8 での実行で最初に見つけた違いは、これらの関数の win7 バージョンが使用 (したがって復元) している間に使用していることです。(私は他の Windows バージョンを詳細に調査していませんが、Vista ではバグが再現されないことに気付きました。)RmShutdownRmRestartECXEBX

RM_WRITE_STATUS_CALLBACKさらに掘り下げてみると、 への呼び出しはスタックから引数をポップすることによってスタックを復元しないことに気付きました。RstrtMgr!CRestartManager::ShutdownApplicationsそのため、呼び出し時RstrtMgr!_EH_epilog3に間違ったレジスタ値がスタックからポップされます。しかし、少なくともESPは適切に復元され、最後には、呼び出しと終了の間で使用されないRmShutdownを含む、使用したレジスタが適切にリセットされます...EBPCRestartManager::ShutdownApplications

したがって、Windows 7では、すべて問題ありませんでした...しかし、Windows 8バージョンは、のECX代わりに使用されているため、復元されず、呼び出しコードがそれに依存している場合... BOOM !!!EBXEBX

これを修正するために、使用するコールバック関数を単純に変更しました__stdcall(これは、実際のRM_WRITE_STATUS_CALLBACK型を使用できず、API が期待するものに型キャストするか、GetProcAddressXP で同じコードを実行するために必要な手法を使用する必要があることを意味します)。とりあえず)。

何か足りないのでしょうか、それとも本当に API の問題なのでしょうか? EDIとはどうESIですか?Windows 7 でも適切に復元されません。

これについてマイクロソフトにバグを報告すると思います...誰かがより良い説明を思いつかない限り...

4

0 に答える 0