【逆向工程核心原理:SEH】

news2025/1/12 13:12:43

SEH

SEH是Windows操作系统提供的异常处理机制,在程序源代码中使用__ try、 __except、__finally关键字来具体实现。主要用在反调试中。


SEH与C++中的try. catch 异常处理具有不同结构。从时间上看,与C++的try、catch异常处理相比,微软先创建出了SEH机制,然后才将它搭载到VC++中。所以SEH是一种从属于VC++开发工具和Windows操作系统的异常处理机制。

调试运行时的异常处理

若被调试进程内部发生异常:
OS会首先把异常抛给调试进程处理调试器几乎拥有被调试者的所有权限,它不仅可以运行、终止被调试者,还拥有被调试进程的虚拟内存、寄存器的读写权限。需要特别指出的是,被调试者内部发生的所有异常( 错误)都由调试器处理。所以调试过程中发生的所有异常( 错误)都要先交由调试器管理(被调试者的SEH依据优先顺序推给调试器)。像这样,被调试者发生异常时,调试器就会暂停运行,必须采取某种措施来处理异常,完成后继续调试。

  • 遇到异常时经常采用的几种处理方法:
  1. 直接修改异常:代码、寄存器、内存
  2. 将异常抛给被调试者处理
  3. OS默认的异常处理机制

操作系统定义的异常

EXCEPTION_DATATYPE_MISALIGNMENT		(0X80000002)
EXCEPTION_BREAKPOINT				(0X80000003)
EXCEPTION_SINGLE_STEP				(0x80000004)
EXCEPTION_ACCESS_VIOLATION			(0xC0000005)
EXCEPTION_IN_PAGE_ERROR				(0xC0000006)
EXCEPTION_ILLEGAL_INSTRUCTION		(0xC000001D)
EXCEPTION_NONCONTINUABLE_EXCEPTION 	(0xC0000025)
EXCEPTION_INVALID_DISPOSITION		(0xC0000026)
EXCEPTION_ARRAY_BOUNDS_EXCEEDED		(0xC000008C)
EXCEPTION_FLT_DENORMAL_OPERAND		(0xC000008D)
EXCEPTION_FLT_DIVIDE_BYZERO			(0xC000008E)
EXCEPTION_FLT_INEXACT_RESULT		(0xC000008F)
EXCEPTION_FLT_INVALID_OPERATION		(0xC0000090)
EXCEPTION_FLT_OVERFLOW				(0xC0000091)
EXCEPTION_FLT_STACK_CHECK			(0xC0000092)
EXCEPTION_FLT_UNDERFLOW				(0xC0000093)
EXCEPTION_INT_DIVIDE_BY_ZERO		(0xC0000094)
EXCEPTION_INT_OVERFLOW				(0xC0000095)
EXCEPTION_PRIV_INSTRUCTION			(0xC0000096)
EXCEPTION_STACK_OVERFLOW			(0xC00000FD)
  • 常见的异常

EXCEPTION_ACCESS_VIOLATION(C0000005):非法访问异常,试图访问不存在或不具访问权限的内存区域。

EXCEPTION_BREAKPOINT(80000003):运行的代码被设置了断点之后,CPU尝试执行该地址处的指令时,就会发生EXCEPTION_BREAKPOINT异常。原理是,设置断点会将该处的指令修改为0xCC,但Ollydbg不会将临时断点的实际指令显示出来,可以使用PE Tools工具转储进程内存之后,使用Hex Editor打开文件,即可看到真是指令。

EXCEPTION_ILLEGAL_INSTRUCTION(C000001D):CPU遇到无法解析的指令时引发该异常。

EXCEPTION_INT_DIVIDE_BY_ZERO(C0000094):除法运算中若分母为零就会发生除零异常。程序中可能出现的情况是分母为变量,变量在某个时刻变为0,再执行除法运算时就会出现异常。

EXCEPTION_SINGLE_STEP(80000004):将EFLAGS寄存器的第八位TF(Trap Flag陷阱标志)设置为1之后,CPU就会进入单步工作模式。每执行一条指令之后,就会暂停,抛出异常。

SEH链

SEH以链的形式存在,由_EXCEPTION_REGISTRATION_RECORD结构体组成的链表
第一个异常处理器如果未处理相关异常,它就会被传递到下一个异常处理器,直到得到处理。

  • SEH结构体
