可能是Windows Restart Manager回调API中存在错误吗?

时间:2014-05-25 23:07:53

标签: c++ windows winapi calling-convention restartmanager

当我正在调查我只能在Windows 8上重现的奇怪崩溃时,我发现EBX寄存器未从RmShutdownRmRestart的调用中恢复。我在Windows 8上运行时发现的第一个区别是它使用ECX,而这些函数的win7版本使用(从而恢复)EBX。 (我没有仔细研究过其他Windows版本,只是注意到这个bug并没有在Vista上重现。)

当我进一步挖掘时,我注意到对RM_WRITE_STATUS_CALLBACK的调用并没有通过弹出其中的参数来恢复堆栈,因为调用者似乎没有做到这一点。它要么。因此,当RstrtMgr!CRestartManager::ShutdownApplications调用RstrtMgr!_EH_epilog3时,会从堆栈中弹出错误的寄存器值。但至少,ESP已正确恢复,RmShutdown的结尾正确重置了所使用的寄存器,包括EBP,它在调用{{1}之间不会使用和...结束......

所以在Windows 7上,一切都很好......但是Windows 8版本,使用CRestartManager::ShutdownApplications代替ECXEBX未恢复,如果调用代码依赖在它... BOOM !!!

要解决此问题,我只是将回调函数更改为使用EBX(这意味着我无法使用真正的__stdcall类型,并且需要将其类型转换为API所期望的内容,或使用RM_WRITE_STATUS_CALLBACK技术,无论如何都需要在XP上运行相同的代码。)

我是否遗漏了某些内容,或者这确实是API的问题? GetProcAddressEDI怎么样?即使在Windows 7上,它们也无法正常恢复。在我的情况下,它们没有被使用,所以没关系,但我不能相信这些函数的调用者都不需要这些寄存器才能正常恢复......对吗?

我想我会向微软提交一个错误信息......除非有人能提出更好的解释......

0 个答案:

没有答案