Windows SafeSEH机制如何工作?

我了解覆盖SEH利用技术的工作原理。我不太了解SafeSEH机制是如何工作的,导致该技术无法正常工作。这个问题与SafeSEH机制的内部运作有关。

#1 楼

关于您的原始问题:ntdll.dll加载每个PE映像后,将解析PE映像中的异常处理程序地址列表,并将每个地址插入ntdll.dll内部使用的排序列表中。当出现异常时,ntdll.dll!KiUserExceptionDispatcher将尝试找出要在SEH链中使用哪个异常。反过来,将在此列表中扫描每个异常处理程序地址(通过ntdll.dll)。如果找到,则允许异常过滤器运行。如果不是,则ntdll.dll将引发异常并使用0xC00001A5快速使线程失败:检测到无效的异常处理程序例程。在虚拟程序中引发异常,然后逐步执行。您还可以在IDA中扫描ntdll中的0xC00001A5(不应经常发生),当您看到它已被使用时,这就是ntdll决定快速使线程失败的原因(由于代码路径局部性优化,可能很难退后)。

#2 楼

我根据自己的研究发表自己的答案。我不确定粗体字的正确性。欢迎提供纠正我的答案或更完整,更好的答案的评论。在收到确认或反驳我的假设的评论后,我将删除粗体。现在,作为SEH开发的第一步,您需要使用地址_EXCEPTION_REGISTRATION_RECORD指令序列覆盖记录的第二个字段PEXCEPTION_ROUTINE。此时,如果您不尝试在被利用的.exe模块中找到此序列,则使用pop pop ret编译该序列并不重要。

接下来,您转向从易受攻击的可执行文件加载的DLL中选择一个/SAFESEH指令序列地址。在您选择了该地址并改写了pop pop ret字段之后,在例外时,操作系统会使用该地址,确定该地址所属的.dll模块,如果.dll是使用PEXCEPTION_ROUTINE编译的,请检查该.dll的模块安全异常处理程序表包含给定的地址。如果.dll是使用/SAFESEH构建的,并且表中不存在您使用的地址,则执行流不会传递到该地址,并且利用失败。如果.dll是在没有/SAFESEH的情况下构建的,则OS没有任何可检查的内容,因此利用此步骤起作用。