typedef struct _EXCEPTION_REGISTRATION_RECORD
{
	// 链表以Next成员为FFFFFFFF的结构体结束,表示链表的最后一个结点
	PEXCEPTION_REGISTRATION_RECORD Next;
	// Handler:异常处理函数
	PEXCEPTION_DISPOSITION Handler;
} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;

// 异常顺着链传递,直到有异常处理器处理

用图表示
在这里插入图片描述

  • 异常处理函数
    这个函数是一个回调函数,由系统来调用,系统会提供函数需要的参数
    由定义可以看出,这个函数需要四个参数,返回值是一个enum类型
EXCEPTION_DISPOSITION _except_handler
(
	EXCEPTION_RECORD *pRecord,
	EXCEPTION_REGISTRATIOIN_RECORD *pFrame,
	CONTEXT *pContext,
	PVOID pValue
);

第一个参数

typedef struct _EXCEPTION_RECORD {
	DWORD ExceptionCode;						//异常代码,用来指明异常类型
	DWORD ExceptionFlags;
	struct _EXCEPTION_RECORD * ExceptionRecord;	
	PVOID ExceptionAddress;						//发生异常的代码地址
	DWORD NumberParameters;
	ULONG_PTR ExceptionInformation[EXCEPTION_AMXIMUM_PARAMETERS];//15
} EXCEPTION_RECORD, *PEXCEPTION_RECORD

第三个参数

struct CONTEXT
{
	DWORD ContextFlags;
	DWORD Dr0;
	DWORD Dr1;
	DWORD Dr2;
	DWORD Dr3;
	DWORD Dr6;
	DWORD Dr7;
	FLOATING_SAVE_AREA FloatSave;
	DWORD SegGs;
	DWORD SegFs;
	DWORD SegEs;
	DWORD SegDs;
	DWORD Edi;
	DWORD Esi;
	DWORD Ebx;
	DWORD Edx;
	DWORD Ecx;
	DWORD Eax;
	DWORD Ebp;
	DWORD Eip;
	DWORD SegCs;
	DWORD EFlags;
	DWORD Esp;
	DWORD SegSs;
	BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];//512
}

返回值

typedef enum _EXCEPTION_DISPOSITION
{
	ExceptionContinueExecution = 0,	//继续执行异常代码
	ExceptionContinueSearch = 1,	//运行下一个异常处理器
	ExceptionNestedException = 2,	//在OS内部使用
	ExceptionCollidedUnwind = 3		//在OS内部使用
} EXCEPTION_DISPOSITION;

异常处理器处理异常后会返回ExceptionContinueExecution(0),从发生异常的代码出继续运行。若无法处理异常,则返回ExceptionContinueSearch(1),将一场派送到SEH链的下一个异常处理器。

  • 访问进程的SEH链的方法

通过TEB结构体的NtTib成员
TEB.NtTib.ExceptionList = FS:[0]

  • 安装SEH

在C语言中,使用__try、__except、__finally关键字可以向代码添加SEH。

汇编

PUSH @MyHandler
PUSH DWORD PTR FS:[0]
MOV DWORD PTR FS:[0], ESP

FS:[0]这里存放的是TEB的地址,TEB的第一个成员是 _NT_TIB 结构体,_NT_TIB 结构体的第一个成员是 _EXCEPTION_REGISTRATION_RECORD 类型的结构体指针,也就是 SEH 链的首地址

  • TEB结构
// MSDN给的参考
typedef struct _TEB {
  PVOID Reserved1[12];
  PPEB  ProcessEnvironmentBlock;
  PVOID Reserved2[399];
  BYTE  Reserved3[1952];
  PVOID TlsSlots[64];
  BYTE  Reserved4[8];
  PVOID Reserved5[26];
  PVOID ReservedForOle;
  PVOID Reserved6[4];
  PVOID TlsExpansionSlots;
} TEB, *PTEB;

WinDbg看到的

+0x000 NtTib            : _NT_TIB
...
+0x030 ProcessEnvironmentBlock : Ptr32 _PEB

这是两个重要的成员,ProcessEnvironmentBlock是PEB的地址

NtTib结构:

