VEH全局链表:与线程无关

全局链表结构(每个是个EXCEOTION_REGISTRATION_RECORD)
构造除零异常

__asm
{xor edx,edxxor ecx,ecxmov eax.0x10idiv ecx //edx:eax 除以 ecx
}

用一个函数将异常处理函数挂入VEH,异常处理函数如下

LONG NTAPI VecExcepHandler( PEXCEPTION_POINTERS pExcepInfo )
{::MessageBoxA(NULL,"VEH异常处理函数执行了","VEH异常",MB_OK);//异常过滤if( pExcepInfo->ExceptionRecord->ExceptionCode == 0xC0000094){  //异常处理pExcepInfo->ContextRecord->Eip = pExcepInfo->ContextRecord->Eip+2;//pExcepInfo->ContextRecord->Ecx = 1;return 已处理}return 未处理
}

SEH局部链表:在堆栈中

windows原始结构

typedef struct _EXCEOTION_REGISTRATION_RECORD{struct _EXCEPTION_REGISTRATION_RECORD *Next;PEXCEPTION_ROUTINE Handler;
}EXCEOTION_REGISTRATION_RECORD;

编译器拓展结构,扩展了3个成员是因为一个函数里无论有多少try catch都只挂一个record

struct _EXCEOTION_REGISTRATION_RECORD{struct _EXCEPTION_REGISTRATION *prev;void (*handler)(PEXCEPTION_RECORD,PEXCEPTION_REGISTRATION,PCONTEXT,PEXCEPTION_RECORD);struct scopetable_entry *scopetable;int reylevel;int _ebp;
};

自己实现将异常处理函数挂入SEH

DWORD temp;
MyException myException;//自己定义的EXCEOTION_REGISTRATION_RECORD
//将原FS:[0]存入temp
//将FS:[0]指向新的EXCEOTION_REGISTRATION_RECORD
//挂入链表
__asm{mov eax,FS:[0]mov temp,eaxlea ecx,myExceptionmov FS:[0],ecx
}
myException.prev = (MyException*)temp;
myException.handle = (DWORD)&MyException_handler;//创造异常
__asm
{xor edx,edxxor ecx,ecxmov eax.0x10idiv ecx //edx:eax 除以 ecx
}//摘除异常
__asm{mov eax,tempmov FS:[0],eax
}

编译器实现将异常处理函数挂入SEH
过滤表达式有 常量 (1,0)/ 表达式(exceptioncode=0x…) / 函数(GetExceptionInfo()里有context等)
过滤表达式为函数,可能在函数里涉及加密,异常处理程序也会涉及

try                  //挂入链表(对应上面的代码)
{}
except(过滤表达式)   //异常过滤
{异常处理程序     //异常处理
}

多个try & scopetable,trylevel分析

Example

try{
}
except(){
}
try{try{}except(){}
}
except(){
}

●每个使用try的函数,不论其内部嵌套或反复使用多少个try,都只将一个EXCEOTION_REGISTRATION_RECORD挂入当前线程的SEH(对于递归函数,每一次调用都会创建一个EXCEOTION_REGISTRATION_RECORD并挂入),以下是初始化了扩展的record

push ebp //ebp
mov ebp,esp //提升堆栈
push 0xFF //-1,trylevel
push scopetable地址
push 异常处理函数地址
mov eax,FS:[0]
push eax  //prev
mov fs:[0] ,esp //指向新结构体,即挂入链表

●对于scopetable,有几个try就有几个成员

struct scopetable_entry
{DWORD previousTryLevel //上一个try{}结构编号PDWRD lpfnFilter      //过滤函数的起始地址,except()PDWRD lpgnHandler        //异常处理程序的地址,except里的
}
scopetable[0].previousTryLevel = -1 //因为前面没try
scopetable[0].lpfnFilter = 过滤函数1 //异常过滤
scopetable[0].lpgnHandler = 异常处理函数1 //异常处理
scopetable[1].previousTryLevel = -1
scopetable[1].lpfnFilter = 过滤函数2
scopetable[1].lpgnHandler = 异常处理函数2
scopetable[2].previousTryLevel = 1 //嵌套try
scopetable[2].lpfnFilter = 过滤函数3
scopetable[2].lpgnHandler = 异常处理函数3
如果嵌套里面再嵌套一个level就是2

Example

try{try{}except(){}
}
except(){
}
try{try{}except(){}
}
except(){
}

●trylevel用于标识当前代码执行在哪个try里,是随时变化的,进入try就改变值

例子的变化过程如下:
-1(try 外),0(第一个try),1(第2个),0(恢复,在第一个try),-1(退出了第一个try)
2(第三个),3(第四个),2,-1(-1就是不在任何try里)

如果是自己throw的知识KiDispatchException前不一样except_handler3在SEH里

try {
可能出错的代码
}
finally{
一定要执行的代码
}
finally用在try里没发生异常且提前退出,finally的PDWRD lpfnFilter为空,局部展开(一个函数的名称)调用finally
若出现异常,一层一层的往外找except处理,然后finally,全局展开这个函数走的

