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

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

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

a4ff90cf2edd46feb1aa0b47e3a0fbdf.png

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

拿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

0eb35d59427b48ccbdd4c9836b40dec3.png

DEBUG_PROCESS说明:

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

DEVUG_ONLY_THIS_PROCESS:

只能调试当前进程

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

71ff70f105f44ad3bf9d5af7a8a006c3.png

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要从teb里取,teb在fs寄存器里详情看这个, 这里有peb在teb结构什么位置,以及通过peb结构找模块链的例子)数据,MmCreatePeb函数会根据DebugProt的值,它的值不被调试的时候一定是0,被调试的时候一定是有内容的,如果为0,PEB结构下的BeingDebugged字段的值等于0,DebugProt的值有内容BeingDebugged字段的值就为1

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

 特征:

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

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

b94bbd9773794d7494fd6fcbfd25e08b.png

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

特征:

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

结论:

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

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

图1:

84a5341a9c0f496b9b43806c0e50a3ff.png

图2:

d0e69886c5fc4a049a0bad6923c64038.png

图3:

5676736d13054c249c77e46affafb77e.png

图4: 

30df1774e4544af6a145eb1de846e383.png

937abc71dfe849969cd98be5aa1632c0.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值