从Windows8开始,Windows设计了一个新的中断,INT 29H,用来快速的抛出失败。在sdk中,他被声明为 __fastfail:
#define FAST_FAIL_LEGACY_GS_VIOLATION 0 #define FAST_FAIL_VTGUARD_CHECK_FAILURE 1 #define FAST_FAIL_STACK_COOKIE_CHECK_FAILURE 2 #define FAST_FAIL_CORRUPT_LIST_ENTRY 3 #define FAST_FAIL_INCORRECT_STACK 4 #define FAST_FAIL_INVALID_ARG 5 #define FAST_FAIL_GS_COOKIE_INIT 6 #define FAST_FAIL_FATAL_APP_EXIT 7 #define FAST_FAIL_RANGE_CHECK_FAILURE 8 #define FAST_FAIL_UNSAFE_REGISTRY_ACCESS 9 #define FAST_FAIL_GUARD_ICALL_CHECK_FAILURE 10 #define FAST_FAIL_GUARD_WRITE_CHECK_FAILURE 11 #define FAST_FAIL_INVALID_FIBER_SWITCH 12 #define FAST_FAIL_INVALID_SET_OF_CONTEXT 13 #define FAST_FAIL_INVALID_REFERENCE_COUNT 14 #define FAST_FAIL_INVALID_JUMP_BUFFER 18 #define FAST_FAIL_MRDATA_MODIFIED 19 #define FAST_FAIL_CERTIFICATION_FAILURE 20 #define FAST_FAIL_INVALID_EXCEPTION_CHAIN 21 #define FAST_FAIL_CRYPTO_LIBRARY 22 #define FAST_FAIL_INVALID_CALL_IN_DLL_CALLOUT 23 #define FAST_FAIL_INVALID_IMAGE_BASE 24 #define FAST_FAIL_DLOAD_PROTECTION_FAILURE 25 #define FAST_FAIL_UNSAFE_EXTENSION_CALL 26 #define FAST_FAIL_DEPRECATED_SERVICE_INVOKED 27 #define FAST_FAIL_INVALID_BUFFER_ACCESS 28 #define FAST_FAIL_INVALID_BALANCED_TREE 29 #define FAST_FAIL_INVALID_NEXT_THREAD 30 #define FAST_FAIL_GUARD_ICALL_CHECK_SUPPRESSED 31 #define FAST_FAIL_APCS_DISABLED 32 #define FAST_FAIL_INVALID_IDLE_STATE 33 #define FAST_FAIL_MRDATA_PROTECTION_FAILURE 34 #define FAST_FAIL_UNEXPECTED_HEAP_EXCEPTION 35 #define FAST_FAIL_INVALID_FAST_FAIL_CODE 0xFFFFFFFF
#if _MSC_VER >= 1610
DECLSPEC_NORETURN VOID __fastfail( _In_ unsigned int Code );
#pragma intrinsic(__fastfail)
#endif
|
在中断代码执行后,操作系统会根据执行代码的环境来做出不同的处理。
如果__fastfail发生在Ring0中,操作系统会抛出一个KERNEL_SECURITY_CHECK_FAILURE (0x139)的蓝屏。如果__fastfail发生在Ring3,系统会抛出一个第二次机会的不可继续执行的异常,异常代码为0xC0000409,然后走进我们熟悉的Windows Error Reporting(WER)流程。另外,无论__fastfail发生在R0或者R3,如果有调试器正在调试系统或进程,都将得到一次中断到调试器的机会,这让我们能够看清楚具体发生了什么事情。但是正如我上面所说,这个是一个不可继续执行的异常,所以我们不能在调试器里处理了异常后让程序继续向前跑,当然也不能用try和except去捕获异常。
我觉得__fastfail是个非常不错的设计,它让程序可以快速的进入内核异常处理流程,不需要执行额外的用户层的代码,也不需要额外的内存空间,提高了不可恢复的异常处理的性能,更重要的是,简单快速不依赖内存的执行方式也保证了系统的安全。所以在系统的安全检查失败处理中,大量使用了这个方式,减少被攻击的可能性。
最后,如果INT 29H发生在Windows8以下的系统上,内核里会抛出一个常规的UNEXPECTED_KERNEL_MODE_TRAP的蓝屏,而用户层程序会抛出一个ACCESS VIOLATION的异常。