当前位置:网站首页 > Go语言开发 > 正文

windows驱动开发(windows驱动开发书籍)



一、CPU异常记录

1)CPU产生的异常 2)软件模拟产生的异常

CPU指令检测到异常(例:除0) -->查IDT表,执行中断处理函数 -->CommonDispatchException-->KiDispatchException

_KiTrap00函数分析: 1)保存现场(将寄存器堆栈位置等信息保存到_trap_frame中) 2)调用CommonDispatchException函数(分析参数EAX,EBX中的值) 为什么不把异常直接处理掉?

该函数构造一个_EXCEPTION_RECORD结构体并赋值

type struct_EXCEPTION_RECORD { DWORD ExceptionCode; //异常代码  DWORD ExceptionFlags; //异常状态  struct_EXCEPTION_RECORD* ExceptionRecord; //下一个异常  PVOID ExceptionAddress; //异常发生地址  DWORD NumberParameters; //附加参数指针  ULONG_PTR ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS]; //附加参数个数 }

CxxThrowException --> (KERNEL32.DLL)RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *IpArguments) --> NTDLL.DLLIRtIRaiseException() --> NTINtRaiseException --> NT!KiRaiseException

1)填充ExceptionRecord结构体

 type struct_EXCEPTION_RECORD { DWORD ExceptionCode; //异常代码 DWORD ExceptionFlags; //异常状态 struct_EXCEPTION_RECORD* ExceptionRecord; //下一个异常 PVOID ExceptionAddress; //异常发生地址 DWORD NumberParameters; //附加参数个数 ULONG_PTR ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS]; //附加参数指针 }
  1. 调用Ntdll.dll!RtIRaiseException函数

异常可以发生在用户空间,也可以发生在内核空间。 ​ 无论是CPU异常还是模拟异常,是用户层异常还是内核异常,都要通过 KiDispatchException函数进行分发。理解这个函数是学好异常的关键,这个函数比较复杂,本节课我们主要分析内核异常是如何分发,如何处理的。

VOID KiDispatchException(ExceptionRecord, ExceptionFrame, TrapFrame,PeviousMode,FirstChance) 1)_KeContextFromKframesTrap_frame备份到context为返回3环做准备 2)判断先前模式PeviousMode 0是内核调用1是用户层调 3)是否是第一次机会 4)是否有内核调试器 5)如果没有或者内核调试器不处理 6)调用RtIDispatchException

typedef struct_EXCEPTION_REGISTRATION_RECORD { struct_EXCEPTION_REGISTRATION_RECORD *Next; PEXCEPTION_ROUTINE Handler; }EXCEPTION_REGISTRATION_RECORD;

RtIDispatchException的作用就是: 遍历异常链表,调用异常处理函数,如果异常被正确处理了,该函数返回1. 如果当前异常处理函数不能处理该异常,那么调用下一个,以此类推。 如果到最好也没有人处理这个异常,返回0。

VOID KiDispatchException(ExceptionRecord, ExceptionFrame, TrapFrame,PeviousMode,FirstChance) 1)_KeContextFromKframesTrap_frame备份到context为返回3环做准备 2)判断先前模式PeviousMode 0是内核调用1是用户层调 3)是否是第一次机会 4)是否有内核调试器 5)发送给3环调试 6)如果3环调试器没有处理这个异常修正EIP为KiUserExceptionDispatcher 7)KiDispatchException函数执行结束: CPU异常与模拟异常返回地点不同 CPU异常: CPU检测到异常→查IDT执行处理函数--> CommonDispatchException->KiDispatchException 通过IRETD返回3环 模拟异常: CxxThrowException-RaiseException->RtiRaiseException NTINtRaiseException→>NTIKiRaiseException-->KiDispatchException 通过系统调用返回3环 8)无论通过那种方式,但线程再次回到3环时,将执行KiUserExceptionDispatcher函数

1)调用RtIDispatchException查找并执行异常处理函数 2)如果RtIDispatchException返回真,调用ZwContinue再次进入0环,但线程再次返回3环时,会从修正后的位置开始执行。 3)如果RtIDispatchException返回假,调用ZwRaiseException进行第二轮异常分发

1)查找VEH链表(全局链表),如果有则调用 2)查找SEH链表(局部链表,在堆栈中),如果有则调用 注意:与内核调用时的区别!

1)CPU捕获异常信息 2)通过KiDispatchException进行分发(EIP=KiUserExceptionDispatcher) 3)KiUserExceptionDispatcher调用RtIDispatchException 4)RtIDispatchException查找VEH处理函数链表并调用相关处理函数 5)代码返回到KiUserExceptionDispatcher 6)调用ZwContinue再次进入0环(ZwContinue调用NtContinue,主要作用就是恢复TRAP-FRAME然后通过-KiServiceExit返回到3环)。 7)线程再次返回3环后,从修正后的位置开始执行

1)FS:[0]指向SEH链表的第一个成员 2)SEH的异常处理函数必须在当前线程的堆栈中 3)只有当VEH中的异常处理函数不存在或者不处理才会到SEH链表中查找

描述:当我们程序刚开始执行时,编译器已经替我们注册了一个异常处理程序,因此叫做最后一道防线

UnhandledExceptionFilter 描述:

最后一道防线调用的异常处理程序的过滤函数 只有当它的返回值为EXCEPTION_CONTINUE_SEARCH(0)时,当前线程不存在对应的SEH 只有在当前程序处于调试状态时,才会发生上述情况 执行流程:

通过NtQueryInformationProcess查询当前进程是否正在被调试,如果是,返回EXCEPTION_CONTINUE_SEARCH,此时会进入第二轮分发 如果没有被调试: 1)查询是否通过SetUnhandledExceptionFilter注册处理函数 如果有就调用 2)如果没有通过SetUnhandledExceptionFilter注册处理函数,弹出窗口,让用户选择终止程序还是启动即时调试器 3)如果用户没有启用即时调试器,那么该函数返回EXCEPTION_EXECUTE_HANDLER,此时会执行except中的代码

到此这篇windows驱动开发(windows驱动开发书籍)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • csgo的莫(csgo mojor)2026-01-22 20:09:08
  • 苹果开发者账号过期了(苹果开发者账号过期了怎么办)2026-01-22 20:09:08
  • 字符串转int go(字符串转int python)2026-01-22 20:09:08
  • windows驱动开发书籍(windows驱动开发陈志远)2026-01-22 20:09:08
  • 苹果开发者账号(苹果开发者账号一年多少钱)2026-01-22 20:09:08
  • vscode配置gcc开发环境(vscodec语言环境配置)2026-01-22 20:09:08
  • 苹果开发者账号注册流程英文(苹果开发者账号免费注册)2026-01-22 20:09:08
  • 拆包英文(拆包英文csgo)2026-01-22 20:09:08
  • 苹果开发者账号个人注册不了(苹果开发者注册失败)2026-01-22 20:09:08
  • linux内核驱动开发pdf(linux内核驱动开发中使用的地址是)2026-01-22 20:09:08
  • 全屏图片