调试原理

调试debug涉及调试者与被调试者间的关系建立,通过CreateProcess函数开启调试,利用DEBUG_PROCESS标志。调试过程中,创建DEBUG_OBJECT和Semaphore,存储在TEB中,并设置EPROCESS的DebugPort字段。WaitForDebugEvent用于捕获调试事件,而单步调试依赖x86架构的EFLAGS寄存器TF标志,控制执行与中断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

调试debug,就是两个进程之间建立起调试与被调试的关系,主要过程包括:

1、打开调试进程,就是CreateProcess等函数,设置标志位DEBUG_PROCESS或者DEUBG_ONLY_THIS_PROCESS,建立一个调试者与被调试者的关系。CreateProcess最终调用到NTDLL!DbgUiConnectToDbg,最终创建DEBUG_OBJECT调试端口对象和等待端口数据的信号量(Semaphore),把他们存到调试者当前线程TEB中的DbgSsReserved[0]和DbgSsReserved[1]中。并将端口对象句柄作为参数传入到内核进程管理器,内核中的进程创建函数会根据这个参数来设置EPROCESS中的DebugPort字段。当这个参数不为空时,找到这个句柄所对应的内核对象,并把他填入到EPROCESS结构中的DebugPort字段,如果为空,那么DebugPort字段也为NULL。PspCreateProcess函数在创建进程时会简历MmCreatePeb,进程PEB中的BeingDebugged字段的设置也就可以根据DebugPort来确定了。

这样调试进程和被调试进程就建立了调试关系了,并且可以通过调试端口对象进行通信。


2、Attach工作的机理与调试打开类似,通过调用DebugActiveProcess函数来简历调试关系。
1)首先也是调用DbgUiConnectToDbg函数,对调试者当前线程的TEB设置DbgSsReserved数组
2)API传入参数是进程ID,所以内部会调用ProcessIdToHandle,这个函数会调用OpenProcess函数,来获取进程的句柄。所以我们要Attach的进程权限要小于等于调试者。
3)NTDLL!DebugUiDebugActiveProcess将调试进程的句柄和调试对象的句柄传递给NtDebugActiveProcess,这个函数会通过进程句柄获取被调试者的EPROCESS结构,然后向调试对象发送虚假的调试事件,调用DebugkpSetProcessDebugObject函数将调试对象设置到的EPROCESS结构的DebugPort字段,并调用DbgkpMarkProcessPeb设置BeingDebugged字段。



3、调试过程就是在调试者(od)中,调用WaitForDebugEvent(OUT LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds);光从这个函数看,调试者和被调试者的关系无法显现?因为我们已经设置了DEBUG_OBJECT。


4、单步调试,就是通过x86架构下的EFLAGE寄存器的TF标志位,当这个标志为被置位TF=1,则被调试进程执行一条指令之后中断,并将TF=0重新置位。在中断处理中,重新设置TF=1,下一次执行一条指令之后,有继续中断......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值