我正在调试游戏,经常遇到异常(EXCEPTION_PRIV_INSTRUCTION)

调试器在它停止的地址处暂停,现在我想一次跳过一个命令,但是当我跳过时一次不会执行一个命令

评论

您可以尝试使用“ exhandlers”命令在x64dbg中查看可能的异常处理程序。

#1 楼

例外是复杂的业务。我将尝试简要解释Windows中的SEH(结构化异常处理)如何调用适当的异常处理程序。您的游戏可能未使用SEH,但是,由于您的问题过于笼统,因此将作为我的答案。我基于SEH编写它,因为它最容易理解,您可以逐步进行。

异常基础知识

有硬件和软件异常。 CPU抛出硬件异常-例如,在非法内存访问中,被0除......

软件异常(由C ++中的throw引起,使用Windows下的RaiseException调用(请参阅MSDN)

操作系统存储一个异常处理程序列表-可以处理异常的例程列表,这些例程通常是catch块中的指令。每个例程确定何时调用该例程它不是要处理异常。如果您的例程决定不处理异常,它将告诉OS继续查找。

处理程序列表存储在线程信息块(TIB)中:

_NT_TIB:
    +0x000 ExceptionList
    +0x004 StackBase
    +0x008 StackLimit
    +0x00C SubSytemTib
    +0x010 FiberData
    +0x010 Version
    +0x014 ArbitaryUserPointer
    +0x018 Self


TIB在FS:[0]处可用。

ExceptionList字段是当前线程的异常处理程序列表的头。

列表是由_EXCEPTION_REGISTRATION_RECORD结构组成的链:

_EXCEPTION_REGISTRATION_RECORD
    +0x000 Next
    +0x004 Handler


如何调度异常(页面错误示例)


加工基因为页面错误中断INT 0x0E评分并调用[IDT+0x0E]。在Windows中,通常为KiTrap0E
然后Windows调用KiUserExceptionDispatcher中的用户模式异常调度程序例程NTDLL.DLL
然后调度程序调用RtlDispatchException,该迭代遍历ExceptionList

从上面可以看到为什么程序跳来跳去,而且不能一行一行地跟随它-发生异常时,处理器本身调用KiTrap0E-您看不到该调用。然后,在调用处理程序时,还会有很多“跳转”-RtlDispatchException函数遍历所有已注册的异常处理程序。您需要找到合适的处理程序,并查看您的游戏在发生异常情况时的作用。