首页
社区
课程
招聘
[原创]Windows内核学习笔记之调试(上)
发表于: 2022-1-2 21:14 11791

[原创]Windows内核学习笔记之调试(上)

2022-1-2 21:14
11791

既然是调试,那么必然存在调试进程和被调试进程。调试进程和被调试进程的关系可以通过函数CreateProcess来定义,该函数定义如下:

其中第六个参数dwCreationFlags的取值有两个重要的常量,分别为DEBUG_PROCESS和DEBUG_ONLY_THIS_PROCESS。DEBUG_PROCESS的作用是被创建的进程处于调试状态。如果一同指定DEBUG_ONLY_THIS_PROCESS的话,那么就只能调试被创建的进程,而不能调试被调试进程创建出来的进程。

另一种创建调试关系的方法是DebugActiveProcess函数,该函数定义如下:

这个函数的功能是将调试进程附加到被调试进程上。该函数的参数只有一个,该参数指定了被调试进程的进程PID。从函数名和参数可以看出,该函数是和一个已经被创建的进程来建立调试关系的。

想要让已建立关系的两个进程断开调试关系,可以使用如下的API:

该函数只有一个参数,就是被调试进程的ID号。使用该函数可以在不影响调试器进程和被调试进程的正常运行的情况下,将两者的关系接触。但是有一个前提,被调试进程需要处于运行状态,而不是中断状态。如果被调试进程处于中断状态时和调试进程解除调试关系,由于被调试进程无法运行而导致退出。

以下函数用来判断进程是否处于调试状态:

如果处于调试状态,该函数返回非0值,否则返回0。

可以通过如下函数来在当前进程中产生一个"int 3"断点异常,如果当前进程未处于调试状态,那么这个异常就会被系统接管,通常情况下会导致进程终止。

以下函数可以在指定进程中产生一个断点异常:

参数是要产生断点异常的进程句柄。

以下函数将使调试进程强制退出,将控制权转移至调试器。于ExitProcess不同的是,该函数在退出前会调试一个int 3断点:

参数是进程退出码。

调试器不断地对被调试目标进程进行捕获异常调试信息,有点类似于Win32应用程序地消息循环,但是又有所不同。调试器在捕获到调试信息后进行相应的处于,然后恢复线程,使之继续运行。

用来等待捕获被调试进程调试事件的函数如下:

调试器捕获到调试事件后,会对被调试的目标进程中产生调试事件的线程进行挂起。调试器对被调试目标进程进行相应的处理后,可以使用以下函数对先前被挂起的线程进行恢复:

另外还有一个比较常用的函数如下:

该函数可以将一个字符串传递给调试器显示,参数指向的就是要显示的以"00"作为结尾的字符串的指针。

当调试器与调试子系统建立连接时,调试子系统会为其创建一个DEBUG_OBJECT调试对象,并将其保存在调试器当前线程的线程环境块(TEB)偏移0x0F24的DbgSsReserved[1]字段中。该字段中保存的调试对象是这个调试器线程区别于其他普通线程的重要标志。由于TEB是用户层的数据结构,所以此时DbgSsReserved[1]中保存的其实是调试对象的句柄,而不是调试对象的地址。

调试对象通常由调试器进程创建,为了起到联系被调试进程和调试进程的作用,还需要将其设置到被调试进程EPROCESS结构的DebugPort字段中。DebugPort是内核进程对象结构的一个有关调试的重要字段。如果一个进程不在调试状态,那么该字段为NULL,否则,该字段是一个指针,指向的就是DEBUG_OBJECT调试对象。

调试对象的结构如下:

接下来通过查看DebugActiveProcess函数的实现来验证上述内容。该函数的调用非常简单,只需要将被调试进程的PID传递给函数,系统便会为调用这个API的进程与传入的参数PID指定的进程建立起调试关系。

函数一开始,会调用DbgUiConnectToDbg使调用进程与调试子系统建立连接

DbgUiConnectToDbg是ntdll.dll中的函数,该函数首先就判断TEB结构的DbgSsReserved[1]中是否已保存了调试对象句柄,如果保存了就会退出函数

如果没保存就会通过调用内核函数ZwCreateDebugObject来创建调试对象,此时第一个参数指向的就是TEB的DbgSsRevered[1],当函数成功创建调试对象以后,就会将句柄赋值到参数所指的地址中,然后退出函数

在内核函数ZwCreateObject中,首先会传入第一个参数是否可写以及Flags字段进行验证

如果验证通过,调用ObCreateObject来创建一个DbgkDebugObjectType的调试对象

如果成功创建调试对象,就会为创建的调试对象赋值

赋值完成以后,调用ObInsertObject将调试对象插入到句柄表中

最后将得到的句柄赋值到第一个参数指向的用户层地址,也就是TEB的DbgSsReserved[1],然后退出函数

也就是说,DbgUiConnectToDbg实质上就是创建了一个调试对象,然后将其赋值到TEB结构的DbgSsReserved[1]中。如果该函数成功调用,接下来就会调用ProcessIdToHandle函数来将被调试进程的PID转为句柄,并将其赋给esi。ProcessIdToHandle函数会通过调用内核函数NtOpenProcess来获得进程句柄,在进行这一步的时候就需要调试进程与被调试进程有同样或更高的权限,否则这一步就会失败。

成功获得调试对象句柄以后,就会调用DbgUiDebugActiveProcess函数,此时第一个参数esi指向的是被调试进程的句柄,而edi指向的是调试进程的句柄

DbgUiDebugActiveProcess是ntdll.dll中的一个函数,该函数会调用ZwDebugActiveProcess

内核函数

在内核函数中,首先会通过ObReferenceObjectByHandle来获取被调试进程的对象

判断被调试对象是否是当前进程或系统进程,如果是的话,函数就会返回错误

再次调用ObReferenceObjectByHandle来获取调试对象的对象地址

获取调试对象以后,会调用DbgkpSetProcessDebugObject函数,此时esi保存的是被调试进程的对象地址,而[ebp+Process]保存的是调试对象的地址

DbgkpSetProcessDebugObject最重要的代码就是判断调试进程的DebugPort是否保存了调试对象,如果没保存,就将解析得到调试对象地址赋值到DebugPort中

当ntdll.dll中的DbgUiDebugActiveProcess函数调用ZwDebugProcess函数返回以后,就会调用函数DbgUiIssueRemoteBreakin在被调试进程中创建中断线程,使其可以中断到调试器中,随后退出函数

而DebugActiveProcess函数返回以后,就会调用NtClose关闭被调试进程句柄,再退出函数