内核学习——VEH / SEH相关推荐

  1. 内核学习-系统调用上

    双机调试配置参看我的另一篇文章[原创]内核学习-双机调试环境搭建-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com,基于xp sp3系统 系统调用的学习 分析ReadProcessM ...

  2. Linux内核学习四库全书

    关于内核学习我建议不要上来就读内核而是先了解内核的构成和特性,然后通过思考发现疑问这时再去读内核源码.即先了解概貌在读局部细节.而且内核分成好多部分,不要只是按照顺序去读,应该针对某一部分比如内存管理 ...

  3. Linux内核学习--内存管理模块

    Linux内核学习--内存管理模块 首先,Linux内核主要由五个部分组成,他们分别是:进程调度模块.内存管理模块.文件系统模块.进程间通信模块和网络接口模块. 本部分所讲的内存是内存管理模块,其主要 ...

  4. linux内核学习之三:linux中的32位与64位

    linux内核学习之三:linux中的"32位"与"64位" 在通用PC领域,不论是windows还是linux界,我们都会经常听到"32位" ...

  5. Linux疑难杂症解决方案100篇(十五)-万字长文带你深入Linux 内核学习:环境搭建和内核编译

    一.linux内核学习之一:环境搭建--安装Debian7.3 本系列文章假设读者已对linux有一定的了解,其实学习linux内核不需要有很深的关于linux的知识,只需要了解以下内容:linux基 ...

  6. Windows x64内核学习笔记(五)—— KPTI(未完待续)

    Windows x64内核学习笔记(五)-- KPTI(未完待续) KPTI 实验一:构造IDT后门并读取Cr3 参考资料 KPTI 描述:KPTI(Kernel page-table isolati ...

  7. Windows x64内核学习笔记(四)—— 9-9-9-9-12分页

    Windows x64内核学习笔记(四)-- 9-9-9-9-12分页 前言 9-9-9-9-12分页 实验一:线性地址转物理地址 页表基址 定位基址 PTE to PXE 实验二:通过页表基址定位各 ...

  8. Windows x64内核学习笔记(三)—— SMEP SMAP

    Windows x64内核学习笔记(三)-- SMEP & SMAP SMEP & SMAP 实验:构造IDT后门 第一步:编译以下代码 第二步:构造IDT后门 第三步:运行程序 第四 ...

  9. Windows x64内核学习笔记(一)—— 环境与配置

    Windows x64内核学习笔记(一)-- 环境与配置 前言 新特性 基础要求 实验环境 Guest Win10配置 问题解决 参考资料 前言 之前,跟着海哥学习了windows内核的一些机制,包括 ...

  10. 操作系统进程学习(Linux 内核学习笔记)

    操作系统进程学习(Linux 内核学习笔记) 进程优先级 并非所有进程都具有相同的重要性.除了大多数我们所熟悉的进程优先级之外,进程还有不同的关键度类别,以满足不同需求.首先进程比较粗糙的划分,进程可 ...

最新文章

  1. zookeeper和duboo 没用
  2. Java基础篇:反射
  3. Unsupported gpu architecture 'compute_*'2017解决方法
  4. Errors running builder 'JavaScript Validator' on project
  5. Java高级工程师学习路径
  6. PyQt之Eric:成功解决No module named 'my_image_rc'
  7. 算法 --- 递归生成括号
  8. 使用Hexo搭建个人博客的终极资料
  9. swift面向对象之多态与继承
  10. 过来人经验告诉你,如何从小菜B晋升为月薪过万的软件测试工程师?
  11. 【数据集的制作】VOC2007数据集格式的转换(voc2yolo)与划分
  12. 基于CCII+的电流模式二阶带通滤波器仿真
  13. 毕业论文查重注意事项论文检测查重原理(以PaperPass为例)
  14. springboot 整合mybatis,pagehelper。测试类。
  15. “校长”,我的同事,神奇的秋名山车神
  16. ue4 ui 序列图_UE4入门之路(UI篇):UMG系统介绍
  17. 圣诞表白html,Pyhton表白代码——浪漫圣诞节
  18. 个人总结:Mysql知识图谱
  19. CMIP6中进行SWAT数据制备时,辐射和相对湿度降尺度一般都用什么方法?类似降水还是气温还是风速的算法?
  20. 手机软件测试自学乐器,自学乐器不难!——从用好这6款APP开始吧

热门文章

  1. 将pdf转成图片时,文字没法显示
  2. java 接入微信获取人员信息名称带表情符号无法存储
  3. Java实现 蓝桥杯VIP 算法训练 调和数列
  4. Python-Level2-day11:TCP客户端/服务端传输(循环模型之短连接与长连接形态);TCP粘包问题;与UDP对比;数据传输过程原理;
  5. 如何拆分PDF文件,PDF如何拆分页面
  6. 班主任直接把奖学金名额给了我?就因为我用Python给她写了一个自动阅卷脚本
  7. windows通过bat运行指定位置程序及设置开机自启
  8. 电脑知识:台式电脑如何使用无线网上网?
  9. stylecloud 自定义蒙版
  10. android版本高低有啥好处与不好,WP跟安卓比流畅 但为什么就不好用呢?