每一个操作都有中断(鼠标,键盘.....)
CPU 内异常
外中断
中断描述符表---~~~
异常在---内核钩子--FSD中
线程环境中保留的EIP是导致异常的指令地址,而不是下一条指令
int3 --(陷阱类的异常)(带整理)
SEH---结构化异常处理(VC++(VS)编译器中 提供的)
__try |
__finally |
__except |
__leave |
会导致局部展开~~~~~~~~(__try 块)
except(函数)可以用函数参数来接收回掉
异常过滤函数
异常处理多个异常的时候------全局展开
ETHREAD 内核成结构体 用户层叫做TEB表
FS:[0]取出链表结构体的首地址,依次处理异常
typedef struct _EXCEPTION_RECORD { 记录异常结构体 DWORD ExceptionCode; //异常代码 DWORD ExceptionFlags; //异常标志 struct _EXCEPTION_RECORD *ExceptionRecord; //相关的异常 PVOID ExceptionAddress; //异常发生的地址 DWORD NumberParameters; //参数数组中的元素个数 ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];//参数数组 } EXCEPTION_RECORD; |
unsigned long _exception_code(void); |
返回值代表异常类型 |
typedef struct _EXCEPTION_POINTERS { PEXCEPTION_RECORD ExceptionRecord; PCONTEXT ContextRecord; } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; |
由异常信息()返回的指针类型 |
向量异常处理
VEH 使用向量函数需要提供一个回掉函数,用一个api 注册一下即可 ,后面不管发生什么异常,都会调用自己的回掉函数(全局链表)
PVOID WINAPI AddVectoredExceptionHandler( _In_ ULONG First, _In_ PVECTORED_EXCEPTION_HANDLER Handler ); 参数1.异常处理函数被调用的顺序 参数2.异常处理回掉函数 --------------------------------------------------------------------------------------------------- 自己需要知道回掉函数的原型 typedef LONG (NTAPI *PVECTORED_EXCEPTION_HANDLER)( struct _EXCEPTION_POINTERS *ExceptionInfo ); 回掉函数返回值的2中情况 #define EXCEPTION_CONTINUE_SEARCH (0) (继续执行) #define EXCEPTION_CONTINUE_EXECUTION (-1) (继续搜索)
|
VCH 向量和上面的一样只有函数名称不同
PVOID WINAPI AddVectoredContinueHandler( _In_ ULONG First, _In_ PVECTORED_EXCEPTION_HANDLER Handler ); 传参调用都一样 |
总结:
1.当异常交由用户处理时,按照以下顺序调用异常处理方式:VEH->SEH->VCH
2.当VEH 表示处理了异常,就不会传递给SEH,但是会传递异常给VCH
3.当VEH没有处理了,就会传递给SEH
4.当SEH的所有异常处理函数没有能够处理异常,会调用默认的SEH处理函数
5.当SEH处理了异常,从except开始执行,就不会在将异常传递给VCH
6.当SHE返回异常产生处执行,在返回之前会调用VCH