我经常使用的第三方库篡改了几个Windows API函数,最烦人的是SetUnhandledExceptionFilter
。不出所料,这让我自己的处理程序完全过时了(如果你不知道的话,试着找出原因!)。
我想解决这个愚蠢问题。显而易见的方法是用xor eax,eax ret 4
覆盖5字节的hotpatch序言(在我自己调用函数之后),有效地进行任何进一步的调用no-op。
这有两个问题:
SetUnhandledExceptionFilter
位于kernel32.dll
,永远不会卸载。这意味着在意外的非异常程序终止的情况下(即用户在TaskManager中杀死进程),补丁将一直持续到机器重新启动。这是一个非常讨厌的功能。是否有可靠的方法来做这样的事情,而不是同时破坏/损害整个系统的正常功能?
我考虑过在应用补丁之前将保护设置为PAGE_WRITECOPY
而不是PAGE_WRITE
(PAGE_EXECUTE_WRITECOPY
也很诱人,因为它之后不应该要求重置保护PAGE_EXECUTE_READ
,但MSDN表示仅在Vista SP1之后才支持此功能,并且需要维护XP功能。)
根据我的理解,这应该限制我对流程所做的任何更改的可见性。
这是一个有效的假设,并且这样的事情是否会起作用,也符合我可能没有想到的其他特征(例如DEP,或某些特殊的特权或其他干扰)?
答案 0 :(得分:3)
第三方库中只有replace that IAT entry指向SetUnhandledExceptionFilter
,这更简单,并且只在第三方库本地。
更好的是,如果第三方库是您使用应用分发的dll /二进制文件,则只需NOP
对SetUnhandledExceptionFilter
进行的调用,这将更容易,更安全。
我考虑过将保护设置为PAGE_WRITECOPY而不是 应用补丁之前的PAGE_WRITE(PAGE_EXECUTE_WRITECOPY是 也很诱人,因为它不应该需要重置保护 之后是PAGE_EXECUTE_READ,但是MSDN说这只是支持 在Vista SP1之后,需要维护XP功能。)
实际上,PAGE_EXECUTE_READWRITE
是您最好的选择,但恢复原始权限通常是一个好主意,除非您需要检查您或其他人是否已经篡改了内存。