typedef struct _NT_TIB          //sizeof  1ch
{
 00h   struct _EXCEPTION_REGISTRATION_RECORD  *ExceptionList;          //SEH链入口
 04h   PVOID StackBase;              //堆栈基址
 08h   PVOID StackLimit;             //堆栈大小
 0ch   PVOID SubSystemTib;
       union {
           PVOID FiberData;
 10h       DWORD Version;
       };
 14h   PVOID ArbitraryUserPointer;
 18h   struct _NT_TIB *Self;                  //本NT_TIB结构自身的线性地址
}NT_TIB;
 
typedef NT_TIB *PNT_TIB;

其他

学习来源

  • 当进程中发生异常时,若SEH未处理或注册的SEH不存在。此时会调用系统的kernel32!UnhandledExceptionFIlter()API。
  • 该API会运行系统的最后一个异常处理器——Top Level Exception FilterLast Exception Filter(通常行为是弹出错误消息框、终止进程)。
  • kernel32!UnhandledExceptionFilter()调用了ntdll!QueryInformationProcess(ProcessDebugPort)。来判断是否正在调试进程。如果正在进行调试,则将异常传递给调试器。否则系统异常处理器终止进程。
  • 通过kernel32!SetUnhandledExceptionFilter()可以修改系统最后的异常处理器。函数定义如下:
//返回的是上一个Top Level Exception Filter的地址,方便恢复
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
	__in LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
  • Top Level Exception Filter的函数定义:
