用户层异常的处理 - VEH异常
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html
用户层异常的处理 - VEH异常
1.初始VEH异常
1)VEH异常链表是一个全局链表,其模板如下:
LONG NTAPI VehFunc(struct _EXCEPTION_POINTERS* ExceptionInfo) {
return EXCEPTION_CONTINUE_SEARCH;
}
int main(int argc, char* argv[])
{
// 1-veh链头部,0-veh链尾部。
AddVectoredExceptionHandler(1,VehFunc);
return 0;
}
其中 _EXCEPTION_POINTER结构体如下:
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord; // 异常记录
PCONTEXT ContextRecord; // 异常发生时的各个寄存器的值
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
2)VEH异常的返回值
#define EXCEPTION_EXECUTE_HANDLER 1 // 异常被识别,_except模块中处理该异常
#define EXCEPTION_CONTINUE_SEARCH 0 // 异常未被识别,继续调用下一个Handler来处理异常
#define EXCEPTION_CONTINUE_EXECUTION (-1) // 异常已被忽略或修复,不继续往下寻找
注意:SEH异常与VEH异常返回值是不同的,对于SEH异常,其返回的是一个 enum EXCEPTION_DISPOSITION。
3)我们根据ContextRecord中保存的寄存器我们就可以实现对我们的代码出现异常的修复,下面是除零异常代码的修复:
LONG NTAPI VehFunc(struct _EXCEPTION_POINTERS* ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xc0000094) {
ExceptionInfo->ContextRecord->Eip += 2;
printf("除零异常已被处理了!\n");
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
int main(int argc, char* argv[])
{
// 1-veh链头部,0-veh链尾部。
AddVectoredExceptionHandler(1,VehFunc);
_asm {
mov ebx, 0;
mov eax, 1;
idiv ebx;
}
return 0;
}
2. Ntdll!RtlAddVectoredExceptionHandler函数分析
该函数分析如下,值得注意的是其中的Handler都是被加密的,因此这意味着你不能手动向Veh中加入链表然后期待着被调用触发。
可以看出其调用AllocateHeap,说明存储在堆中,作为一个进程是全局共享的。
3. Ntdll!RtlCallVectoredExceptionHandlers函数分析
该函数就是遍历VEH链表找到函数来进行分析,其函数结构时相当清晰地,VEH的handler被加密了,此时会执行加密。
整体的处理流程下面已经分析地相当透彻了,这里就不在做过多的解释了。
原文地址:https://www.cnblogs.com/onetrainee/p/12773858.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据库应用技术系列第一讲 创建数据库和表
- 怎样让数据库再快一点?
- 大数据场景下,如何快速将Linux 大文件处理小
- Mysql系列第十六讲 变量详解
- Mysql系列第十七讲 流程控制语句(高手进阶)
- 私藏的5个好用的Pandas函数!
- 漫画:如何在数组中找到和为 “特定值” 的两个数?
- 当你在百度搜索关键字的时候,哪个网站会排在最前面?今天给大家科普一下“网站SEO”
- Mysql系列第十九讲 异常捕获及处理详解
- 【原创】经验分享:一个小小emoji尽然牵扯出来这么多东西?
- jQuery 事件对象,拷贝对象,多库共存
- jQuery 事件注册与事件处理
- v-charts 修改文本颜色
- 使用 jsDelivr 免费加速 GitHub Pages 博客的静态资源(二)
- 竞赛比完,代码、模型怎么处理?Kaggle大神:别删,这都是宝藏