-
-
[原创]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返回
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直播授课
赞赏
- [原创]CVE-2022-21882提权漏洞学习笔记 16383
- [原创]CVE-2021-1732提权漏洞学习笔记 19489
- [原创]CVE-2014-1767提权漏洞学习笔记 15192
- [原创]CVE-2018-8453提权漏洞学习笔记 18526
- [原创]CVE-2020-1054提权漏洞学习笔记 13542