typedef struct _EXCEPTION_POINTERS{
	PEXCEPTION_RECORD ExceptionRecord;
	PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

LONG TopLevelExceptionFilter(
	PEXCEPTION_POINTER pExcept;
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/551826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app--》uView组件库:提升您的uni-app开发体验

🏍️作者简介:大家好,我是亦世凡华、渴望知识储备自己的一名在校大学生 🛵个人主页:亦世凡华、 🛺系列专栏:uni-app 🚲座右铭:人生亦可燃烧,亦可腐败&#xf…

MMDet3d样本均衡

MMDet3d样本均衡 文章目录 MMDet3d样本均衡CBGSDataset训练时数据是200帧,后面处理时,dataloader中数据变成了460帧,怎么均衡的?思考抽帧数计算某个类别帧数为0 Reference欢迎关注公众号【三戒纪元】 CBGSDataset **CBGS &#x…

UE虚幻引擎,Unity3D,Blender区别和联系

1. 官网手册 UnityUEBlenderUnity 用户手册 (2019.4 LTS) - Unity 手册虚幻引擎5.2文档 | 虚幻引擎5.2文档 (unrealengine.com)Blender 3.5 Reference Manual — Blender Manual 2. Unity, UnrealEngine, Blender的区别 Blender 是一款免费的开源软件,是一个开源…

Godot引擎 4.0 文档 - 循序渐进教程 - 脚本语言

本文为Google Translate英译中结果,DrGraph在此基础上加了一些校正。英文原版页面: Scripting languages — Godot Engine (stable) documentation in English 脚本语言 本课将概述 Godot 中可用的脚本语言。您将了解每个选项的优缺点。在下一部分中&…

CentOS7搭建伪分布式Hadoop(全过程2023)

##具体操作目录## 1.配置静态ip2.关闭防火墙3.修改主机名为 *master* ,并重启虚拟机vi /etc/hostname 4.修改主机名与ip映射5.设置SSH免密登录6.安装配置java环境----------------------正式Hadoop配置1.移动安装包到合适位置2.解压安装包并重命名3.配置环境变量4.修…

know it and do it

overview: 在一盘盘有立即反馈的系统中,可以更直观的看到知道一个道理和能自然的用出来之间的鸿沟有多大。 这个就是日积月累的训练的意义了。 一夜回到解放前 继续金铲铲的游玩回味,之前一段时间忙于工作就放下了,后来新的版本…

20230521 AI 一周大事件汇总

🚀 ChatGPT 上线联网和插件功能 OpenAI宣布将在这周推出联网和插件功能,位于Alpha和Beta通道的ChatGPT Plus用户都可使用70多个上线的插件。 更新意味着ChatGPT将利用最新的信息和资讯为使用者提供服务。 上线的ChatGPT插件种类涵盖了行程安排助理、代…

拿捏大厂面试官的高质量自动化测试工程师简历--看完必有所获

一、前言:简历(职场敲门砖) 作为软件测试的垂直领域深耕者,面试或者被面试都是常有的事,可是不管是啥,总和简历有着理不清的关系,面试官要通过简历了解面试者的基本信息、过往经历等&#xff0c…

阿里p10手敲python +pytest +yaml + Allure 实现接口自动化框架

以前弄过好多接口自动化框架的东西,比如httprunner2.0版本实现的接口自动化框架,还有httprunner3.X实现的接口自动化框架,这些都是开源的,实现起来比较简单。 以及使用pythonunittestddtyaml等工具实现的接口自动化框架等。 今天…

【腾讯云 Finops Crane 集训营】安装使用及EHPA弹性演示

随着时间的推移,降本增效成为了企业界和组织中的一个新口号。在2023年,这个口号进一步获得了广泛的认可和重要性,成为了许多组织在业务运营中的关键目标。在2023年,许多组织开始将降本增效作为战略性目标,并将其融入到…

3.fabric二进制工具包介绍

(1)Fabric二进制工具包: Fabric二进制工具包:Fabric二进制工具包(Fabric Binary Distribution)是Hyperledger Fabric的核心组件,它包含了一系列可执行的二进制文件,用于搭建、管理和操作Fabric网络。该工具包提供了一套命令行工具,可以执行各种与Fabric网络相关的任务…

模板(初阶)

目录 一、泛型编程二、函数模板2.1 函数模板的概念2.2 函数模板的格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 三、类模板3.1 类模板的定义格式3.2 类模板的实例化 一、泛型编程 如何实现一个通用的Swap函数 void Swap(int& x, int& y) {int …

chatgpt赋能Python-pythonapp自动化

Python App自动化:优化SEO的终极解决方案 随着互联网的发展,SEO(搜索引擎优化)变得日益重要。对于任何网站或应用程序开发人员来说,SEO应该是一个非常重要的考虑因素。为了帮助开发人员和企业提高其在线可见性&#x…

Squid代理服务器应用

在web架构中,用户一般进入负载均衡层,通过调度来访问web应用层,但是如果访问量太大,并发量较高,web应用层会吃不消,我们把静态资源、经常要访问的资源放入缓存,用户直接访问缓存层,加…

解析使用FPGA逻辑实现FIR滤波器的几种架构

有限脉冲响应(finite impulse response,FIR)数字滤波器 一、FIR数字滤波器理论介绍 FIR滤波器的实质就是输入序列与系统脉冲响应的卷积,即: 其中,N为滤波器的阶数,也即抽头数;x(n)为第n个输入序列&#xff…

人工智能轨道交通行业周刊-第45期(2023.5.15-5.21)

本期关键词:动车洗澡、热备列车、火车司机室、无缝线路、图像分割、自动标注 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道…

Linux开发工具:yum和vim的使用

目录 一. Linux下的软件 1.1 软件安装的三种方法 1.2 采用yum安装软件 1.3 yum源的问题 二. vim开发工具的使用 2.1 vim的三种基本模式 2.2 命令模式下vim的常用指令 2.2.1 定位相关指令 2.2.2 光标移动相关指令 2.2.3 插入相关指令 2.2.4 复制粘贴相关指令 2.2.5 替…

Tauri应用开发(三):自定义拖拽区域

1. 自定义拖拽:data-tauri-drag-region tauri默认的顶部可拖拽,有时候我们不需要这个拖拽,或者需要自定义拖拽区域时,就需要通过tauri提供的data-tauri-drag-region属性来自定义拖拽区。 ![在这里插入图片描述](https://img-blog…

基于Python的图书信息管理系统

1引言 进入21世纪以来,信息技术从根本上推动了图书馆的飞速发展,计算机和计算机管理系统已成为图书馆进行图书管理的主要设备和系统。虽然目前很多大型的图书馆已经有一整套比较完善的管理系统,但是在一些中小型的图书馆中,大部分…

【Python 虚拟环境创建】解决遇到的问题并在vscode上测试

目录 一、前提准备 二、python虚拟环境创建 解决问题:‘virtualenv’/‘mkvirtualenv‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 解决问题:pycharm终端提示无法加载文件 E:\software\python_pycharm\venv\Scripts\activat…