在调试进程与被调试进程建立连接的过程中会创建一个调试对象,被调试进程对象的DebugPort字段保存了调试对象的地址,调试进程的调试线程的线程环境块(TEB)的偏移0xF24DbgSsReserved[1]中保存了调试对象的句柄

为了让调试进程得知被调试进程的状态,内核会将被调试进程所有的调试消息都收集起来发送给调试子系统。调试消息用DBGKM_APIMSG结构描述,该结构定义如下:

不同的消息会在内核执行不同函数的时候被采集起来,具体情况如下:

这些不同的Dbgk采集例程会根据当前进程的DebugPort字段来判断是否处于被调试状态。如果不是,便会忽略这次调用;如果处于调试状态,便会产生一个DBGKM_APIMSG结构,该结构的定义如下:

其中联合体u根据消息类型的不同而不同,用来描述消息参数和详细信息。

接下来以DbgkForwardException函数为例,体会上述过程。该函数原型如下:

函数首先会对一些字段进行填充,然后判断是否是要发送给调试端口

如果是调试端口,接下来就会判断DebugPort字段是否存在,也就是是否存在调试器

如果存在调试调试器,就会继续填充字段

调用DbgkpSendApiMessage将结构体发送给调试子系统

对函数的返回结果以及ReturnedStatus进行判断

如果验证通过,则将返回值赋为1,然后退出函数

所有的调试消息的采集例程的代码主要的执行内容都是以下这几个步骤:

判断是否存在调试器,也就是DebugPort是否为空

填充DBGKM_APIMSG结构

将DBGKM_APIMSG结构的作为参数,调用DbgkpSendApiMessage来讲调试消息发送给调试子系统

最大的区别就是DBGKM_APIMSG结构的联合体u中保存的数据的不同

上面提到通过DbgkpSendApiMessage来将调试消息发送给调试子系统,该函数定义如下:

函数首先就会判断参数SuspendProcess,如果为TRUE就会调用DbgkpSuspendProcess,并将返回值赋给参数SuspendProcess

而DbgkpSuspendProcess则是通过KeFreezeAllThreads来冻结线程

接下来函数会调用DbgkpQueueMessage来发送调试消息

在根据前面是否成功将线程冻结来觉得是否要恢复线程

DbgkpQueueMessage的作用是向一个调试对象的消息队列中追加调试事件。而调试消息队列的每一个节点都是DBGKM_DEBUG_EVENT结构,该结构定义如下:

因此,DbgkpQueueMessage函数首先就是申请一块内存用来保存这些数据,但是在申请之前将参数Event的数据与2进行与操作以后保存在局部变量var_Event中,也就是判断参数中是否有不需等待(NOWAIT,值为2)的标志

通过申请的内存来对一些字段进行赋值

将调试对象赋值给参数Event的地址,将调试消息类型赋值给eax

根据调试消息类型进行相应的操作

继续为成员赋值

继续赋值,并判断DebugPort是否存在调试对象,如果不存在则返回错误,此时Event中保存的是DebugPort所保存的调试对象的地址

接下来就会将生成并且赋值好的DBGKM_DEBUG_EVENT插入到调试对象EventList中,判断局部变量var_Event的值是否为0,该值是在函数开始的时候,参数Event的值与2进行与操作的结果,如果为0,则说明Event中不带有不需等待的(NOWAIT)标志

如果Event参数不带有无需等待的标志,接下来就会通过调用KeSetEvent来设置调试对象

并通过KeWaitForSingleObject来等待ContinueEvent对象

当调试器处理好对象后,它会设置ContinueEvent对象,此时处于等待状态的被调试进程就会被唤醒,继续运行。

函数会将DBGKM_DEBUG_EVENT中的ApiMsg赋值到参数ApiMsg中,并取出Status将其赋值到参数Thread的地址

将参数Thread中保存的数据作为返回值返回,也就是将Status返回

下篇:Windows内核学习笔记之调试(下)

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);
BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);
 
BOOL WINAPI DebugActiveProcess(
  __in  DWORD dwProcessId
);
BOOL WINAPI DebugActiveProcess(
  __in  DWORD dwProcessId
);
 
BOOL WINAPI DebugActiveProcessStop(
  __in  DWORD dwProcessId
);
BOOL WINAPI DebugActiveProcessStop(
  __in  DWORD dwProcessId
);
BOOL WINAPI IsDebuggerPresent(void);
BOOL WINAPI IsDebuggerPresent(void);
void WINAPI DebugBreak(void);
void WINAPI DebugBreak(void);
BOOL WINAPI DebugBreakProcess(
  __in  HANDLE Process
);
BOOL WINAPI DebugBreakProcess(
  __in  HANDLE Process
);
 
void WINAPI FatalExit(
  __in  int ExitCode
);
void WINAPI FatalExit(
  __in  int ExitCode
);
 
BOOL WINAPI WaitForDebugEvent(
  __out  LPDEBUG_EVENT lpDebugEvent,
  __in   DWORD dwMilliseconds
);
BOOL WINAPI WaitForDebugEvent(
  __out  LPDEBUG_EVENT lpDebugEvent,
  __in   DWORD dwMilliseconds
);
参数 含义
lpDebugEvent 用于保存调试事件
dwMilliseconds 用于指定超时的时间,如果是INFINITE则表示无线等待
 
BOOL WINAPI ContinueDebugEvent(
  __in  DWORD dwProcessId,
  __in  DWORD dwThreadId,
  __in  DWORD dwContinueStatus
);
BOOL WINAPI ContinueDebugEvent(
  __in  DWORD dwProcessId,
  __in  DWORD dwThreadId,
  __in  DWORD dwContinueStatus
);
参数 含义
dwProcessId 表示被调试进程的进程标识符
dwThreadId 表示准备恢复挂机线程的线程标识符
dwContinueStatus 该参数指定了该线程以何种方式继续,其取值为DEBUG_EXCEPTION_NOT_HANDLED和DBG_CONTINUE。对于这两个值来说,通常情况下并没有什么差别。但是当遇到调试事件中的调试码为EXCEPTION_DEBUG_EVENT时,这两个常量会有不同的动作。如果使用前者,则调试器进程会忽略该异常,Windows会使用被调试进程的异常处理函数对异常进行处理;如果使用后者,那么需要调试器进程对异常进行处理 ,然后继续运行
 
