异常处理真的是个好复杂的东西,网上有不少牛文,大家参考,这里只说其中的一点,关于SHE不工作的问题及如何解决的一点思路。
上面的代码稳蓝。
疑惑了N久,WINDBG了下,发现了一个叫做RtlIsValidHandler的函数,顾名思义是一个判断异常处理过程是否合法的函数。原型应该是
BOOLEAN RtlIsValidHandler(PVOID Handler);
如果返回0那么这个异常处理过程就不会被调用,就是我们看到的失效状况。查了下这个函数据说是xp sp2 跟 2003 sp1 才出现的一个新的安全检测函数。防止数据运行,溢出攻击等等。在2000下尝试被加载的驱动,果然工作良好。
于是最简单的解决方法诞生了,想办法找到RtlIsValidHandler的地址,hook了直接返回1就OK。这样相当于屏蔽了系统的安全检测机制,商业产品的话被同行说成给病毒木马开后门就不好了。还是着手分析下RtlIsValidHandler的流程构造一个符合规则的异常处理函数是正道。
还好RtlIsValidHandler不大,开始就是对一个叫做RtlLookupFunctionTable函数的调用,这次不是太容易顾名思义了。单从返回参数来看也很诡异。RtlLookupFunctionTable也非常不大^_^,而且提示明显,有一个对_PsLoadedModuleList的遍历动作,有点安全方面经验的朋友基本可以很快推测个八九不离十。这个函数的原型跟伪代码如下:
大致如此,随后RtlIsValidHandler对返回值做了相关检测没有仔细分析。已知的如下。
补充:PsLoadedModuleList是一个内核变量,指向一个加载模块的链表,具体结构是
实际发现InMemoryOrderLinks InInitializationOrderLinks这两个链表貌似在做一些跟它的名称很不相符的工作。其内容经常为0或者未知内容,总之不像一个双向链表。从前面的比较也可以看出不应该是链表,自己太笨不能理解。希望有明白的牛人可以指教。
SEH用起来简单,理解起来相当复杂,Ring3跟Ring0的检测貌似不完全相同。总之有一天你发现异常捕获也异常了^_^,就考虑下新加入的这个RtlIsValidHandler。