前两日碰到了用异常处理来做加密的re题目 所以系统学习一下windows内核相关

windows内核基础

权限级别

内核层:R0 零环 核心态工作区域 大多数驱动程序

应用层:R3 用户态工作区域 只能使用win32 api与系统交互

R0与R3的通信

调用流程

当用户调用一个有关I/O的API时

该API封装在一个用户层的DLL文件中(如kernel32.dll或user32.dll)

此dll函数的更底层函数被包含在ntdll.dll中

即用户调用的系统API在ntdll.dll均有对应

(ntdll.dll中的函数均为成对出现 且为Nt与Zw开头 他们本质一样)

当调用到ntdll.dll中的函数时,检查完参数后,会通过int 2Eh或SysEnter进入R0内核层

调用内核ntoskrnl.exe中的SSDT(系统服务处理函数)他们与ntdll.dll的函数一一对应

调用区别

从用户态调用 Nt 与Zw 函数时**

完全一致 均为设置系统服务表与栈中参数后由SYSENTER跳入内核态

再由KiSystemService跳入对应系统例程

代码会严格检验传入参数

从内核态调用 Nt 与Zw 函数时**

Nt* API:直接调用对应函数代码

Zw* API:由KiSystemService跳入对应函数代码

用户模式Nt*api会将Previous Mode改为用户态

内核模式Nt*api会将Previous Mode改为内核态

Zw*api只有用户态 但一调用就会将Previous Mode改为内核态

而Zw*不会严格检查传入参数 进而提高效率

总结

Zw和Nt在表面功能一模一样!

内核函数

windows异常处理

也可使用RaiseException()函数来主动抛出一个异常

异常处理流程

window正常启动后运行在保护模式下,当中断或异常发生时,CPU会通过IDT(中断描述符表 Interrupt Descriptor Table)来寻找相对应的处理函数

IDT

IDT存在于物理内存中 共有256项 32位每项8字节 64位中每项64字节

每个cpu中都有一份IDT拷贝 下面主要考虑32位

异常处理准备工作

会根据异常号来寻找异常处理函数 如中断号03(即int 3)对应断点异常 由nt!KiTrap03 函数处理

该函数封装异常信息(包括异常产生原因与异常时线程状态(如寄存器值与其他特殊变量))

然后下发给内核的nt!KiDispatchException来处理

该函数会根据是否存在内核调试器用户态调试器,以及调试器对异常的干预结果来进行不同的处理

