49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理

图0: 下方是一个简化过的代码

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第1张图片

做一个软件调试器最基本的是,首先要调试一个进程那么就要有一个进程

拿x96dbg来讲调试一个进程有两种方式,第一种通过附加(如图1),通过附加可以对已经创建的进程进行调试,第二种通过打开(如图2)创建一个进程对它进行调试,图0里的代码也有体现,创建一个进程CreateProcess函数,另外一种DebugActiveProcess函数,需要提供任务管理器里的进程id。如图3

打开或附近进程成功的话:

就有一个类似Windows消息循环,如图4,就是首先给它传递一个结构体(DEBUG_EVENT),然后通过WaitForDebugEvent(等待调试时间的函数)只要有调试事件我们就能收到,然后通过消息里的dbgevent.dwDebugEventCode就能够处理了,它会有模块的加载,下个断点给我们回馈等,DEBUG_EVENT里的内容很丰富,也就是调试器与被调试进程通过 图4 的代码给衔接起来了,它们是通过Windows消息机制来传递的。

以上就是一个调试器最核心的地方,知道这些东西之后,再分析CreateProcess是怎样达成一个调试的状态的。

CreateProcess里有一个dwCreationFlags 进程创建标志位,它的取值很多,需要去看微软提供的文档,跟调试器有关了有两个,DEBUG_PROCESS、DEVUG_ONLY_THIS_PROCESS

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第2张图片

DEBUG_PROCESS说明:

得到调试进程的权限并且可以调试它的子进程

DEVUG_ONLY_THIS_PROCESS:

只能调试当前进程

然后 CreateProcess 创建被调试进程的底层函数:

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第3张图片

DbgUiConnectToDbg:

调试器进程与调试器子系统建立链接,意思是调试它是通过一套复杂的系统来完成的,涉及到消息的传递、管理等,早期操作系统是通过smss.exe 或 crss.exe去完成的,它怎样建立链接的,它是先创建一个DEBUG_OBJECT类型的内核对象(在Windows2000或Windows2000以前的时候不是),然后把内核对象保存到线程环境里TEB结构里有一个DbgSsReserved[1](Windows2000会保存到0和1两个位置),这个对象是保存在调试进程里的,不是被调试进程里,这时被调试进程还没被创建

NtCreateProcess() 或 NtCreateProcessEx()

创建进程,首先内核里有一个进程管理器,需要把 DbgSsReserved[1] 传递给内核进程管理器,然后调用内核里的PsCreateProcess函数把 DbgSsReserved 这个字段传递给EPROCESS结构里的DebugPort字段,然后创建进程的函数(PsCreateProcess)调用MmCreatePeb创建进程PEB(3环进程结构或者说是用户层的进程结构这里有peb结构怎样去找,以及通过peb结构找模块链的例子)数据,MmCreatePeb函数会根据DebugProt的值,它的值不被调试的时候一定是0,被调试的时候一定是有内容的,如果为0,PEB结构下的BeingDebugged字段的值等于0,DebugProt的值有内容BeingDebugged字段的值就为1

EPROCESS结构说明:https://note.youdao.com/s/Qp1hET5X

 特征:

进程一但被调试,它的两大特征是DebugPort字段在内核下一定是有内容的,在应用态下PEB里的BeingDebugged是由内容的,它的依赖就是着一系列路径上用到的函数

接下俩再说对现有进程做调试的:

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第4张图片

首先第一步还是跟调试子系统建立链接,接下来因为给它传的是一个进程id,进程id要转换成内核对象句柄,所以这时就会调用OpenProcess,然后OpenProcess再调用底层的NtOpenProcess来得到句柄,得到句柄以后然后设置它进程的调试状态,这时就利用DbgUiDebugActiveProcess函数来得到它的PPROCESS结构,再根据DbgkpSetProcessDebugObject函数将DebugProt建立链接,然后再通过DbgkpMarkProcessPeb来设置调试进程的BeingDebuggged

特征:

两种方法归根到底,都是设置DebugProt、BeingDebuggged这俩字段

结论:

一个进程被调试,内核状态下EPROCESS结构的DebugProt一定不为0

用户态模式下PEB结构的BeingDebuged一定不为0

图1:

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第5张图片

图2:

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第6张图片

图3:

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第7张图片

图4: 

49.网游逆向分析与插件开发-游戏反调试功能的实现-软件调试器设计的基本原理_第8张图片

你可能感兴趣的:(游戏,网游逆向)