void WINAPI OutputDebugString(
  __in_opt  LPCTSTR lpOutputString
);
void WINAPI OutputDebugString(
  __in_opt  LPCTSTR lpOutputString
);
 
 
typedef struct _DEBUG_OBJECT
{
    KEVENT EventsPresent;
    FAST_MUTEX Mutex;
    LIST_ENTRY StateEventListEntry;
    ULONG Flags;
}DEBUG_OBJECT, *PDEBUG_OBJECT;
typedef struct _DEBUG_OBJECT
{
    KEVENT EventsPresent;
    FAST_MUTEX Mutex;
    LIST_ENTRY StateEventListEntry;
    ULONG Flags;
}DEBUG_OBJECT, *PDEBUG_OBJECT;
偏移 名称 作用
0x00 EventsPresent 用于指示调试事件发生的事件对象,用来同步调试器进程和被调试进程,调试子系统服务器通过设置此事件来通知调试器读取消息队列中的调试信息
0x10 Mutex 用于同步的互斥对象,用来锁定对这个数据结构的访问,以防止对各线程同时读写造成数据错误
0x30 StateEventListEntry 保存调试事件的链表,被称为调试消息队列
0x38 Flags 包含多个标志位,比如,位1代表结束调试会话时是否终止被调试进程
 
 
.text:7C85B0FB ; BOOL __stdcall DebugActiveProcess(DWORD dwProcessId)
.text:7C85B0FB                 public _DebugActiveProcess@4
.text:7C85B0FB _DebugActiveProcess@4 proc near         ; DATA XREF: .text:off_7C802654↑o
.text:7C85B0FB
.text:7C85B0FB dwProcessId     = dword ptr  8
.text:7C85B0FB
.text:7C85B0FB                 mov     edi, edi
.text:7C85B0FD                 push    ebp
.text:7C85B0FE                 mov     ebp, esp
.text:7C85B100                 call    _DbgUiConnectToDbg@0 ; DbgUiConnectToDbg()
.text:7C85B105                 test    eax, eax
.text:7C85B107                 jge     short loc_7C85B113 ; 调用成功则跳转
.text:7C85B109                 push    eax             ; Status
.text:7C85B10A                 call    _BaseSetLastNTError@4 ; BaseSetLastNTError(x)
.text:7C85B10F                 xor     eax, eax
.text:7C85B111                 jmp     short loc_7C85B145
.text:7C85B0FB ; BOOL __stdcall DebugActiveProcess(DWORD dwProcessId)
.text:7C85B0FB                 public _DebugActiveProcess@4
.text:7C85B0FB _DebugActiveProcess@4 proc near         ; DATA XREF: .text:off_7C802654↑o
.text:7C85B0FB
.text:7C85B0FB dwProcessId     = dword ptr  8
.text:7C85B0FB
.text:7C85B0FB                 mov     edi, edi
.text:7C85B0FD                 push    ebp
.text:7C85B0FE                 mov     ebp, esp
.text:7C85B100                 call    _DbgUiConnectToDbg@0 ; DbgUiConnectToDbg()
.text:7C85B105                 test    eax, eax
.text:7C85B107                 jge     short loc_7C85B113 ; 调用成功则跳转
.text:7C85B109                 push    eax             ; Status
.text:7C85B10A                 call    _BaseSetLastNTError@4 ; BaseSetLastNTError(x)
.text:7C85B10F                 xor     eax, eax
.text:7C85B111                 jmp     short loc_7C85B145
.text:7C96FEF1                 public DbgUiConnectToDbg
.text:7C96FEF1 DbgUiConnectToDbg proc near             ; DATA XREF: .text:off_7C923428↑o
.text:7C96FEF1
.text:7C96FEF1 var_ObjAttributes= _OBJECT_ATTRIBUTES ptr -18h
.text:7C96FEF1
.text:7C96FEF1                 mov     edi, edi
.text:7C96FEF3                 push    ebp
.text:7C96FEF4                 mov     ebp, esp
.text:7C96FEF6                 sub     esp, 18h
.text:7C96FEF9                 xor     ecx, ecx
.text:7C96FEFB                 mov     eax, large fs:18h ; 获取TEB地址
.text:7C96FF01                 cmp     [eax+0F24h], ecx ; 判断DbgSsReserved[1]中是否保存了内容
.text:7C96FF07                 jnz     short loc_7C96FF3D ; 如果保存了则退出函数
.text:7C96FEF1                 public DbgUiConnectToDbg
.text:7C96FEF1 DbgUiConnectToDbg proc near             ; DATA XREF: .text:off_7C923428↑o
.text:7C96FEF1
.text:7C96FEF1 var_ObjAttributes= _OBJECT_ATTRIBUTES ptr -18h
.text:7C96FEF1
.text:7C96FEF1                 mov     edi, edi
.text:7C96FEF3                 push    ebp
.text:7C96FEF4                 mov     ebp, esp
.text:7C96FEF6                 sub     esp, 18h
.text:7C96FEF9                 xor     ecx, ecx
.text:7C96FEFB                 mov     eax, large fs:18h ; 获取TEB地址
.text:7C96FF01                 cmp     [eax+0F24h], ecx ; 判断DbgSsReserved[1]中是否保存了内容
.text:7C96FF07                 jnz     short loc_7C96FF3D ; 如果保存了则退出函数
.text:7C96FF09                 mov     [ebp+var_ObjAttributes.Length], 18h
.text:7C96FF10                 mov     [ebp+var_ObjAttributes.RootDirectory], ecx
.text:7C96FF13                 mov     [ebp+var_ObjAttributes.Attributes], ecx
.text:7C96FF16                 mov     [ebp+var_ObjAttributes.ObjectName], ecx
.text:7C96FF19                 mov     [ebp+var_ObjAttributes.SecurityDescriptor], ecx
.text:7C96FF1C                 mov     [ebp+var_ObjAttributes.SecurityQualityOfService], ecx
.text:7C96FF1F                 mov     eax, large fs:18h ; 将TEB地址赋给eax
.text:7C96FF25                 push    1
.text:7C96FF27                 lea     ecx, [ebp+var_ObjAttributes]
.text:7C96FF2A                 push    ecx
.text:7C96FF2B                 push    1F000Fh
.text:7C96FF30                 add     eax, 0F24h      ; eax指向DbgSsReserved[1]的地址
.text:7C96FF35                 push    eax
.text:7C96FF36                 call    ZwCreateDebugObject ; 创建DebugObject对象
.text:7C96FF3B                 mov     ecx, eax
.text:7C96FF3D
.text:7C96FF3D loc_7C96FF3D:                           ; CODE XREF: DbgUiConnectToDbg+16↑j
.text:7C96FF3D                 mov     eax, ecx
.text:7C96FF3F                 leave
.text:7C96FF40                 retn
.text:7C96FF40 DbgUiConnectToDbg endp
.text:7C96FF09                 mov     [ebp+var_ObjAttributes.Length], 18h
.text:7C96FF10                 mov     [ebp+var_ObjAttributes.RootDirectory], ecx
.text:7C96FF13                 mov     [ebp+var_ObjAttributes.Attributes], ecx
.text:7C96FF16                 mov     [ebp+var_ObjAttributes.ObjectName], ecx
.text:7C96FF19                 mov     [ebp+var_ObjAttributes.SecurityDescriptor], ecx
.text:7C96FF1C                 mov     [ebp+var_ObjAttributes.SecurityQualityOfService], ecx
.text:7C96FF1F                 mov     eax, large fs:18h ; 将TEB地址赋给eax
.text:7C96FF25                 push    1
.text:7C96FF27                 lea     ecx, [ebp+var_ObjAttributes]
.text:7C96FF2A                 push    ecx
.text:7C96FF2B                 push    1F000Fh
.text:7C96FF30                 add     eax, 0F24h      ; eax指向DbgSsReserved[1]的地址
.text:7C96FF35                 push    eax
.text:7C96FF36                 call    ZwCreateDebugObject ; 创建DebugObject对象
.text:7C96FF3B                 mov     ecx, eax
.text:7C96FF3D
.text:7C96FF3D loc_7C96FF3D:                           ; CODE XREF: DbgUiConnectToDbg+16↑j
.text:7C96FF3D                 mov     eax, ecx
.text:7C96FF3F                 leave
.text:7C96FF40                 retn
.text:7C96FF40 DbgUiConnectToDbg endp
PAGE:0058B2B6 ; NTSTATUS __stdcall NtCreateDebugObject(PHANDLE DebugHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG Flags)
PAGE:0058B2B6 _NtCreateDebugObject@16 proc near       ; DATA XREF: .text:0040D8A4↑o
PAGE:0058B2B6
PAGE:0058B2B6 var_2C          = dword ptr -2Ch
PAGE:0058B2B6 var_28          = dword ptr -28h
PAGE:0058B2B6 Object          = dword ptr -24h
PAGE:0058B2B6 PreviousMode    = byte ptr -20h
PAGE:0058B2B6 Handle          = dword ptr -1Ch
PAGE:0058B2B6 ms_exc          = CPPEH_RECORD ptr -18h
PAGE:0058B2B6 DebugHandle     = dword ptr  8
PAGE:0058B2B6 DesiredAccess   = dword ptr  0Ch
PAGE:0058B2B6 ObjectAttributes= dword ptr  10h
PAGE:0058B2B6 Flags           = dword ptr  14h
PAGE:0058B2B6                 push    1Ch
PAGE:0058B2B8                 push    offset stru_4585F0
PAGE:0058B2BD                 call    __SEH_prolog
PAGE:0058B2C2                 mov     eax, large fs:124h
PAGE:0058B2C8                 mov     al, [eax+_KTHREAD.PreviousMode]
PAGE:0058B2CE                 mov     [ebp+PreviousMode], al
PAGE:0058B2D1                 xor     ebx, ebx
PAGE:0058B2D6                 mov     edi, [ebp+DebugHandle]
PAGE:0058B2D9                 cmp     al, bl
PAGE:0058B2DB                 jz      short loc_58B2EC
PAGE:0058B2DD                 mov     eax, _MmUserProbeAddress
PAGE:0058B2E2                 cmp     edi, eax
PAGE:0058B2E4                 jb      short loc_58B2E8
PAGE:0058B2E6                 mov     [eax], ebx
PAGE:0058B2E8
PAGE:0058B2E8 loc_58B2E8:                             ; CODE XREF: NtCreateDebugObject(x,x,x,x)+2E↑j
PAGE:0058B2E8                 mov     eax, [edi]
PAGE:0058B2EA                 mov     [edi], eax
PAGE:0058B2EC
PAGE:0058B2EC loc_58B2EC:                             ; CODE XREF: NtCreateDebugObject(x,x,x,x)+25↑j
PAGE:0058B2EC                 mov     [edi], ebx
PAGE:0058B2F2                 test    [ebp+Flags], 0FFFFFFFEh
PAGE:0058B2F9                 jz      short loc_58B305
PAGE:0058B2FB                 mov     eax, STATUS_INVALID_PARAMETER
PAGE:0058B300                 jmp     loc_58B3D8
PAGE:0058B2B6 ; NTSTATUS __stdcall NtCreateDebugObject(PHANDLE DebugHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG Flags)
PAGE:0058B2B6 _NtCreateDebugObject@16 proc near       ; DATA XREF: .text:0040D8A4↑o
PAGE:0058B2B6
PAGE:0058B2B6 var_2C          = dword ptr -2Ch
PAGE:0058B2B6 var_28          = dword ptr -28h
PAGE:0058B2B6 Object          = dword ptr -24h
PAGE:0058B2B6 PreviousMode    = byte ptr -20h
PAGE:0058B2B6 Handle          = dword ptr -1Ch
PAGE:0058B2B6 ms_exc          = CPPEH_RECORD ptr -18h
PAGE:0058B2B6 DebugHandle     = dword ptr  8
PAGE:0058B2B6 DesiredAccess   = dword ptr  0Ch
PAGE:0058B2B6 ObjectAttributes= dword ptr  10h
PAGE:0058B2B6 Flags           = dword ptr  14h
PAGE:0058B2B6                 push    1Ch
PAGE:0058B2B8                 push    offset stru_4585F0
PAGE:0058B2BD                 call    __SEH_prolog
PAGE:0058B2C2                 mov     eax, large fs:124h
PAGE:0058B2C8                 mov     al, [eax+_KTHREAD.PreviousMode]
PAGE:0058B2CE                 mov     [ebp+PreviousMode], al
PAGE:0058B2D1                 xor     ebx, ebx
PAGE:0058B2D6                 mov     edi, [ebp+DebugHandle]
PAGE:0058B2D9                 cmp     al, bl
PAGE:0058B2DB                 jz      short loc_58B2EC
PAGE:0058B2DD                 mov     eax, _MmUserProbeAddress
PAGE:0058B2E2                 cmp     edi, eax
PAGE:0058B2E4                 jb      short loc_58B2E8
PAGE:0058B2E6                 mov     [eax], ebx
PAGE:0058B2E8
PAGE:0058B2E8 loc_58B2E8:                             ; CODE XREF: NtCreateDebugObject(x,x,x,x)+2E↑j
PAGE:0058B2E8                 mov     eax, [edi]
PAGE:0058B2EA                 mov     [edi], eax
PAGE:0058B2EC
PAGE:0058B2EC loc_58B2EC:                             ; CODE XREF: NtCreateDebugObject(x,x,x,x)+25↑j
PAGE:0058B2EC                 mov     [edi], ebx
PAGE:0058B2F2                 test    [ebp+Flags], 0FFFFFFFEh
PAGE:0058B2F9                 jz      short loc_58B305
PAGE:0058B2FB                 mov     eax, STATUS_INVALID_PARAMETER
PAGE:0058B300                 jmp     loc_58B3D8
PAGE:0058B305 loc_58B305:                             ; CODE XREF: NtCreateDebugObject(x,x,x,x)+43↑j
PAGE:0058B305                 lea     eax, [ebp+Object]
PAGE:0058B308                 push    eax             ; Object
PAGE:0058B309                 push    ebx             ; NonPagedPoolCharge
PAGE:0058B30A                 push    ebx             ; PagePoolCharge
PAGE:0058B30B                 push    3Ch             ; ObjectBodySize
PAGE:0058B30D                 push    ebx             ; ParentContext
PAGE:0058B30E                 push    dword ptr [ebp+PreviousMode] ; OwnershipMode
PAGE:0058B311                 push    [ebp+ObjectAttributes] ; ObjectAttributes
PAGE:0058B314                 push    _DbgkDebugObjectType ; ObjectType
PAGE:0058B31A                 push    dword ptr [ebp+PreviousMode] ; PreviousMode
PAGE:0058B31D                 call    _ObCreateObject@36 ; ObCreateObject(x,x,x,x,x,x,x,x,x)
PAGE:0058B322                 cmp     eax, ebx
PAGE:0058B324                 jl      loc_58B3D8
PAGE:0058B305 loc_58B305:                             ; CODE XREF: NtCreateDebugObject(x,x,x,x)+43↑j
PAGE:0058B305                 lea     eax, [ebp+Object]
PAGE:0058B308                 push    eax             ; Object
PAGE:0058B309                 push    ebx             ; NonPagedPoolCharge
PAGE:0058B30A                 push    ebx             ; PagePoolCharge
PAGE:0058B30B                 push    3Ch             ; ObjectBodySize
PAGE:0058B30D                 push    ebx             ; ParentContext
PAGE:0058B30E                 push    dword ptr [ebp+PreviousMode] ; OwnershipMode
PAGE:0058B311                 push    [ebp+ObjectAttributes] ; ObjectAttributes
PAGE:0058B314                 push    _DbgkDebugObjectType ; ObjectType
PAGE:0058B31A                 push    dword ptr [ebp+PreviousMode] ; PreviousMode
PAGE:0058B31D                 call    _ObCreateObject@36 ; ObCreateObject(x,x,x,x,x,x,x,x,x)
PAGE:0058B322                 cmp     eax, ebx
PAGE:0058B324                 jl      loc_58B3D8
PAGE:0058B32A                 mov     eax, [ebp+Object] ; 将调试对象地址赋给eax
PAGE:0058B32D                 xor     esi, esi
PAGE:0058B32F                 inc     esi
PAGE:0058B330                 mov     [eax+_DEBUG_OBJECT.Mutex.Count], esi
PAGE:0058B333                 mov     [eax+_DEBUG_OBJECT.Mutex.Owner], ebx
PAGE:0058B336                 mov     [eax+_DEBUG_OBJECT.Mutex.Contention], ebx
PAGE:0058B339                 mov     [eax+_DEBUG_OBJECT.Mutex.Event.Header.Type], 1
PAGE:0058B33D                 mov     [eax+_DEBUG_OBJECT.Mutex.Event.Header.Size], 4
PAGE:0058B341                 mov     [eax+_DEBUG_OBJECT.Mutex.Event.Header.SignalState], ebx
PAGE:0058B344                 lea     ecx, [eax+_DEBUG_OBJECT.Mutex.Event.Header.WaitListHead]
PAGE:0058B347                 mov     [ecx+LIST_ENTRY.Blink], ecx
PAGE:0058B34A                 mov     [ecx+LIST_ENTRY.Flink], ecx
PAGE:0058B34C                 lea     ecx, [eax+_DEBUG_OBJECT.EventList]
PAGE:0058B34F                 mov     [ecx+LIST_ENTRY.Blink], ecx
PAGE:0058B352                 mov     [ecx+LIST_ENTRY.Flink], ecx
PAGE:0058B354                 mov     [eax+_DEBUG_OBJECT.EventsPresent.Header.Type], bl
PAGE:0058B356                 mov     [eax+_DEBUG_OBJECT.EventsPresent.Header.Size], 4
PAGE:0058B35A                 mov     [eax+_DEBUG_OBJECT.EventsPresent.Header.SignalState], ebx
PAGE:0058B35D                 lea     ecx, [eax+_DEBUG_OBJECT.EventsPresent.Header.WaitListHead]
PAGE:0058B360                 mov     [ecx+LIST_ENTRY.Blink], ecx
PAGE:0058B363                 mov     [ecx+LIST_ENTRY.Flink], ecx
PAGE:0058B365                 movzx   ecx, byte ptr [ebp+Flags]
PAGE:0058B369                 and     ecx, esi
PAGE:0058B36B                 shl     ecx, 1
PAGE:0058B36D                 mov     [eax+_DEBUG_OBJECT.Flags], ecx
PAGE:0058B32A                 mov     eax, [ebp+Object] ; 将调试对象地址赋给eax
PAGE:0058B32D                 xor     esi, esi
PAGE:0058B32F                 inc     esi
PAGE:0058B330                 mov     [eax+_DEBUG_OBJECT.Mutex.Count], esi
PAGE:0058B333                 mov     [eax+_DEBUG_OBJECT.Mutex.Owner], ebx
PAGE:0058B336                 mov     [eax+_DEBUG_OBJECT.Mutex.Contention], ebx
PAGE:0058B339                 mov     [eax+_DEBUG_OBJECT.Mutex.Event.Header.Type], 1
PAGE:0058B33D                 mov     [eax+_DEBUG_OBJECT.Mutex.Event.Header.Size], 4
PAGE:0058B341                 mov     [eax+_DEBUG_OBJECT.Mutex.Event.Header.SignalState], ebx
PAGE:0058B344                 lea     ecx, [eax+_DEBUG_OBJECT.Mutex.Event.Header.WaitListHead]
PAGE:0058B347                 mov     [ecx+LIST_ENTRY.Blink], ecx
PAGE:0058B34A                 mov     [ecx+LIST_ENTRY.Flink], ecx
PAGE:0058B34C                 lea     ecx, [eax+_DEBUG_OBJECT.EventList]
PAGE:0058B34F                 mov     [ecx+LIST_ENTRY.Blink], ecx
PAGE:0058B352                 mov     [ecx+LIST_ENTRY.Flink], ecx
PAGE:0058B354                 mov     [eax+_DEBUG_OBJECT.EventsPresent.Header.Type], bl
PAGE:0058B356                 mov     [eax+_DEBUG_OBJECT.EventsPresent.Header.Size], 4
PAGE:0058B35A                 mov     [eax+_DEBUG_OBJECT.EventsPresent.Header.SignalState], ebx
PAGE:0058B35D                 lea     ecx, [eax+_DEBUG_OBJECT.EventsPresent.Header.WaitListHead]
PAGE:0058B360                 mov     [ecx+LIST_ENTRY.Blink], ecx
PAGE:0058B363                 mov     [ecx+LIST_ENTRY.Flink], ecx
PAGE:0058B365                 movzx   ecx, byte ptr [ebp+Flags]
PAGE:0058B369                 and     ecx, esi
PAGE:0058B36B                 shl     ecx, 1
PAGE:0058B36D                 mov     [eax+_DEBUG_OBJECT.Flags], ecx
PAGE:0058B370                 lea     ecx, [ebp+Handle]
PAGE:0058B373                 push    ecx             ; Handle
PAGE:0058B374                 push    ebx             ; NewObject
PAGE:0058B375                 push    ebx             ; ObjectPointerBias
PAGE:0058B376                 push    [ebp+DesiredAccess] ; DesiredAccess
PAGE:0058B379                 push    ebx             ; PACCESS_STATE
PAGE:0058B37A                 push    eax             ; Object
PAGE:0058B37B                 call    _ObInsertObject@24 ; ObInsertObject(x,x,x,x,x,x)
PAGE:0058B380                 cmp     eax, ebx
PAGE:0058B382                 jl      short loc_58B3D8
PAGE:0058B370                 lea     ecx, [ebp+Handle]
PAGE:0058B373                 push    ecx             ; Handle
PAGE:0058B374                 push    ebx             ; NewObject
PAGE:0058B375                 push    ebx             ; ObjectPointerBias
PAGE:0058B376                 push    [ebp+DesiredAccess] ; DesiredAccess
PAGE:0058B379                 push    ebx             ; PACCESS_STATE
PAGE:0058B37A                 push    eax             ; Object
PAGE:0058B37B                 call    _ObInsertObject@24 ; ObInsertObject(x,x,x,x,x,x)
PAGE:0058B380                 cmp     eax, ebx
PAGE:0058B382                 jl      short loc_58B3D8
PAGE:0058B387                 mov     ecx, [ebp+Handle]
PAGE:0058B38A                 mov     [edi], ecx      ; 将得到的句柄赋值到DebugHandle指定用户层地址
PAGE:0058B38C                 jmp     short loc_58B3AE
PAGE:0058B387                 mov     ecx, [ebp+Handle]
PAGE:0058B38A                 mov     [edi], ecx      ; 将得到的句柄赋值到DebugHandle指定用户层地址
PAGE:0058B38C                 jmp     short loc_58B3AE
.text:7C85B113 loc_7C85B113:                           ; CODE XREF: DebugActiveProcess(x)+C↑j
.text:7C85B113                 push    esi
.text:7C85B114                 push    [ebp+dwProcessId] ; ProcessHandle
.text:7C85B117                 call    _ProcessIdToHandle@4 ; ProcessIdToHandle(x)
.text:7C85B11C                 mov     esi, eax        ; 将句柄赋给esi
.text:7C85B11E                 test    esi, esi
.text:7C85B120                 jz      short loc_7C85B144
.text:7C85B113 loc_7C85B113:                           ; CODE XREF: DebugActiveProcess(x)+C↑j
.text:7C85B113                 push    esi
.text:7C85B114                 push    [ebp+dwProcessId] ; ProcessHandle
.text:7C85B117                 call    _ProcessIdToHandle@4 ; ProcessIdToHandle(x)
.text:7C85B11C                 mov     esi, eax        ; 将句柄赋给esi
.text:7C85B11E                 test    esi, esi
.text:7C85B120                 jz      short loc_7C85B144
.text:7C85B122                 push    edi
.text:7C85B123                 push    esi             ; Process
.text:7C85B124                 call    _DbgUiDebugActiveProcess@4
.text:7C85B122                 push    edi
.text:7C85B123                 push    esi             ; Process
.text:7C85B124                 call    _DbgUiDebugActiveProcess@4
 