内核态的异常处理机制(内核态下出现异常

1.交由内核态调试器

当在被内核态调试器调试时,将异常处理控制权移交,表明FirstChance,

​ 内核调试器根据设置来判断处理,若无法决定则发生中断将控制权移交给用户

​ 若正确处理则继续执行程序

若无内核态调试器则跳过该步

2.交由nt!RtlDispatchException函数处理(由SEH处理

若无内核调试器或内核调试器选择不处理该异常,将会调用内核的nt!RtlDispatchException函数,根据SEH来处理

3.交由内核态调试器

若nt!RtlDispatchException函数未能处理该异常,系统将异常处理控制权移交内核调试器(SecondChance)

4.蓝屏!

若不存在内核态调试器或在第二次机会时仍不处理,则系统调用KeBugCheckEx的BSOD 引发蓝屏

在以上任何一步异常被处理 整个异常处理流程就会被终结

用户态的异常处理机制

完全可以交由内核调试器来处理 但一般内核调试器对用户异常不关心

所以将会分发给用户调试器

1.交由用户态调试器

当在被用户态调试器调试时,将异常处理控制权移交,表明FirstChance,

若无用户态调试器则跳过该步

2.由SEH与VEH来处理

若无用户态调试器或用户态调试器未处理该异常,

将在栈上放置EXCEPTION_RECORD和CONTEXT两个结构

然后调用ntdll.dll的nt!RtlDispatchException函数

SEH:在有调试器时进入下一步,否则调用API函数SetUnhandledExceptionFilter的顶级异常处理,即显示以下对话框

若无调试器附加或调试器无法处理异常则ExitProcess函数来终结程序

3.再次分发给用户态调试器

若nt!RtlDispatchException函数未能处理该异常,系统将异常处理控制权移交用户调试器(SecondChance)

若无调试器则直接结束进程

4.错误弹窗

若第二次机会调试器仍不处理则

SEH

TIB

TIB(线程信息块)位于TEB(线程环境块)头部

而TIB的首项指向异常处理链表

32位下FS寄存器指向TEB 即指向TIB 即指向异常处理链表

64位下是gs寄存器指向TEB

而TIB[0]对应的

因为TEB是线程环境块,所属于当前线程,所以SEH机制仅限于当前线程

SEH

若想新增或删除 则直接在链表头部编写一个新的_EXCEPTION_REGISTRATION_RECORD

可以说SEH是基于栈帧的异常处理机制

因此SEH是从0开始往后面找的异常处理

SEH中异常处理函数的返回值

VEH

VEH与SEH大抵类似 同样是链表 但调用顺序为调试器>VEH>SEH

VEH对整个进程都有效 而SEH对单个线程有效

总结 大概吧

对我目前碰到的re题来说 与异常相关的只有主动抛出异常(如idiv rax)在循环加密过程中rax可能为0 从而进入另外的加密函数

若想动态跟踪该类函数 可以调试OD x64dbg 或IDA 的debug调试 将异常交由被调试者处理

(别没事瞎F5 伪代码还真不显示SEH 汇编

只总结了一点点 实际上加密与解密中关于内核和异常处理还有很多更深的内容 (但我还是选择先看17章(

windows内核基础与异常处理的更多相关文章

  1. Windows内核基础知识-1-段寄存器

    Windows内核基础知识-1-段寄存器 学过汇编的应该都知道段寄存器,在Windows里段寄存器有很多,之前可能只接触了ds数据段,cs 代码段这种,今天这个博客就介绍Windows一些比较常用的段 ...

  2. Windows内核基础知识-2-段描述符

    Windows内核基础知识-2-段描述符 比如: ES 002B 0(FFFFFFFF) 意思就是es段寄存器,段选择子/段选择符 为002B, 起始地址base为0, 限制范围Limit地址最大能寻 ...

  3. Windows内核基础知识-8-监听进程、线程和模块

    Windows内核基础知识-8-监听进程.线程和模块 Windows内核有一种强大的机制,可以在重大事件发送时得到通知,比如这里的进程.线程和模块加载通知. 本次采用链表+自动快速互斥体来实现内核的主 ...

  4. Windows内核基础知识-5-调用门(32-Bit Call Gate)

    Windows内核基础知识-5-调用门(32-Bit Call Gate) 调用门有一个关键的作用,就是用来提权.调用门其实就是一个段. 调用门: 这是段描述符的结构体,里面的s字段用来标记是代码段还 ...

  5. Windows内核开发-3-内核编程基础

    Windows内核开发-3-内核编程基础 这里会深入讲解kernel内核的API.结构体.和一些定义.考察代码在内核驱动中运行的机制.最后把所有知识合在一起写一个有用的驱动. 本章学习要点: 1:通用 ...

  6. Windows内核开发-4-内核编程基础

    Windows内核开发-4-内核编程基础 这里会构建一个简单但是完整的驱动程序和一个客户端,部署内核执行一些平时user下无法执行的操作. 将通过以下内容进行讲解: 1 介绍 2 驱动初始化 3 Cr ...

  7. [1]windows 内核情景分析---说明

    本文说明:这一系列文章(笔记)是在看雪里面下载word文档,现转帖出来,希望更多的人能看到并分享,感谢原作者的分享精神. 说明 本文结合<Windows内核情景分析>(毛德操著).< ...

  8. Windows内核安全与驱动开发

    这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...

  9. Windows Kernel Way 1:Windows内核调试技术

    掌握Windows内核调试技术是学习与研究Windows内核的基础,调试Windows内核的方式大致分为两种: (1)通过Windbg工具在Windows系统运行之初连接到Windows内核,连接成功 ...

随机推荐

  1. 初识python: 递归函数

    定义: 在函数内,可以调用其他函数,如果一个函数在内部调用自己,返回值中包含函数名,这个函数就是递归函数. 特性: 1.必须要有明确的结束条件: 2.每进入更深一层递归时,问题规模相对上次递归都应该有 ...

  2. Flask_generate_password_hash的加盐哈希加密算法与check_password_hash的校验

    密码加密简介 密码存储的主要形式: 明文存储:肉眼就可以识别,没有任何安全性. 加密存储:通过一定的变换形式,使得密码原文不易被识别. 密码加密的几类方式: 明文转码加密算法:BASE64, 7BIT ...

  3. nuxt2.0项目创建(最新)

     使用import需要babel编译写法如下 //修改1打开package.json文件 "dev": "cross-env NODE_ENV=development n ...

  4. F5 BIG-IP 远程代码执行漏洞环境搭建

    最近F5设备里的远程代码执行漏洞可谓是火爆,漏洞评分10分,所以,我也想搭建下环境复现一下该漏洞 漏洞详情 F5 BIG-IP 是美国F5公司一款集成流量管理.DNS.出入站规则.web应用防火墙.w ...

  5. Linux中的一些基本命令

    文章目录 ls cd Linux的目录 文件的权限 1.用户,组,权限 2.文件的权限 文件的基本操作 增:创建文件 删:删除文件 改:修改文件 查:查看 vi/vim 是一个编辑工具,主要用来编辑文 ...

  6. 【视频解码性能对比】opencv + cuvid + gpu vs. ffmpeg + cpu

    视频大小:1168856 字节画面尺寸:480*848帧数:275opencv + cuvid + tesla P4, 解码性能:1426.84 fps ffmpeg 4.0 API + [Intel ...

  7. vscode配置Microsoft C++注意事项

    vscode配置c++插件教程链接如下: https://code.visualstudio.com/docs/cpp/config-msvc#_check-your-microsoft-visual ...

  8. selenium获取cookies并持久化登陆

    selenium获取cookies并持久化登陆 需求背景: ​ 这几天需要写一个接口,用来批量上传数据,最开始考虑的是 UI 自动化,然后选值的时候自动化难以判别,最终选择 接口 自动化. ​ 然后操 ...

  9. sql中常用到的GUID

    在项目的数据库中经常见到如下所示的列: 列名:**_id 数据类型:UNIQUEIDENTIFIER 默认:NEWID() ROWGUIDCOL 属性. 其实这样的列通常为表的主键,函数NEWID() ...

  10. 边带权并查集 学习笔记 & 洛谷P1196 [NOI2002] 银河英雄传说 题解

    花了2h总算把边带权并查集整明白了qaq 1.边带权并查集的用途 众所周知,并查集擅长维护与可传递关系有关的信息.然而我们有时会发现并查集所维护的信息不够用,这时"边带权并查集"就 ...