.text:7C970082                 public DbgUiDebugActiveProcess
.text:7C970082 DbgUiDebugActiveProcess proc near       ; DATA XREF: .text:off_7C923428↑o
.text:7C970082
.text:7C970082 arg_ProcessHandle= dword ptr  8
.text:7C970082
.text:7C970082                 mov     edi, edi
.text:7C970084                 push    ebp
.text:7C970085                 mov     ebp, esp
.text:7C970087                 push    esi
.text:7C970088                 mov     eax, large fs:18h ; 获取TEB地址
.text:7C97008E                 push    dword ptr [eax+0F24h] ; 将调试对象句柄入栈
.text:7C970094                 push    [ebp+arg_ProcessHandle]
.text:7C970097                 call    ZwDebugActiveProcess
.text:7C97009C                 mov     esi, eax
.text:7C97009E                 test    esi, esi
.text:7C9700A0                 jl      short loc_7C9700B8
.text:7C970082                 public DbgUiDebugActiveProcess
.text:7C970082 DbgUiDebugActiveProcess proc near       ; DATA XREF: .text:off_7C923428↑o
.text:7C970082
.text:7C970082 arg_ProcessHandle= dword ptr  8
.text:7C970082
.text:7C970082                 mov     edi, edi
.text:7C970084                 push    ebp
.text:7C970085                 mov     ebp, esp
.text:7C970087                 push    esi
.text:7C970088                 mov     eax, large fs:18h ; 获取TEB地址
.text:7C97008E                 push    dword ptr [eax+0F24h] ; 将调试对象句柄入栈
.text:7C970094                 push    [ebp+arg_ProcessHandle]
.text:7C970097                 call    ZwDebugActiveProcess
.text:7C97009C                 mov     esi, eax
.text:7C97009E                 test    esi, esi
.text:7C9700A0                 jl      short loc_7C9700B8
PAGE:0058C431 ; NTSTATUS __stdcall NtDebugActiveProcess(HANDLE Process, HANDLE DebugObject)
PAGE:0058C431 _NtDebugActiveProcess@8 proc near       ; DATA XREF: .text:0040D904↑o
PAGE:0058C431
PAGE:0058C431 AccessMode      = byte ptr -4
PAGE:0058C431 Process         = dword ptr  8
PAGE:0058C431 DebugObject     = dword ptr  0Ch
PAGE:0058C431
PAGE:0058C431                 mov     edi, edi
PAGE:0058C433                 push    ebp
PAGE:0058C434                 mov     ebp, esp
PAGE:0058C436                 push    ecx
PAGE:0058C437                 mov     eax, large fs:124h ; 获取线程对象地址
PAGE:0058C43D                 mov     al, [eax+_KTHREAD.PreviousMode]
PAGE:0058C443                 push    0               ; HandleInformation
PAGE:0058C445                 mov     [ebp+AccessMode], al
PAGE:0058C448                 lea     eax, [ebp+Process] ; 保存被调试进程对象地址
PAGE:0058C44B                 push    eax             ; Object
PAGE:0058C44C                 push    dword ptr [ebp+AccessMode] ; AccessMode
PAGE:0058C44F                 push    _PsProcessType  ; ObjectType
PAGE:0058C455                 push    PROCESS_SUSPEND_RESUME ; DesiredAccess
PAGE:0058C45A                 push    [ebp+Process]   ; Handle
PAGE:0058C45D                 call    _ObReferenceObjectByHandle@24 ; ObReferenceObjectByHandle(x,x,x,x,x,x)
PAGE:0058C462                 test    eax, eax
PAGE:0058C464                 jl      locret_58C4F8
PAGE:0058C431 ; NTSTATUS __stdcall NtDebugActiveProcess(HANDLE Process, HANDLE DebugObject)
PAGE:0058C431 _NtDebugActiveProcess@8 proc near       ; DATA XREF: .text:0040D904↑o
PAGE:0058C431
PAGE:0058C431 AccessMode      = byte ptr -4
PAGE:0058C431 Process         = dword ptr  8
PAGE:0058C431 DebugObject     = dword ptr  0Ch
PAGE:0058C431
PAGE:0058C431                 mov     edi, edi
PAGE:0058C433                 push    ebp
PAGE:0058C434                 mov     ebp, esp
PAGE:0058C436                 push    ecx
PAGE:0058C437                 mov     eax, large fs:124h ; 获取线程对象地址
PAGE:0058C43D                 mov     al, [eax+_KTHREAD.PreviousMode]
PAGE:0058C443                 push    0               ; HandleInformation
PAGE:0058C445                 mov     [ebp+AccessMode], al
PAGE:0058C448                 lea     eax, [ebp+Process] ; 保存被调试进程对象地址
PAGE:0058C44B                 push    eax             ; Object
PAGE:0058C44C                 push    dword ptr [ebp+AccessMode] ; AccessMode
PAGE:0058C44F                 push    _PsProcessType  ; ObjectType
PAGE:0058C455                 push    PROCESS_SUSPEND_RESUME ; DesiredAccess
PAGE:0058C45A                 push    [ebp+Process]   ; Handle
PAGE:0058C45D                 call    _ObReferenceObjectByHandle@24 ; ObReferenceObjectByHandle(x,x,x,x,x,x)
PAGE:0058C462                 test    eax, eax
PAGE:0058C464                 jl      locret_58C4F8
PAGE:0058C46A                 push    ebx
PAGE:0058C46B                 push    esi
PAGE:0058C46C                 mov     eax, large fs:124h
PAGE:0058C472                 mov     esi, [ebp+Process] ; 将被调试进程对象地址赋给esi
PAGE:0058C475                 cmp     esi, [eax+_KTHREAD.ApcState.Process] ; 判断是否为当前进程
PAGE:0058C478                 jz      short loc_58C4E8
PAGE:0058C47A                 cmp     esi, _PsInitialSystemProcess ; 判断是否为系统进程
PAGE:0058C480                 jz      short loc_58C4E8
PAGE:0058C46A                 push    ebx
PAGE:0058C46B                 push    esi
PAGE:0058C46C                 mov     eax, large fs:124h
PAGE:0058C472                 mov     esi, [ebp+Process] ; 将被调试进程对象地址赋给esi
PAGE:0058C475                 cmp     esi, [eax+_KTHREAD.ApcState.Process] ; 判断是否为当前进程
PAGE:0058C478                 jz      short loc_58C4E8
PAGE:0058C47A                 cmp     esi, _PsInitialSystemProcess ; 判断是否为系统进程
PAGE:0058C480                 jz      short loc_58C4E8
PAGE:0058C482                 push    0               ; HandleInformation
PAGE:0058C484                 lea     eax, [ebp+Process] ; 保存调试对象的地址
PAGE:0058C487                 push    eax             ; Object
PAGE:0058C488                 push    dword ptr [ebp+AccessMode] ; AccessMode
PAGE:0058C48B                 push    _DbgkDebugObjectType ; ObjectType
PAGE:0058C491                 push    2               ; DesiredAccess
PAGE:0058C493                 push    [ebp+DebugObject] ; Handle
PAGE:0058C496                 call    _ObReferenceObjectByHandle@24 ; ObReferenceObjectByHandle(x,x,x,x,x,x)
PAGE:0058C49B                 mov     ebx, eax
PAGE:0058C49D                 test    ebx, ebx
PAGE:0058C49F                 jl      short loc_58C4ED
PAGE:0058C482                 push    0               ; HandleInformation
PAGE:0058C484                 lea     eax, [ebp+Process] ; 保存调试对象的地址
PAGE:0058C487                 push    eax             ; Object
PAGE:0058C488                 push    dword ptr [ebp+AccessMode] ; AccessMode
PAGE:0058C48B                 push    _DbgkDebugObjectType ; ObjectType
PAGE:0058C491                 push    2               ; DesiredAccess
PAGE:0058C493                 push    [ebp+DebugObject] ; Handle
PAGE:0058C496                 call    _ObReferenceObjectByHandle@24 ; ObReferenceObjectByHandle(x,x,x,x,x,x)
PAGE:0058C49B                 mov     ebx, eax
PAGE:0058C49D                 test    ebx, ebx
PAGE:0058C49F                 jl      short loc_58C4ED
PAGE:0058C4C0                 push    [ebp+DebugObject] ; DebugObjectHandle
PAGE:0058C4C3                 push    eax             ; int
PAGE:0058C4C4                 push    [ebp+Process]   ; DebugObject
PAGE:0058C4C7                 push    esi             ; Process
PAGE:0058C4C8                 call    _DbgkpSetProcessDebugObject@16
PAGE:0058C4C0                 push    [ebp+DebugObject] ; DebugObjectHandle
PAGE:0058C4C3                 push    eax             ; int
PAGE:0058C4C4                 push    [ebp+Process]   ; DebugObject
PAGE:0058C4C7                 push    esi             ; Process
PAGE:0058C4C8                 call    _DbgkpSetProcessDebugObject@16
PAGE:0058C237                 mov     edi, [ebp+Process]        ; 将被调试进行句柄赋给edi
PAGE:0058C251                 cmp     [edi+_EPROCESS.DebugPort], ebx    ; 判断DebugPort是否保存了调试对象
PAGE:0058C257                 jnz     short loc_58C2CC
PAGE:0058C259
PAGE:0058C259 loc_58C259:                             ; CODE XREF: DbgkpSetProcessDebugObject(x,x,x,x)+CF↓j
PAGE:0058C259                 mov     eax, [ebp+DebugObject]        ; 将调试对象地址赋给eax
PAGE:0058C25C                 mov     ecx, [ebp+DebugObjectHandle]
PAGE:0058C25F                 mov     [edi+_EPROCESS.DebugPort], eax    ; 将调试对象地址赋给DebugPort
PAGE:0058C237                 mov     edi, [ebp+Process]        ; 将被调试进行句柄赋给edi
PAGE:0058C251                 cmp     [edi+_EPROCESS.DebugPort], ebx    ; 判断DebugPort是否保存了调试对象
PAGE:0058C257                 jnz     short loc_58C2CC
PAGE:0058C259
PAGE:0058C259 loc_58C259:                             ; CODE XREF: DbgkpSetProcessDebugObject(x,x,x,x)+CF↓j
PAGE:0058C259                 mov     eax, [ebp+DebugObject]        ; 将调试对象地址赋给eax
PAGE:0058C25C                 mov     ecx, [ebp+DebugObjectHandle]
PAGE:0058C25F                 mov     [edi+_EPROCESS.DebugPort], eax    ; 将调试对象地址赋给DebugPort
.text:7C97009C                 mov     esi, eax
.text:7C97009E                 test    esi, esi
.text:7C9700A0                 jl      short loc_7C9700B8
.text:7C9700A2                 push    [ebp+arg_ProcessHandle]
.text:7C9700A5                 call    DbgUiIssueRemoteBreakin
.text:7C9700AA                 mov     esi, eax
.text:7C9700AC                 test    esi, esi
.text:7C9700AE                 jge     short loc_7C9700B8
.text:7C9700B0                 push    [ebp+arg_ProcessHandle]
.text:7C9700B3                 call    DbgUiStopDebugging
.text:7C97009C                 mov     esi, eax
.text:7C97009E                 test    esi, esi
.text:7C9700A0                 jl      short loc_7C9700B8
.text:7C9700A2                 push    [ebp+arg_ProcessHandle]
.text:7C9700A5                 call    DbgUiIssueRemoteBreakin
.text:7C9700AA                 mov     esi, eax
.text:7C9700AC                 test    esi, esi
.text:7C9700AE                 jge     short loc_7C9700B8
.text:7C9700B0                 push    [ebp+arg_ProcessHandle]
.text:7C9700B3                 call    DbgUiStopDebugging
.text:7C85B129                 push    esi             ; Handle
.text:7C85B12A                 mov     edi, eax
.text:7C85B12C                 call    ds:__imp__NtClose@4 ; NtClose(x)
.text:7C85B132                 test    edi, edi
.text:7C85B134                 jge     short loc_7C85B140
.text:7C85B136                 push    edi             ; Status
.text:7C85B137                 call    _BaseSetLastNTError@4 ; BaseSetLastNTError(x)
.text:7C85B13C                 xor     eax, eax
.text:7C85B13E                 jmp     short loc_7C85B143
.text:7C85B140 ; ---------------------------------------------------------------------------
.text:7C85B140
.text:7C85B140 loc_7C85B140:                           ; CODE XREF: DebugActiveProcess(x)+39↑j
.text:7C85B140                 xor     eax, eax
.text:7C85B142                 inc     eax
.text:7C85B143
.text:7C85B143 loc_7C85B143:                           ; CODE XREF: DebugActiveProcess(x)+43↑j
.text:7C85B143                 pop     edi
.text:7C85B144
.text:7C85B144 loc_7C85B144:                           ; CODE XREF: DebugActiveProcess(x)+25↑j
.text:7C85B144                 pop     esi
.text:7C85B145
.text:7C85B145 loc_7C85B145:                           ; CODE XREF: DebugActiveProcess(x)+16↑j
.text:7C85B145                 pop     ebp
.text:7C85B146                 retn    4
.text:7C85B146 _DebugActiveProcess@4 endp
.text:7C85B129                 push    esi             ; Handle
.text:7C85B12A                 mov     edi, eax
.text:7C85B12C                 call    ds:__imp__NtClose@4 ; NtClose(x)
.text:7C85B132                 test    edi, edi
.text:7C85B134                 jge     short loc_7C85B140
.text:7C85B136                 push    edi             ; Status
.text:7C85B137                 call    _BaseSetLastNTError@4 ; BaseSetLastNTError(x)
.text:7C85B13C                 xor     eax, eax
.text:7C85B13E                 jmp     short loc_7C85B143
.text:7C85B140 ; ---------------------------------------------------------------------------
.text:7C85B140
.text:7C85B140 loc_7C85B140:                           ; CODE XREF: DebugActiveProcess(x)+39↑j
.text:7C85B140                 xor     eax, eax
.text:7C85B142                 inc     eax
.text:7C85B143
.text:7C85B143 loc_7C85B143:                           ; CODE XREF: DebugActiveProcess(x)+43↑j
.text:7C85B143                 pop     edi
.text:7C85B144
.text:7C85B144 loc_7C85B144:                           ; CODE XREF: DebugActiveProcess(x)+25↑j
.text:7C85B144                 pop     esi
.text:7C85B145
.text:7C85B145 loc_7C85B145:                           ; CODE XREF: DebugActiveProcess(x)+16↑j
.text:7C85B145                 pop     ebp
.text:7C85B146                 retn    4

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-1-3 21:13 被1900编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (2)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
这是基于什么平台测试的
2022-6-27 04:10
0
雪    币: 22411
活跃值: (25361)
能力值: ( LV15,RANK:910 )
在线值:
发帖
回帖
粉丝
3
sanqiu 这是基于什么平台测试的
xp
2022-6-27 09:03
0
游客
登录 | 注册 方可回帖
返回
//