-
-
[原创]Windows内核学习笔记之线程(中)
-
发表于: 2021-12-22 19:06 12665
-
普通的函数调用是阻塞的,直到子函数执行完毕和返回后,父函数才能继续执行。如果子函数所用的时间很久,那么这次函数调用就会导致线程阻塞在这个函数内部。对于典型的Windows GUI程序,如果这样的阻塞发生在UI线程中,那么便会导致界面无法更新,失去响应。为了避免这样的情况,Windows系统的很多API支持以异步的方式工作,它们所依赖的便是NT内核的异步过程调用(APC)机制。
APC是针对线程的,每个APC都是在特定的线程环境中运行的,每个线程都有字节特有的APC链表。同一个线程的APC也是被排队执行的。由于APC的IRQL为APC_LEVEL,会高于普通线程代码的PASSIVE_LEVEL。所以,当一个线程获得控制时,它的APC过程就会立刻被执行。这一特性使得APC非常适合于实现各种异步通知事件。例如,I/O的完成通知就是通过APC来实现的。
APC是通过一种内核控制对象来表达的,称为APC对象,其定义如下:
APC对象要挂载到相应的线程对象链表中才会执行,在线程结构体ETHREAD中与APC对象比较有关联的成员有如下几个:
ApcState和SaveApcState是KAPC_STATE类型的成员,ApcStatePointer是一个包含两个元素的指针数组,ApcStateIndex则是KAPC_ENVIRONMENT的枚举类型索引。当一个线程在它所属的进程中运行时,使用的APC链表是ApcState成员,此时ApcStatePointer[0]指向的就是ApcState,并且ApcStateIndex等于0。如果线程挂载(attach)到另一个进程中,那么,尚未交付的APC对象从ApcState转移到SaveApcState中,并且ApcStatePointer[0]指向的就是SaveApcState,ApcStatePointer[1]指向的就是ApcState,ApcStateIndex等于1。所以,挂载完成以后,ApcStateIndex知名了ApcState将包含的当前进程的信息,包括在新进程环境中要执行的APC对象。此后插入的APC对象都将进入到ApcState链表中。
等到线程回到它自己的进程(detach)时,KeDetachProcess首先让属于当前进程的APC对象,即ApcState中的APC对象被交付,然后,将SaveApcState中的APC转移到ApcState中,并且设置ApcStateIndex等于0。这样就恢复了该线程被挂载以前的状态。因此,ApcState总包含了要在当前进程环境中执行的APC对象;ApcStateIndex总是指向ApcState在指针数组ApcStatePointer中的下标值。APC对象的插入操作总数以ApcStateIndex为下标来访问数组ApcStatePointer中的元素。
KAPC_STATE和定义如下:
KAPC_ENVIRONMENT枚举类型的定义如下:
OriginalApcEnvironment表示原始的进程环境;AttachedApcEnvironment表示挂载以后的新进程环境;CurrentApcEnvironment表示在APC对象初始化时线程所属的进程环境;最后的InsertApcEnvironment表示在APC对象被插入时线程所属的进程环境。在APC_STATE结构中,Process域指向了一个进程对象,代表了这些APC所关联的进程,PsGetCurrentProcess函数会从该与域获取进程对象的原因就是无论是否是挂载状态,总能获取正确的进程对象
ApcListHead数组有两个元素,分别代表了内核模式APC对象链表和用户模式APC对象链表。三个布尔变量KernelApcInProcess, KernelApcPending和UserApcPending分别表示:该线程当前正在处理一个内核APC,有内核模式APC对象正在等待被交付,以及有用户模式APC对象正在等待被交付。
不仅内核可以向一个线程发出APC请求,别的线程乃至目标线程自身也可以发出这样的请求。Win32 API为应用程序提供了一个函数QueueUserAPC就是用于此目的,而该函数是通过调用内核的NtQueueApcThread来实现的,第三个参数为函数BaesDispatchAPC函数地址,所以当从用户层插入APC的时候NormalRoutine被指定为BaseDispatchAPC,而用户真正要指向的函数则用第三个参数NormalContext传递进去
在NtQueueApcThread函数中,首先将线程的先前模式保存在局部变量中
调用函数来获得线程句柄的线程对象
对解析到的线程对象的CrossThreadFlags进行检测
如果通过检测,接下来就调用函数来申请0x30大小的内存用来保存APC对象
通过函数来初始化APC对象
将初始化完成的APC对象插入到线程中
最后退出函数
因此可以得出结论,向一个线程插入APC对象的之前需要申请一块0x30大小的内存,这块内存用来保存要插入的APC的对象,在调用KeInitializeApc的时候,指定了KernelApc的函数地址是IopDeallocateApc,根据该函数反汇编的结果可以得知,该函数的作用就是将申请到的保存APC对象的内存空间释放掉
在内核中,初始化APC对象是通过KeInitializeApc函数来实现的,而插入APC对象则是通过函数KeInsertQueueApc来实现的,KiDeliverApc则是用来交付插入的APC
在KeInitializeApc函数中首先对APC对象的类型和大小赋值,判断环境是否等于2,也就是是否是在CurrentApcEnvironment环境中
如果处在CurrentApcEnvironment环境中,则将dl赋值为当前线程的ApcStateIndex
使用传入的参数为APC对象中的Thread, KernelRoutine, RundownRoutine赋值,使用dl的值为APC对象中的ApcStateIndex赋值
判断传入的NormalRoutine是否为NULL
如果不为NULL,则会用传入的ApcMode和NormalContext为APC对象中的ApcMode和NormalContext赋值
如果为NULL,则将APC对象中的ApcMode和NormalContext赋值为寄存器edx中保存的0
将APC对象中的Inserted赋值为0,代表APC对象还未插入到APC链表中
在KeInsertQueueApc中首先要先获取APC锁
判断线程的ApcQueueable是否为0,即是否可以插入APC对象
如果可以插入,就调用KiInsertQueueApc将APC对象插入到相应的线程对象中,注意在调用之前将KAPC对象的地址赋给了ecx
最后释放掉APC锁
所以正在将APC对象插入到线程对象中是通过KiInsertQueueApc来实现的,继续看该函数的实现,函数首先将ecx赋给eax,因为ecx此时保存的是APC对象的地址,所以经过赋值以后eax保存的是APC对象的地址,判断APC的ApcStateIndex是否等于3
如果等于3则会将线程的ApcStateIndex赋给KAPC的ApcStateIndex
通过KAPC中的ApcStateIndex从线程对象中获取相应的APC_STATE,判断NormalRoutine是否为NULL
如果不为NULL,获取KAPC_STATE地址赋给edi,根据ApcMode从KAPC_STATE队列中的将上一个APC赋给esi
判断esi与edi是否相等
如果不相等,则判断KPAC队列的下一个KPAC对象是否为0
如果不为NULL,则将esi指向下一个KAPC,并跳转到上面的loc_402CB0执行
所以这个过程就是在从线程的KAPC_STATE中获取APC队列的最后一个KAPC对象,当esi执行队列中的最后一个KAPC对象的时候,就将要插入的APC对象插入到APC队列中
如果NormalRoutine为NULL,此时的edx保存的是ApcMode,所以会判断ApcMode是否为0,如果不为0,接着判断APC对象的KernelRoutine是否为PsExitSpecialApc
如果ApcMode为0或者当它不为0但是KernelRoutine不为PsExitSpecialApc的时候,将APC对象插入到线程APC队列的尾部
如果ApcMode不为0且APC对象的KernelRoutine为PsExitSpecialApc的时候,依然会把APC对象插入到APC队列中,只是此时的线程对象的ApcState的UserApcPending赋值为1
当APC对象插入到线程的APC队列以后,会将APC对象的Inserted赋值为1代表APC对象插入到线程中,将KAPC的ApcStateIndex和线程的ApcStateIndex分别赋给edi和esi,判断edi和esi是否相等
如果相等继续判断ApcMode是否为0
如果为0,则会将KernelApcPending赋值为1
如果不为0,则会继续判断线程的State, WaitMode, Alertable
如果都符合条件,就会将线程的UserApcPending赋值为1
APC对象成功插入到线程链表以后,在以下的几种情况下会执行APC的交付
当内核代码离开一个临界区或守护区,也就是在调用KeLevelGuardedRegion或KeLeaveCritiicalRegion时,通过KiCheckForKernelApcDeliver函数直接调用KiDeleverApc,或者调用KiRequestSoftwareInterrupt函数请求一个APC_LEVEL的软件中断。这是因为,当线程进入临界区或守护区时,内核模式APC被禁止了,所以,当离开时,KiCheckForKernelApcDelivery函数被调用,以便即使交付内核模式APC
当一个线程经过一次线程切换而获得控制权时,如果内核模式APC需要被交付,则在函数KiSwapThread函数返回以前,调用KiDeliverApc函数交付该内核模式APC
当系统服务或异常处理函数返回用户模式时,KiDeliverApc函数被调用以便交付用户模式APC
在APC_LEVEL软件中断发生时,HAL模块中的软件中断处理函数(HalpDispatchSoftwareInterrupt)调用KIDeliverApc交付内核模式APC。当内核代码调用KeLowerIrql函数降低IRQL到PASSIVE_LEVEL时,KiDeliverApc函数也会被调用
在交付函数KiDeliverApc中,首先对局部变量进行赋值,获得APC锁,将进程对象ETHREAD中的KernelApcPending赋值为0,代表线程没有要执行的内核APC
判断ApcState第一个链表是否有成员,也就是是否有内核APC,loc_45E56这个地址到后面执行完内核APC以后会在跳上来,通过这种方式就能遍历链表将内核APC都执行完毕
如果有内核APC,则从链表中将其取出,由于挂载到线程链表中的APC对象是通过偏移0x0C的ApcListEntry来连接的,所以需要将线程链表中获取的APC对象地址减去0x0C才可以得到APC对象的真正地址
将成员赋值到局部变量,判断NormalRoutine是否为NULL
如果NormalRoutine为NULL,则将APC对象从链表中删除,清空Inserted成员,释放APC锁并通过调用保存在KernelRoutine中的函数来释放APC对象的内存空间,最后跳转到loc_405E56继续判断是否有下一个内核APC需要执行
如果NormalRoutine不为NULL,先对线程中的KernelApcInProgress和KernelApcDisable两个成员进行判断,分别判断是否有内核APC在执行,以及内核APC是否被禁止
如果有内核APC在执行或内核APC被禁止,则结束执行
如果通过验证,则将内核APC从链表中摘除,将Inserted赋值为0,释放APC锁
调用KernelRoutine释放APC对象内存
再次判断NormalRoutine是否为NULL
不为NULL,则将KernelApcInProgress赋值为1,代表内核APC正在执行,且通过函数降低IRQL
调用NormalRoutine中保存的内核APC函数
通过函数提高IRQL
释放APC锁,将KernelApcInProgress赋值为0,代表没有内核APC函数正在执行,然后依然返回到loc_405E56处继续寻找下一个内核APC
当执行完内核APC以后,就会判断用户APC链表中是否有需要处理的APC对象
如果没有,就会释放APC锁,退出KiDeliver函数
如果有用户APC要执行,会首先判断先前模式是否为用户模式以及用户APC是否等待交互。如果先前模式不是用户模式,或者用户APC正在等待交付,则会退出函数执行
将线程对象中的UserApcPending赋值为0,并为局部变量赋值
将APC对象从链表中摘除,APC对象的Inserted赋值为0,释放APC锁
由于ebx此时保存的是KernelRoutine,所以接下来就是调用KernelRoutine来释放APC对象的内存
判断NormalRoutine是否为NULL
如果为NULL,则会调用KeTestAlertThread
如果不为NULL,则调用KiInitializeUserApc
对于用户APC函数,由于该函数是在用户空间执行的,所以需要返回到用户空间,而要返回到用户空间就会导致陷阱帧(Trap_Frame)遭到破坏,为了保证程序在执行完用户APC以后依然可以正常运行,就需要将陷阱帧中的内容保存起来,所以函数最开始除了把变量赋值到局部变量中,还通过KeContextFromKFrames函数将陷阱帧中的数据保存到Context结构的局部变量var_ContextFrame中
取出用户栈的栈顶指针,此时的指针指向陷阱帧的顶部,将其减去一段地址得到新的栈顶,验证栈顶是否可写
将局部变量var_ContextFrame中保存的陷阱帧数据赋值到新的栈顶偏移0x10处
为陷阱帧的各项寄存器赋值,验证Iopl是否为0
为0的时候,将新的栈顶指针赋给eax,继续陷阱帧中的寄存器赋值,此时陷阱帧的EIP被修改为ntdll.dll中的函数KeUserAcpDispatcher地址
由于eax此时指向新的栈顶的指针,所以接下来的代码就是将4参数赋值到栈顶,这也就是为什么在复制Context的时候,复制的目的地址是新的栈顶指针偏移0x10的地址,因为最开始的0x10的空间是用来保存这四个参数的
此时已经成功修改的陷阱帧的EIP,当函数返回到用户层的时候就会执行指定的ntdll.dll中的函数KeUserAcpDispatcher,且经过复制以后,此时用户栈的数据如下图所示
继续看ntll.dll中KeUserApcDispatcher中的函数的时候,可以看到该函数首先取出栈顶指针偏移0x10的地址赋给edi,随后弹出栈顶保存的NormalRoutine,调用该函数,将edi入栈后调用ZwContinue
NormalRoutine的函数地址是在用户层调用QueueUserApc插入用户APC的时候,指定为函数BaseDispatchAPC,该函数在kernel32.dll中,而该函数最重要的就是调用由用户所指定的NormalContext中保存的函数
调用结束以后,加下来继续调用ZwContinue进入内核,重复上面的操作
在线程创建的内核函数NtCreateThread中会调用KeInitThread函数来初始化线程对象,以及线程的启动函数。
初始化与同步有关的各个域
初始化系统服务表,APC的域
调用KeInitializeApc初始化一个内核APC对象
该APC对象的NormalRoutine为KiSuspendThread,该函数实现如下
初始化互斥体,定时器,WaitBlock,APC锁
创建内核栈
初始化栈信息
调用KeInitializeContextThread初始化域特定处理器相关的执行环境
在初始化线程的两个域以后退出函数
在KeInitializeContextThread中,函数会首先判断是否传递了ContextFrame参数,如果有该参数,说明创建的是用户线程,否则就是内核线程
如果是用户线程,就会将传递的ContextFrame赋值给局部变量var_Context
从线程对象中取出栈指针,并开辟一段空间用来吧保存数据
对局部变量var_Context进行赋值
调用KeContextToKframes将局部变量var_Context内容赋值到var_TrapFrame中,该函数的作用就是根据Context结构中的内容将数据赋值到陷阱帧(TrapFrame)结构中,此时局部变量var_SwitchFrame是在TrapFrame低地址处,该变量是KSWITCHFRAME结构,用来存储的内容就包括了创建的线程的启动函数
此时esi执行陷阱帧的头部,对陷阱帧中的几个寄存器进行赋值
对陷阱帧的先前模式和线程的先前模式赋值为用户模式
在栈中填充SystemRoutine, StartRoutine, StartContext,指定线程的启动函数以及线程的栈指针后退出函数
由上内容可以知道,启动函数为KiThreadStartup,该函数就是将栈顶的SystemRoutine弹出后调用,而SystemRoutine则是在调用KeInitThread的时候指定的,如果创建的是用户线程,该参数就会是PspUserThreadStartup,如果是内核线程就会是PspSystemThreadStartup。线程启动函数被当作第一个参数传入,该函数是kernel32.dll中的BaseProcessStart
以下是函数的部分代码,根据这些代码可以指代,该函数就是将全局变量PspSytemDll中保存的函数作为APC插入到线程中,而这个被插入的函数是ntdll.dll中的LdrInitializeThunk,该函数负责dll的装入和链接。当PspUserThreadStartup函数返回以后,KiThreadStartup函数返回到用户模式,此时,PspUserThreadStartup插入的APC被交付,于是LdrInitializeThunk函数被调用。当LdrInitializeThunk返回到用户模式APC分发器时,该线程开始在用户模式下执行,调用应用程序指定的线程启动函数,此启动函数的地址已经在APC交付时被压到用户栈中
kd> dt _KAPC
nt!_KAPC
+
0x000
Type
+
0x002
Size
+
0x004
Spare0
+
0x008
Thread
+
0x00c
ApcListEntry
+
0x014
KernelRoutine
+
0x018
RundownRoutine
+
0x01c
NormalRoutine
+
0x020
NormalContext
+
0x024
SystemArgument1
+
0x028
SystemArgument2
+
0x02c
ApcStateIndex
+
0x02d
ApcMode
+
0x02e
Inserted
kd> dt _KAPC
nt!_KAPC
+
0x000
Type
+
0x002
Size
+
0x004
Spare0
+
0x008
Thread
+
0x00c
ApcListEntry
+
0x014
KernelRoutine
+
0x018
RundownRoutine
+
0x01c
NormalRoutine
+
0x020
NormalContext
+
0x024
SystemArgument1
+
0x028
SystemArgument2
+
0x02c
ApcStateIndex
+
0x02d
ApcMode
+
0x02e
Inserted
名称 | 含义 |
---|---|
Type | 为KOBJECTS枚举类型的ApcObject |
Size | 等于KAPC结构的大小 |
Thread | 指向此APC对象所在的线程ETHREAD |
ApcListEntry | APC对象被加入到线程APC链表中的节点对象 |
KernelRoutine | 指向释放APC对象的函数指针 |
RundownRoutine | 函数指针(可选参数),当一个线程终止时,如果它的APC链表中还有APC对象,若RundownRoutine非空,则调用它所指函数 |
NormalRoutine | 如果是内核APC,指向要指向的函数,如果是用户APC指向了所有用户APC都会运行的函数 |
NormalContext | 如果是内核APC该参数为NULL,如果是用户APC该参数就是真正要执行的用户APC函数 |
SystemArgument1 | APC函数的参数 |
SystemArgument2 | APC函数的参数 |
AppStateIndex | 说明了APC对象的环境状态,它是KAPC_ENVIRONMENT枚举类型的成员,一旦APC对象被插入到线程的APC链表中,则ApcStateIndex指示了它位于线程ETHREAD对象的哪个APC链表中 |
ApcMode | 为0表示这是一个内核APC,为1说明这是用户APC |
Inserted | 指示该APC是否已被插入到线程的APC链表中 |
偏移 | 名称 |
---|---|
0x034 | ApcState |
0x138 | ApcStatePointer |
0x014C | SavedApcState |
0x165 | ApcStateIndex |
kd> dt _KAPC_STATE
nt!_KAPC_STATE
+
0x000
ApcListHead
+
0x010
Process
+
0x014
KernelApcInProgress
+
0x015
KernelApcPending
+
0x016
UserApcPending
kd> dt _KAPC_STATE
nt!_KAPC_STATE
+
0x000
ApcListHead
+
0x010
Process
+
0x014
KernelApcInProgress
+
0x015
KernelApcPending
+
0x016
UserApcPending
typedef enum _KAPC_ENVIRONMENT{
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
}KAPC_ENVIRONMENT;
typedef enum _KAPC_ENVIRONMENT{
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
}KAPC_ENVIRONMENT;
.text:
0040ED86
public _PsGetCurrentProcess@
0
.text:
0040ED86
_PsGetCurrentProcess@
0
proc near
.text:
0040ED86
mov eax, large fs:
124h
; IoGetCurrentProcess
.text:
0040ED8C
mov eax, [eax
+
_KTHREAD.ApcState.Process]
.text:
0040ED8F
retn
.text:
0040ED8F
_PsGetCurrentProcess@
0
endp
.text:
0040ED86
public _PsGetCurrentProcess@
0
.text:
0040ED86
_PsGetCurrentProcess@
0
proc near
.text:
0040ED86
mov eax, large fs:
124h
; IoGetCurrentProcess
.text:
0040ED8C
mov eax, [eax
+
_KTHREAD.ApcState.Process]
.text:
0040ED8F
retn
.text:
0040ED8F
_PsGetCurrentProcess@
0
endp
.text:
7C82C0CF
loc_7C82C0CF: ; CODE XREF: QueueUserAPC(x,x,x)
+
18B79
↓j
.text:
7C82C0CF
push eax ; SystemArgument2
.text:
7C82C0D0
push [ebp
+
dwData] ; SystemArgument1
.text:
7C82C0D3
push [ebp
+
pfnAPC] ; NormalContext
.text:
7C82C0D6
push offset _BaseDispatchAPC@
12
; NormalRoutine
.text:
7C82C0DB
push [ebp
+
hThread] ; ThreadHandle
.text:
7C82C0DE
call ds:__imp__NtQueueApcThread@
20
; NtQueueApcThread(x,x,x,x,x)
.text:
7C82C0E4
xor ecx, ecx
.text:
7C82C0E6
test eax, eax
.text:
7C82C0E8
setnl cl
.text:
7C82C0EB
mov eax, ecx
.text:
7C82C0CF
loc_7C82C0CF: ; CODE XREF: QueueUserAPC(x,x,x)
+
18B79
↓j
.text:
7C82C0CF
push eax ; SystemArgument2
.text:
7C82C0D0
push [ebp
+
dwData] ; SystemArgument1
.text:
7C82C0D3
push [ebp
+
pfnAPC] ; NormalContext
.text:
7C82C0D6
push offset _BaseDispatchAPC@
12
; NormalRoutine
.text:
7C82C0DB
push [ebp
+
hThread] ; ThreadHandle
.text:
7C82C0DE
call ds:__imp__NtQueueApcThread@
20
; NtQueueApcThread(x,x,x,x,x)
.text:
7C82C0E4
xor ecx, ecx
.text:
7C82C0E6
test eax, eax
.text:
7C82C0E8
setnl cl
.text:
7C82C0EB
mov eax, ecx
PAGE:
004C2AAA
; NTSTATUS __stdcall NtQueueApcThread(HANDLE ThreadHandle, PKNORMAL_ROUTINE ApcRoutine, PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
PAGE:
004C2AAA
_NtQueueApcThread@
20
proc near ; DATA XREF: .text:
0040DAF0
↑o
PAGE:
004C2AAA
PAGE:
004C2AAA
AccessMode
=
byte ptr
-
4
PAGE:
004C2AAA
ThreadHandle
=
dword ptr
8
PAGE:
004C2AAA
ApcRoutine
=
dword ptr
0Ch
PAGE:
004C2AAA
NormalContext
=
dword ptr
10h
PAGE:
004C2AAA
SystemArgument1
=
dword ptr
14h
PAGE:
004C2AAA
SystemArgument2
=
dword ptr
18h
PAGE:
004C2AAA
PAGE:
004C2AAA
; FUNCTION CHUNK AT PAGE:
0052E6D5
SIZE
00000025
BYTES
PAGE:
004C2AAA
PAGE:
004C2AAA
mov edi, edi
PAGE:
004C2AAC
push ebp
PAGE:
004C2AAD
mov ebp, esp
PAGE:
004C2AAF
push ecx
PAGE:
004C2AB0
push ebx
PAGE:
004C2AB1
push esi
PAGE:
004C2AB2
mov eax, large fs:
124h
; 将线程对象赋给eax
PAGE:
004C2AB8
mov al, [eax
+
_KTHREAD.PreviousMode]
PAGE:
004C2ABE
mov [ebp
+
AccessMode], al ; 为局部变量赋值
PAGE:
004C2AAA
; NTSTATUS __stdcall NtQueueApcThread(HANDLE ThreadHandle, PKNORMAL_ROUTINE ApcRoutine, PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
PAGE:
004C2AAA
_NtQueueApcThread@
20
proc near ; DATA XREF: .text:
0040DAF0
↑o
PAGE:
004C2AAA
PAGE:
004C2AAA
AccessMode
=
byte ptr
-
4
PAGE:
004C2AAA
ThreadHandle
=
dword ptr
8
PAGE:
004C2AAA
ApcRoutine
=
dword ptr
0Ch
PAGE:
004C2AAA
NormalContext
=
dword ptr
10h
PAGE:
004C2AAA
SystemArgument1
=
dword ptr
14h
PAGE:
004C2AAA
SystemArgument2
=
dword ptr
18h
PAGE:
004C2AAA
PAGE:
004C2AAA
; FUNCTION CHUNK AT PAGE:
0052E6D5
SIZE
00000025
BYTES
PAGE:
004C2AAA
PAGE:
004C2AAA
mov edi, edi
PAGE:
004C2AAC
push ebp
PAGE:
004C2AAD
mov ebp, esp
PAGE:
004C2AAF
push ecx
PAGE:
004C2AB0
push ebx
PAGE:
004C2AB1
push esi
PAGE:
004C2AB2
mov eax, large fs:
124h
; 将线程对象赋给eax
PAGE:
004C2AB8
mov al, [eax
+
_KTHREAD.PreviousMode]
PAGE:
004C2ABE
mov [ebp
+
AccessMode], al ; 为局部变量赋值
PAGE:
004C2AC1
xor esi, esi ; esi清
0
PAGE:
004C2AC3
push esi ; HandleInformation
PAGE:
004C2AC4
lea eax, [ebp
+
Object
]
PAGE:
004C2AC7
push eax ;
Object
PAGE:
004C2AC8
push dword ptr [ebp
+
AccessMode] ; AccessMode
PAGE:
004C2ACB
push _PsThreadType ; ObjectType
PAGE:
004C2AD1
push
10h
; DesiredAccess
PAGE:
004C2AD3
push [ebp
+
ThreadHandle] ; Handle
PAGE:
004C2AD6
call _ObReferenceObjectByHandle@
24
; ObReferenceObjectByHandle(x,x,x,x,x,x)
PAGE:
004C2ADB
mov ebx, eax
PAGE:
004C2ADD
cmp
ebx, esi
PAGE:
004C2ADF
jl short loc_4C2B42
PAGE:
004C2AC1
xor esi, esi ; esi清
0
PAGE:
004C2AC3
push esi ; HandleInformation
PAGE:
004C2AC4
lea eax, [ebp
+
Object
]
PAGE:
004C2AC7
push eax ;
Object
PAGE:
004C2AC8
push dword ptr [ebp
+
AccessMode] ; AccessMode
PAGE:
004C2ACB
push _PsThreadType ; ObjectType
PAGE:
004C2AD1
push
10h
; DesiredAccess
PAGE:
004C2AD3
push [ebp
+
ThreadHandle] ; Handle
PAGE:
004C2AD6
call _ObReferenceObjectByHandle@
24
; ObReferenceObjectByHandle(x,x,x,x,x,x)
PAGE:
004C2ADB
mov ebx, eax
PAGE:
004C2ADD
cmp
ebx, esi
PAGE:
004C2ADF
jl short loc_4C2B42
PAGE:
004C2AE1
mov eax, [ebp
+
Object
]
PAGE:
004C2AE4
xor ebx, ebx
PAGE:
004C2AE6
test byte ptr [eax
+
_ETHREAD.___u24.CrossThreadFlags], OBJ_PERMANENT
PAGE:
004C2AED
jnz loc_52E6D5
PAGE:
004C2AE1
mov eax, [ebp
+
Object
]
PAGE:
004C2AE4
xor ebx, ebx
PAGE:
004C2AE6
test byte ptr [eax
+
_ETHREAD.___u24.CrossThreadFlags], OBJ_PERMANENT
PAGE:
004C2AED
jnz loc_52E6D5
PAGE:
004C2AF3
push edi
PAGE:
004C2AF4
push
'pasP'
; Tag
PAGE:
004C2AF9
push
30h
; NumberOfBytes
PAGE:
004C2AFB
push
8
; PoolType
PAGE:
004C2AFD
call _ExAllocatePoolWithQuotaTag@
12
; ExAllocatePoolWithQuotaTag(x,x,x)
PAGE:
004C2B02
mov edi, eax ; 将申请到的内存地址赋给edi
PAGE:
004C2B04
cmp
edi, esi
PAGE:
004C2B06
jz loc_52E6DF
PAGE:
004C2AF3
push edi
PAGE:
004C2AF4
push
'pasP'
; Tag
PAGE:
004C2AF9
push
30h
; NumberOfBytes
PAGE:
004C2AFB
push
8
; PoolType
PAGE:
004C2AFD
call _ExAllocatePoolWithQuotaTag@
12
; ExAllocatePoolWithQuotaTag(x,x,x)
PAGE:
004C2B02
mov edi, eax ; 将申请到的内存地址赋给edi
PAGE:
004C2B04
cmp
edi, esi
PAGE:
004C2B06
jz loc_52E6DF
PAGE:
004C2B0C
push [ebp
+
NormalContext] ; NormalContext
PAGE:
004C2B0F
push
1
; ApcMode
PAGE:
004C2B11
push [ebp
+
ApcRoutine] ; NormalRoutine
PAGE:
004C2B14
push esi ; RundownRoutine
PAGE:
004C2B15
push offset _IopDeallocateApc@
20
; KernelRoutine
PAGE:
004C2B1A
push esi ;
int
PAGE:
004C2B1B
push [ebp
+
ThreadHandle] ; Thread
PAGE:
004C2B1E
push edi ; Apc
PAGE:
004C2B1F
call _KeInitializeApc@
32
PAGE:
004C2B0C
push [ebp
+
NormalContext] ; NormalContext
PAGE:
004C2B0F
push
1
; ApcMode
PAGE:
004C2B11
push [ebp
+
ApcRoutine] ; NormalRoutine
PAGE:
004C2B14
push esi ; RundownRoutine
PAGE:
004C2B15
push offset _IopDeallocateApc@
20
; KernelRoutine
PAGE:
004C2B1A
push esi ;
int
PAGE:
004C2B1B
push [ebp
+
ThreadHandle] ; Thread
PAGE:
004C2B1E
push edi ; Apc
PAGE:
004C2B1F
call _KeInitializeApc@
32
PAGE:
004C2B24
push esi ; Increment
PAGE:
004C2B25
push [ebp
+
SystemArgument2] ; SystemArgument2
PAGE:
004C2B28
push [ebp
+
SystemArgument1] ; SystemArgument1
PAGE:
004C2B2B
push edi ; Apc
PAGE:
004C2B2C
call _KeInsertQueueApc@
16
; KeInsertQueueApc(x,x,x,x)
PAGE:
004C2B31
test al, al
PAGE:
004C2B33
jz loc_52E6E9
PAGE:
004C2B24
push esi ; Increment
PAGE:
004C2B25
push [ebp
+
SystemArgument2] ; SystemArgument2
PAGE:
004C2B28
push [ebp
+
SystemArgument1] ; SystemArgument1
PAGE:
004C2B2B
push edi ; Apc
PAGE:
004C2B2C
call _KeInsertQueueApc@
16
; KeInsertQueueApc(x,x,x,x)
PAGE:
004C2B31
test al, al
PAGE:
004C2B33
jz loc_52E6E9
PAGE:
004C2B39
loc_4C2B39: ; CODE XREF: NtQueueApcThread(x,x,x,x,x)
+
6BC3A
↓j
PAGE:
004C2B39
; NtQueueApcThread(x,x,x,x,x)
+
6BC4B
↓j
PAGE:
004C2B39
pop edi
PAGE:
004C2B3A
PAGE:
004C2B3A
loc_4C2B3A: ; CODE XREF: NtQueueApcThread(x,x,x,x,x)
+
6BC30
↓j
PAGE:
004C2B3A
mov ecx, [ebp
+
ThreadHandle] ;
Object
PAGE:
004C2B3D
call @ObfDereferenceObject@
4
; ObfDereferenceObject(x)
PAGE:
004C2B42
PAGE:
004C2B42
loc_4C2B42: ; CODE XREF: NtQueueApcThread(x,x,x,x,x)
+
35
↑j
PAGE:
004C2B42
pop esi
PAGE:
004C2B43
mov eax, ebx
PAGE:
004C2B45
pop ebx
PAGE:
004C2B46
leave
PAGE:
004C2B47
retn
14h
PAGE:
004C2B47
_NtQueueApcThread@
20
endp
PAGE:
004C2B39
loc_4C2B39: ; CODE XREF: NtQueueApcThread(x,x,x,x,x)
+
6BC3A
↓j
PAGE:
004C2B39
; NtQueueApcThread(x,x,x,x,x)
+
6BC4B
↓j
PAGE:
004C2B39
pop edi
PAGE:
004C2B3A
PAGE:
004C2B3A
loc_4C2B3A: ; CODE XREF: NtQueueApcThread(x,x,x,x,x)
+
6BC30
↓j
PAGE:
004C2B3A
mov ecx, [ebp
+
ThreadHandle] ;
Object
PAGE:
004C2B3D
call @ObfDereferenceObject@
4
; ObfDereferenceObject(x)
PAGE:
004C2B42
PAGE:
004C2B42
loc_4C2B42: ; CODE XREF: NtQueueApcThread(x,x,x,x,x)
+
35
↑j
PAGE:
004C2B42
pop esi
PAGE:
004C2B43
mov eax, ebx
PAGE:
004C2B45
pop ebx
PAGE:
004C2B46
leave
PAGE:
004C2B47
retn
14h
PAGE:
004C2B47
_NtQueueApcThread@
20
endp
PAGE:
0049F852
;
int
__stdcall IopDeallocateApc(PVOID P,
int
,
int
,
int
,
int
)
PAGE:
0049F852
_IopDeallocateApc@
20
proc near ; DATA XREF: IoRaiseHardError(x,x,x)
+
16070
↑o
PAGE:
0049F852
; IoRaiseInformationalHardError(x,x,x)
+
123
↑o ...
PAGE:
0049F852
PAGE:
0049F852
P
=
dword ptr
8
PAGE:
0049F852
PAGE:
0049F852
mov edi, edi
PAGE:
0049F854
push ebp
PAGE:
0049F855
mov ebp, esp
PAGE:
0049F857
push
0
; Tag
PAGE:
0049F859
push [ebp
+
P] ; P
PAGE:
0049F85C
call _ExFreePoolWithTag@
8
; ExFreePoolWithTag(x,x)
PAGE:
0049F861
pop ebp
PAGE:
0049F862
retn
14h
PAGE:
0049F862
_IopDeallocateApc@
20
endp
PAGE:
0049F852
;
int
__stdcall IopDeallocateApc(PVOID P,
int
,
int
,
int
,
int
)
PAGE:
0049F852
_IopDeallocateApc@
20
proc near ; DATA XREF: IoRaiseHardError(x,x,x)
+
16070
↑o
PAGE:
0049F852
; IoRaiseInformationalHardError(x,x,x)
+
123
↑o ...
PAGE:
0049F852
PAGE:
0049F852
P
=
dword ptr
8
PAGE:
0049F852
PAGE:
0049F852
mov edi, edi
PAGE:
0049F854
push ebp
PAGE:
0049F855
mov ebp, esp
PAGE:
0049F857
push
0
; Tag
PAGE:
0049F859
push [ebp
+
P] ; P
PAGE:
0049F85C
call _ExFreePoolWithTag@
8
; ExFreePoolWithTag(x,x)
PAGE:
0049F861
pop ebp
PAGE:
0049F862
retn
14h
PAGE:
0049F862
_IopDeallocateApc@
20
endp
.text:
0040EBD9
;
int
__stdcall KeInitializeApc(PRKAPC Apc, PRKTHREAD Thread,
int
, PKKERNEL_ROUTINE KernelRoutine, PKRUNDOWN_ROUTINE RundownRoutine, PKNORMAL_ROUTINE NormalRoutine, KPROCESSOR_MODE ApcMode, PVOID NormalContext)
.text:
0040EBD9
public _KeInitializeApc@
32
.text:
0040EBD9
_KeInitializeApc@
32
proc near ; CODE XREF: NtSetTimer(x,x,x,x,x,x,x)
+
12F
↓p
.text:
0040EBD9
; IopfCompleteRequest(x,x)
+
11581
↓p ...
.text:
0040EBD9
.text:
0040EBD9
Apc
=
dword ptr
8
.text:
0040EBD9
Thread
=
dword ptr
0Ch
.text:
0040EBD9
Environment
=
dword ptr
10h
.text:
0040EBD9
KernelRoutine
=
dword ptr
14h
.text:
0040EBD9
RundownRoutine
=
dword ptr
18h
.text:
0040EBD9
NormalRoutine
=
dword ptr
1Ch
.text:
0040EBD9
ApcMode
=
byte ptr
20h
.text:
0040EBD9
NormalContext
=
dword ptr
24h
.text:
0040EBD9
.text:
0040EBD9
mov edi, edi
.text:
0040EBDB
push ebp
.text:
0040EBDC
mov ebp, esp
.text:
0040EBDE
mov eax, [ebp
+
Apc] ; 将APC赋给eax
.text:
0040EBE1
mov edx, [ebp
+
Environment] ; 将APC环境赋给edx
.text:
0040EBE4
cmp
edx,
2
; 判断APC环境是否为CurrentApcEnvironment
.text:
0040EBE7
mov ecx, [ebp
+
Thread] ; 将线程对象赋给ecx
.text:
0040EBEA
mov [eax
+
KAPC.
Type
], ApcObject ; 为APC类型赋值
.text:
0040EBEF
mov [eax
+
KAPC.Size],
30h
; 为结构体的大小赋值
.text:
0040EBF5
jz loc_40FB78
.text:
0040EBD9
;
int
__stdcall KeInitializeApc(PRKAPC Apc, PRKTHREAD Thread,
int
, PKKERNEL_ROUTINE KernelRoutine, PKRUNDOWN_ROUTINE RundownRoutine, PKNORMAL_ROUTINE NormalRoutine, KPROCESSOR_MODE ApcMode, PVOID NormalContext)
.text:
0040EBD9
public _KeInitializeApc@
32
.text:
0040EBD9
_KeInitializeApc@
32
proc near ; CODE XREF: NtSetTimer(x,x,x,x,x,x,x)
+
12F
↓p
.text:
0040EBD9
; IopfCompleteRequest(x,x)
+
11581
↓p ...
.text:
0040EBD9
.text:
0040EBD9
Apc
=
dword ptr
8
.text:
0040EBD9
Thread
=
dword ptr
0Ch
.text:
0040EBD9
Environment
=
dword ptr
10h
.text:
0040EBD9
KernelRoutine
=
dword ptr
14h
.text:
0040EBD9
RundownRoutine
=
dword ptr
18h
.text:
0040EBD9
NormalRoutine
=
dword ptr
1Ch
.text:
0040EBD9
ApcMode
=
byte ptr
20h
.text:
0040EBD9
NormalContext
=
dword ptr
24h
.text:
0040EBD9
.text:
0040EBD9
mov edi, edi
.text:
0040EBDB
push ebp
.text:
0040EBDC
mov ebp, esp
.text:
0040EBDE
mov eax, [ebp
+
Apc] ; 将APC赋给eax
.text:
0040EBE1
mov edx, [ebp
+
Environment] ; 将APC环境赋给edx
.text:
0040EBE4
cmp
edx,
2
; 判断APC环境是否为CurrentApcEnvironment
.text:
0040EBE7
mov ecx, [ebp
+
Thread] ; 将线程对象赋给ecx
.text:
0040EBEA
mov [eax
+
KAPC.
Type
], ApcObject ; 为APC类型赋值
.text:
0040EBEF
mov [eax
+
KAPC.Size],
30h
; 为结构体的大小赋值
.text:
0040EBF5
jz loc_40FB78
.text:
0040FB78
loc_40FB78: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
1C
↑j
.text:
0040FB78
mov dl, [ecx
+
_KTHREAD.ApcStateIndex]
.text:
0040FB7E
jmp loc_40EBFB
.text:
0040FB78
loc_40FB78: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
1C
↑j
.text:
0040FB78
mov dl, [ecx
+
_KTHREAD.ApcStateIndex]
.text:
0040FB7E
jmp loc_40EBFB
.text:
0040EBFB
loc_40EBFB: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
FA5↓j
.text:
0040EBFB
mov [eax
+
KAPC.Thread], ecx ; 为APC对象所在的线程对象KTHREAD对象赋值
.text:
0040EBFE
mov ecx, [ebp
+
KernelRoutine]
.text:
0040EC01
mov [eax
+
KAPC.KernelRoutine], ecx ; 为KernelRoutine对象赋值
.text:
0040EC04
mov ecx, [ebp
+
RundownRoutine]
.text:
0040EC07
mov [eax
+
KAPC.ApcStateIndex], dl ; 将dl赋值给ApcStateIndex
.text:
0040EC0A
mov [eax
+
KAPC.RundownRoutine], ecx
.text:
0040EBFB
loc_40EBFB: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
FA5↓j
.text:
0040EBFB
mov [eax
+
KAPC.Thread], ecx ; 为APC对象所在的线程对象KTHREAD对象赋值
.text:
0040EBFE
mov ecx, [ebp
+
KernelRoutine]
.text:
0040EC01
mov [eax
+
KAPC.KernelRoutine], ecx ; 为KernelRoutine对象赋值
.text:
0040EC04
mov ecx, [ebp
+
RundownRoutine]
.text:
0040EC07
mov [eax
+
KAPC.ApcStateIndex], dl ; 将dl赋值给ApcStateIndex
.text:
0040EC0A
mov [eax
+
KAPC.RundownRoutine], ecx
.text:
0040EC0D
mov ecx, [ebp
+
NormalRoutine]
.text:
0040EC10
xor edx, edx ; edx清
0
.text:
0040EC12
cmp
ecx, edx
.text:
0040EC14
mov [eax
+
KAPC.NormalRoutine], ecx ; 判断NormalRoutine是否为NULL
.text:
0040EC17
jnz loc_40EDEF
.text:
0040EC0D
mov ecx, [ebp
+
NormalRoutine]
.text:
0040EC10
xor edx, edx ; edx清
0
.text:
0040EC12
cmp
ecx, edx
.text:
0040EC14
mov [eax
+
KAPC.NormalRoutine], ecx ; 判断NormalRoutine是否为NULL
.text:
0040EC17
jnz loc_40EDEF
.text:
0040EDEF
loc_40EDEF: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
3E
↑j
.text:
0040EDEF
mov cl, [ebp
+
ApcMode]
.text:
0040EDF2
mov [eax
+
KAPC.ApcMode], cl
.text:
0040EDF5
mov ecx, [ebp
+
NormalContext]
.text:
0040EDF8
mov [eax
+
KAPC.NormalContext], ecx
.text:
0040EDFB
jmp loc_40EC23
.text:
0040EDEF
loc_40EDEF: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
3E
↑j
.text:
0040EDEF
mov cl, [ebp
+
ApcMode]
.text:
0040EDF2
mov [eax
+
KAPC.ApcMode], cl
.text:
0040EDF5
mov ecx, [ebp
+
NormalContext]
.text:
0040EDF8
mov [eax
+
KAPC.NormalContext], ecx
.text:
0040EDFB
jmp loc_40EC23
.text:
0040EC1D
mov [eax
+
_KAPC.ApcMode], dl
.text:
0040EC20
mov [eax
+
KAPC.NormalContext], edx
.text:
0040EC1D
mov [eax
+
_KAPC.ApcMode], dl
.text:
0040EC20
mov [eax
+
KAPC.NormalContext], edx
.text:
0040EC23
loc_40EC23: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
222
↓j
.text:
0040EC23
mov [eax
+
KAPC.Inserted], dl ; Insert赋值为
0
,代表还未插入到APC链表中
.text:
0040EC26
pop ebp
.text:
0040EC27
retn
20h
.text:
0040EC27
_KeInitializeApc@
32
endp
.text:
0040EC23
loc_40EC23: ; CODE XREF: KeInitializeApc(x,x,x,x,x,x,x,x)
+
222
↓j
.text:
0040EC23
mov [eax
+
KAPC.Inserted], dl ; Insert赋值为
0
,代表还未插入到APC链表中
.text:
0040EC26
pop ebp
.text:
0040EC27
retn
20h
.text:
0040EC27
_KeInitializeApc@
32
endp
.text:
0040EC2F
;
int
__stdcall KeInsertQueueApc(PRKAPC Apc, PVOID SystemArgument1, PVOID SystemArgument2, KPRIORITY Increment)
.text:
0040EC2F
public _KeInsertQueueApc@
16
.text:
0040EC2F
_KeInsertQueueApc@
16
proc near ; CODE XREF: ExpTimerDpcRoutine(x,x,x,x)
+
30
↓p
.text:
0040EC2F
; IopfCompleteRequest(x,x)
+
11528
↓p ...
.text:
0040EC2F
.text:
0040EC2F
LockHandle
=
_KLOCK_QUEUE_HANDLE ptr
-
0Ch
.text:
0040EC2F
Apc
=
dword ptr
8
.text:
0040EC2F
SystemArgument1
=
dword ptr
0Ch
.text:
0040EC2F
SystemArgument2
=
dword ptr
10h
.text:
0040EC2F
Increment
=
dword ptr
14h
.text:
0040EC2F
.text:
0040EC2F
mov edi, edi
.text:
0040EC31
push ebp
.text:
0040EC32
mov ebp, esp
.text:
0040EC34
sub esp,
0Ch
.text:
0040EC37
push ebx
.text:
0040EC38
push esi ; Increment
.text:
0040EC39
push edi ; Apc
.text:
0040EC3A
mov edi, [ebp
+
Apc]
.text:
0040EC3D
mov esi, [edi
+
_KAPC.Thread]
.text:
0040EC40
lea ecx, [esi
+
_KTHREAD.ApcQueueLock]
.text:
0040EC46
lea edx, [ebp
+
LockHandle]
.text:
0040EC49
call ds:__imp_@KeAcquireInStackQueuedSpinLockRaiseToSynch@
8
; KeAcquireInStackQueuedSpinLockRaiseToSynch(x,x)
.text:
0040EC4F
mov eax, large fs:
20h
.text:
0040EC55
lea ecx, [eax
+
418h
]
.text:
0040EC5B
call @KeAcquireQueuedSpinLockAtDpcLevel@
4
.text:
0040EC2F
;
int
__stdcall KeInsertQueueApc(PRKAPC Apc, PVOID SystemArgument1, PVOID SystemArgument2, KPRIORITY Increment)
.text:
0040EC2F
public _KeInsertQueueApc@
16
.text:
0040EC2F
_KeInsertQueueApc@
16
proc near ; CODE XREF: ExpTimerDpcRoutine(x,x,x,x)
+
30
↓p
.text:
0040EC2F
; IopfCompleteRequest(x,x)
+
11528
↓p ...
.text:
0040EC2F
.text:
0040EC2F
LockHandle
=
_KLOCK_QUEUE_HANDLE ptr
-
0Ch
.text:
0040EC2F
Apc
=
dword ptr
8
.text:
0040EC2F
SystemArgument1
=
dword ptr
0Ch
.text:
0040EC2F
SystemArgument2
=
dword ptr
10h
.text:
0040EC2F
Increment
=
dword ptr
14h
.text:
0040EC2F
.text:
0040EC2F
mov edi, edi
.text:
0040EC31
push ebp
.text:
0040EC32
mov ebp, esp
.text:
0040EC34
sub esp,
0Ch
.text:
0040EC37
push ebx
.text:
0040EC38
push esi ; Increment
.text:
0040EC39
push edi ; Apc
.text:
0040EC3A
mov edi, [ebp
+
Apc]
.text:
0040EC3D
mov esi, [edi
+
_KAPC.Thread]
.text:
0040EC40
lea ecx, [esi
+
_KTHREAD.ApcQueueLock]
.text:
0040EC46
lea edx, [ebp
+
LockHandle]
.text:
0040EC49
call ds:__imp_@KeAcquireInStackQueuedSpinLockRaiseToSynch@
8
; KeAcquireInStackQueuedSpinLockRaiseToSynch(x,x)
.text:
0040EC4F
mov eax, large fs:
20h
.text:
0040EC55
lea ecx, [eax
+
418h
]
.text:
0040EC5B
call @KeAcquireQueuedSpinLockAtDpcLevel@
4
.text:
0040EC60
xor bl, bl ; bl清
0
.text:
0040EC62
cmp
[esi
+
_KTHREAD.ApcQueueable], bl ; 判断ApcQueueable是否为
0
.text:
0040EC68
jz short loc_40EC82
.text:
0040EC60
xor bl, bl ; bl清
0
.text:
0040EC62
cmp
[esi
+
_KTHREAD.ApcQueueable], bl ; 判断ApcQueueable是否为
0
.text:
0040EC68
jz short loc_40EC82
.text:
0040EC6A
mov eax, [ebp
+
SystemArgument1]
.text:
0040EC6D
mov edx, [ebp
+
Increment]
.text:
0040EC70
mov [edi
+
KAPC.SystemArgument1], eax
.text:
0040EC73
mov eax, [ebp
+
SystemArgument2]
.text:
0040EC76
mov ecx, edi
.text:
0040EC78
mov [edi
+
KAPC.SystemArgument2], eax
.text:
0040EC7B
call @KiInsertQueueApc@
8
; KiInsertQueueApc(x,x)
.text:
0040EC80
mov bl, al ; 将返回值赋给bl
.text:
0040EC6A
mov eax, [ebp
+
SystemArgument1]
.text:
0040EC6D
mov edx, [ebp
+
Increment]
.text:
0040EC70
mov [edi
+
KAPC.SystemArgument1], eax
.text:
0040EC73
mov eax, [ebp
+
SystemArgument2]
.text:
0040EC76
mov ecx, edi
.text:
0040EC78
mov [edi
+
KAPC.SystemArgument2], eax
.text:
0040EC7B
call @KiInsertQueueApc@
8
; KiInsertQueueApc(x,x)
.text:
0040EC80
mov bl, al ; 将返回值赋给bl
.text:
0040EC82
loc_40EC82: ; CODE XREF: KeInsertQueueApc(x,x,x,x)
+
39
↑j
.text:
0040EC82
mov eax, large fs:
20h
.text:
0040EC88
lea ecx, [eax
+
418h
]
.text:
0040EC8E
call @KeReleaseQueuedSpinLockFromDpcLevel@
4
; KeReleaseQueuedSpinLockFromDpcLevel(x)
.text:
0040EC93
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
0040EC96
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
; KeReleaseInStackQueuedSpinLock(x)
.text:
0040EC9C
pop edi
.text:
0040EC9D
pop esi
.text:
0040EC9E
mov al, bl ; 用bl赋值给al作为返回值
.text:
0040ECA0
pop ebx
.text:
0040ECA1
leave
.text:
0040ECA2
retn
10h
.text:
0040ECA2
_KeInsertQueueApc@
16
endp
.text:
0040EC82
loc_40EC82: ; CODE XREF: KeInsertQueueApc(x,x,x,x)
+
39
↑j
.text:
0040EC82
mov eax, large fs:
20h
.text:
0040EC88
lea ecx, [eax
+
418h
]
.text:
0040EC8E
call @KeReleaseQueuedSpinLockFromDpcLevel@
4
; KeReleaseQueuedSpinLockFromDpcLevel(x)
.text:
0040EC93
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
0040EC96
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
; KeReleaseInStackQueuedSpinLock(x)
.text:
0040EC9C
pop edi
.text:
0040EC9D
pop esi
.text:
0040EC9E
mov al, bl ; 用bl赋值给al作为返回值
.text:
0040ECA0
pop ebx
.text:
0040ECA1
leave
.text:
0040ECA2
retn
10h
.text:
0040ECA2
_KeInsertQueueApc@
16
endp
.text:
00402C6A
;
int
__cdecl KiInsertQueueApc(PKAPC Apc, KPRIORITY Increment)
.text:
00402C6A
@KiInsertQueueApc@
8
proc near ; CODE XREF: KeInsertQueueApc(x,x,x,x)
+
4C
↓p
.text:
00402C6A
; KeSuspendThread(x)
+
68
↓p ...
.text:
00402C6A
.text:
00402C6A
var_Increament
=
dword ptr
-
4
.text:
00402C6A
Apc
=
dword ptr
8
.text:
00402C6A
Increment
=
dword ptr
0Ch
.text:
00402C6A
.text:
00402C6A
mov edi, edi
.text:
00402C6C
push ebp
.text:
00402C6D
mov ebp, esp
.text:
00402C6F
push ecx
.text:
00402C70
mov eax, ecx
.text:
00402C72
cmp
[eax
+
KAPC.Inserted],
0
; APC是否已经插入到线程中
.text:
00402C76
mov ecx, [eax
+
_KAPC.Thread] ; 将线程对象赋给ecx
.text:
00402C79
mov [ebp
+
var_Increament], edx
.text:
00402C7C
jnz loc_44B3BF
.text:
00402C82
cmp
[eax
+
KAPC.ApcStateIndex],
3
; ApcStateIndex是否等于
3
.text:
00402C86
jz loc_44B3C3
.text:
00402C6A
;
int
__cdecl KiInsertQueueApc(PKAPC Apc, KPRIORITY Increment)
.text:
00402C6A
@KiInsertQueueApc@
8
proc near ; CODE XREF: KeInsertQueueApc(x,x,x,x)
+
4C
↓p
.text:
00402C6A
; KeSuspendThread(x)
+
68
↓p ...
.text:
00402C6A
.text:
00402C6A
var_Increament
=
dword ptr
-
4
.text:
00402C6A
Apc
=
dword ptr
8
.text:
00402C6A
Increment
=
dword ptr
0Ch
.text:
00402C6A
.text:
00402C6A
mov edi, edi
.text:
00402C6C
push ebp
.text:
00402C6D
mov ebp, esp
.text:
00402C6F
push ecx
.text:
00402C70
mov eax, ecx
.text:
00402C72
cmp
[eax
+
KAPC.Inserted],
0
; APC是否已经插入到线程中
.text:
00402C76
mov ecx, [eax
+
_KAPC.Thread] ; 将线程对象赋给ecx
.text:
00402C79
mov [ebp
+
var_Increament], edx
.text:
00402C7C
jnz loc_44B3BF
.text:
00402C82
cmp
[eax
+
KAPC.ApcStateIndex],
3
; ApcStateIndex是否等于
3
.text:
00402C86
jz loc_44B3C3
.text:
0044B3C3
loc_44B3C3: ; CODE XREF: KiInsertQueueApc(x,x)
+
1C
↑j
.text:
0044B3C3
mov dl, [ecx
+
_KTHREAD.ApcStateIndex]
.text:
0044B3C9
mov [eax
+
KAPC.ApcStateIndex], dl
.text:
0044B3CC
jmp loc_402C8C
.text:
0044B3C3
loc_44B3C3: ; CODE XREF: KiInsertQueueApc(x,x)
+
1C
↑j
.text:
0044B3C3
mov dl, [ecx
+
_KTHREAD.ApcStateIndex]
.text:
0044B3C9
mov [eax
+
KAPC.ApcStateIndex], dl
.text:
0044B3CC
jmp loc_402C8C
.text:
00402C8C
loc_402C8C: ; CODE XREF: KiInsertQueueApc(x,x)
+
48762
↓j
.text:
00402C8C
cmp
[eax
+
KAPC.NormalRoutine],
0
; NormalRoutine是否为NULL
.text:
00402C90
movsx edx, [eax
+
KAPC.ApcStateIndex] ; 将ApcStateIndex赋给edx
.text:
00402C94
push ebx
.text:
00402C95
push esi
.text:
00402C96
push edi
.text:
00402C97
mov edi, [ecx
+
edx
*
4
+
_KTHREAD.ApcStatePointer] ; 将相应的KAPC_STATE赋给edi
.text:
00402C9E
mov dl, [eax
+
KAPC.ApcMode] ; 将ApcMode赋给dl
.text:
00402CA1
jnz loc_41049E
.text:
00402C8C
loc_402C8C: ; CODE XREF: KiInsertQueueApc(x,x)
+
48762
↓j
.text:
00402C8C
cmp
[eax
+
KAPC.NormalRoutine],
0
; NormalRoutine是否为NULL
.text:
00402C90
movsx edx, [eax
+
KAPC.ApcStateIndex] ; 将ApcStateIndex赋给edx
.text:
00402C94
push ebx
.text:
00402C95
push esi
.text:
00402C96
push edi
.text:
00402C97
mov edi, [ecx
+
edx
*
4
+
_KTHREAD.ApcStatePointer] ; 将相应的KAPC_STATE赋给edi
.text:
00402C9E
mov dl, [eax
+
KAPC.ApcMode] ; 将ApcMode赋给dl
.text:
00402CA1
jnz loc_41049E
.text:
00402CA7
movsx esi, dl ; 将ApcMode赋给esi
.text:
00402CAA
lea edi, [edi
+
esi
*
8
] ; 将KAPC_STATE地址赋给edi
.text:
00402CAD
mov esi, [edi
+
LIST_ENTRY.Blink] ; 取出队列中的上一个APC
.text:
00402CA7
movsx esi, dl ; 将ApcMode赋给esi
.text:
00402CAA
lea edi, [edi
+
esi
*
8
] ; 将KAPC_STATE地址赋给edi
.text:
00402CAD
mov esi, [edi
+
LIST_ENTRY.Blink] ; 取出队列中的上一个APC
.text:
00402CB0
loc_402CB0: ; CODE XREF: KiInsertQueueApc(x,x)
+
4876A
↓j
.text:
00402CB0
cmp
esi, edi ; 判断上一个APC是否等于线程APC_STATE地址
.text:
00402CB2
jnz loc_42615A
.text:
00402CB0
loc_402CB0: ; CODE XREF: KiInsertQueueApc(x,x)
+
4876A
↓j
.text:
00402CB0
cmp
esi, edi ; 判断上一个APC是否等于线程APC_STATE地址
.text:
00402CB2
jnz loc_42615A
.text:
0042615A
loc_42615A: ; CODE XREF: KiInsertQueueApc(x,x)
+
48
↑j
.text:
0042615A
cmp
[esi
+
KAPC.ApcListEntry.Blink],
0
.text:
0042615E
jz loc_402CB8
.text:
00426164
jmp loc_44B3D1
.text:
0042615A
loc_42615A: ; CODE XREF: KiInsertQueueApc(x,x)
+
48
↑j
.text:
0042615A
cmp
[esi
+
KAPC.ApcListEntry.Blink],
0
.text:
0042615E
jz loc_402CB8
.text:
00426164
jmp loc_44B3D1
.text:
0044B3D1
loc_44B3D1: ; CODE XREF: KiInsertQueueApc(x,x)
+
234FA
↑j
.text:
0044B3D1
mov esi, [esi
+
LIST_ENTRY.Blink]
.text:
0044B3D4
jmp loc_402CB0
.text:
0044B3D1
loc_44B3D1: ; CODE XREF: KiInsertQueueApc(x,x)
+
234FA
↑j
.text:
0044B3D1
mov esi, [esi
+
LIST_ENTRY.Blink]
.text:
0044B3D4
jmp loc_402CB0
.text:
00402CB8
loc_402CB8: ; CODE XREF: KiInsertQueueApc(x,x)
+
234F4
↓j
.text:
00402CB8
mov ebx, [esi
+
LIST_ENTRY.Flink]
.text:
00402CBA
lea edi, [eax
+
_KAPC.ApcListEntry]
.text:
00402CBD
mov [edi
+
LIST_ENTRY.Flink], ebx
.text:
00402CBF
mov [edi
+
LIST_ENTRY.Blink], esi
.text:
00402CC2
mov [ebx
+
LIST_ENTRY.Blink], edi
.text:
00402CC5
mov [esi
+
LIST_ENTRY.Flink], edi
.text:
00402CB8
loc_402CB8: ; CODE XREF: KiInsertQueueApc(x,x)
+
234F4
↓j
.text:
00402CB8
mov ebx, [esi
+
LIST_ENTRY.Flink]
.text:
00402CBA
lea edi, [eax
+
_KAPC.ApcListEntry]
.text:
00402CBD
mov [edi
+
LIST_ENTRY.Flink], ebx
.text:
00402CBF
mov [edi
+
LIST_ENTRY.Blink], esi
.text:
00402CC2
mov [ebx
+
LIST_ENTRY.Blink], edi
.text:
00402CC5
mov [esi
+
LIST_ENTRY.Flink], edi
.text:
0041049E
loc_41049E: ; CODE XREF: KiInsertQueueApc(x,x)
+
37
↑j
.text:
0041049E
test dl, dl ; 判断ApcMode是否为
0
.text:
004104A0
jz short loc_4104AF
.text:
004104A2
cmp
[eax
+
KAPC.KernelRoutine], offset _PsExitSpecialApc@
20
; PsExitSpecialApc(x,x,x,x,x)
.text:
004104A9
jz loc_42950C
.text:
0041049E
loc_41049E: ; CODE XREF: KiInsertQueueApc(x,x)
+
37
↑j
.text:
0041049E
test dl, dl ; 判断ApcMode是否为
0
.text:
004104A0
jz short loc_4104AF
.text:
004104A2
cmp
[eax
+
KAPC.KernelRoutine], offset _PsExitSpecialApc@
20
; PsExitSpecialApc(x,x,x,x,x)
.text:
004104A9
jz loc_42950C
.text:
004104AF
loc_4104AF: ; CODE XREF: KiInsertQueueApc(x,x)
+
D836↑j
.text:
004104AF
movsx ebx, dl ; 将ApcMode赋给ebx
.text:
004104B2
lea edi, [edi
+
ebx
*
8
] ; 取出KAPC_STATE地址赋给edi
.text:
004104B5
mov ebx, [edi
+
LIST_ENTRY.Blink] ; 将KAPC_STATE的上一个APC对象赋给ebx
.text:
004104B8
lea esi, [eax
+
KAPC.ApcListEntry] ; 将KAPC的ApcListEntry地址赋给esi
.text:
004104BB
mov [esi
+
LIST_ENTRY.Flink], edi
.text:
004104BD
mov [esi
+
LIST_ENTRY.Blink], ebx
.text:
004104C0
mov [ebx
+
LIST_ENTRY.Flink], esi
.text:
004104C2
mov [edi
+
LIST_ENTRY.Blink], esi
.text:
004104C5
jmp loc_402CC7
.text:
004104AF
loc_4104AF: ; CODE XREF: KiInsertQueueApc(x,x)
+
D836↑j
.text:
004104AF
movsx ebx, dl ; 将ApcMode赋给ebx
.text:
004104B2
lea edi, [edi
+
ebx
*
8
] ; 取出KAPC_STATE地址赋给edi
.text:
004104B5
mov ebx, [edi
+
LIST_ENTRY.Blink] ; 将KAPC_STATE的上一个APC对象赋给ebx
.text:
004104B8
lea esi, [eax
+
KAPC.ApcListEntry] ; 将KAPC的ApcListEntry地址赋给esi
.text:
004104BB
mov [esi
+
LIST_ENTRY.Flink], edi
.text:
004104BD
mov [esi
+
LIST_ENTRY.Blink], ebx
.text:
004104C0
mov [ebx
+
LIST_ENTRY.Flink], esi
.text:
004104C2
mov [edi
+
LIST_ENTRY.Blink], esi
.text:
004104C5
jmp loc_402CC7
.text:
0042950C
loc_42950C: ; CODE XREF: KiInsertQueueApc(x,x)
+
D83F↑j
.text:
0042950C
movsx ebx, dl ; 将ApcMode赋给ebx
.text:
0042950F
mov [ecx
+
_KTHREAD.ApcState.UserApcPending],
1
.text:
00429513
lea edi, [edi
+
ebx
*
8
]
.text:
00429516
mov ebx, [edi
+
LIST_ENTRY.Flink]
.text:
00429518
lea esi, [eax
+
KAPC.ApcListEntry]
.text:
0042951B
mov [esi
+
LIST_ENTRY.Flink], ebx
.text:
0042951D
mov [esi
+
LIST_ENTRY.Blink], edi
.text:
00429520
mov [ebx
+
LIST_ENTRY.Blink], esi
.text:
00429523
mov [edi
+
LIST_ENTRY.Flink], esi
.text:
00429525
jmp loc_402CC7
.text:
0042950C
loc_42950C: ; CODE XREF: KiInsertQueueApc(x,x)
+
D83F↑j
.text:
0042950C
movsx ebx, dl ; 将ApcMode赋给ebx
.text:
0042950F
mov [ecx
+
_KTHREAD.ApcState.UserApcPending],
1
.text:
00429513
lea edi, [edi
+
ebx
*
8
]
.text:
00429516
mov ebx, [edi
+
LIST_ENTRY.Flink]
.text:
00429518
lea esi, [eax
+
KAPC.ApcListEntry]
.text:
0042951B
mov [esi
+
LIST_ENTRY.Flink], ebx
.text:
0042951D
mov [esi
+
LIST_ENTRY.Blink], edi
.text:
00429520
mov [ebx
+
LIST_ENTRY.Blink], esi
.text:
00429523
mov [edi
+
LIST_ENTRY.Flink], esi
.text:
00429525
jmp loc_402CC7
.text:
00402CC7
loc_402CC7: ; CODE XREF: KiInsertQueueApc(x,x)
+
D85B↓j
.text:
00402CC7
; KiInsertQueueApc(x,x)
+
268BB
↓j
.text:
00402CC7
movsx edi, [eax
+
KAPC.ApcStateIndex]
.text:
00402CCB
mov [eax
+
KAPC.Inserted],
1
.text:
00402CCF
movzx esi, [ecx
+
_KTHREAD.ApcStateIndex]
.text:
00402CD6
cmp
edi, esi
.text:
00402CD8
pop edi
.text:
00402CD9
pop esi
.text:
00402CDA
pop ebx
.text:
00402CDB
jnz short loc_402D12
.text:
00402CC7
loc_402CC7: ; CODE XREF: KiInsertQueueApc(x,x)
+
D85B↓j
.text:
00402CC7
; KiInsertQueueApc(x,x)
+
268BB
↓j
.text:
00402CC7
movsx edi, [eax
+
KAPC.ApcStateIndex]
.text:
00402CCB
mov [eax
+
KAPC.Inserted],
1
.text:
00402CCF
movzx esi, [ecx
+
_KTHREAD.ApcStateIndex]
.text:
00402CD6
cmp
edi, esi
.text:
00402CD8
pop edi
.text:
00402CD9
pop esi
.text:
00402CDA
pop ebx
.text:
00402CDB
jnz short loc_402D12
.text:
00402CDD
test dl, dl
.text:
00402CDF
jnz loc_4106A4
.text:
00402CDD
test dl, dl
.text:
00402CDF
jnz loc_4106A4
.text:
00402CE5
mov dl, [ecx
+
_KTHREAD.State]
.text:
00402CE8
cmp
dl,
2
.text:
00402CEB
mov [ecx
+
_KTHREAD.ApcState.KernelApcPending],
1
.text:
00402CEF
jnz loc_40EEB3
.text:
00402CE5
mov dl, [ecx
+
_KTHREAD.State]
.text:
00402CE8
cmp
dl,
2
.text:
00402CEB
mov [ecx
+
_KTHREAD.ApcState.KernelApcPending],
1
.text:
00402CEF
jnz loc_40EEB3
.text:
004106A4
loc_4106A4: ; CODE XREF: KiInsertQueueApc(x,x)
+
75
↑j
.text:
004106A4
cmp
[ecx
+
_KTHREAD.State],
5
.text:
004106A8
jnz loc_402D12
.text:
004106AE
cmp
[ecx
+
_KTHREAD.WaitMode],
1
.text:
004106B2
jnz loc_402D12
.text:
004106B8
cmp
[ecx
+
_KTHREAD.Alertable],
0
.text:
004106BF
jz loc_432270
.text:
004106A4
loc_4106A4: ; CODE XREF: KiInsertQueueApc(x,x)
+
75
↑j
.text:
004106A4
cmp
[ecx
+
_KTHREAD.State],
5
.text:
004106A8
jnz loc_402D12
.text:
004106AE
cmp
[ecx
+
_KTHREAD.WaitMode],
1
.text:
004106B2
jnz loc_402D12
.text:
004106B8
cmp
[ecx
+
_KTHREAD.Alertable],
0
.text:
004106BF
jz loc_432270
.text:
004106C5
loc_4106C5: ; CODE XREF: KiInsertQueueApc(x,x)
+
2F610
↓j
.text:
004106C5
mov [ecx
+
_KTHREAD.ApcState.UserApcPending],
1
.text:
004106C9
push
0
.text:
004106CB
mov edx,
0C0h
.text:
004106D0
jmp loc_40EED7
.text:
004106C5
loc_4106C5: ; CODE XREF: KiInsertQueueApc(x,x)
+
2F610
↓j
.text:
004106C5
mov [ecx
+
_KTHREAD.ApcState.UserApcPending],
1
.text:
004106C9
push
0
.text:
004106CB
mov edx,
0C0h
.text:
004106D0
jmp loc_40EED7
.text:
00405E01
;
int
__stdcall KiDeliverApc(KPROCESSOR_MODE PreviousMode,
int
,
int
)
.text:
00405E01
public _KiDeliverApc@
12
.text:
00405E01
_KiDeliverApc@
12
proc near ; CODE XREF: KiUnlockDispatcherDatabase(x)
+
CA↑p
.text:
00405E01
; _KiServiceExit
+
54
↓p ...
.text:
00405E01
.text:
00405E01
LockHandle
=
_KLOCK_QUEUE_HANDLE ptr
-
28h
.text:
00405E01
var_TrapFrame
=
dword ptr
-
1Ch
.text:
00405E01
var_EPROCESS
=
dword ptr
-
18h
.text:
00405E01
var_KernelRoutine
=
dword ptr
-
14h
.text:
00405E01
NormalContext
=
dword ptr
-
10h
.text:
00405E01
SystemArgument1
=
dword ptr
-
0Ch
.text:
00405E01
SystemArgument2
=
dword ptr
-
8
.text:
00405E01
NormalRoutine
=
dword ptr
-
4
.text:
00405E01
PreviousMode
=
byte ptr
8
.text:
00405E01
ExceptionFrame
=
dword ptr
0Ch
.text:
00405E01
TrapFrame
=
dword ptr
10h
.text:
00405E01
.text:
00405E01
mov edi, edi
.text:
00405E03
push ebp
.text:
00405E04
mov ebp, esp
.text:
00405E06
sub esp,
28h
.text:
00405E09
mov ecx, [ebp
+
TrapFrame] ; 将TrapFrame地址赋给ecx
.text:
00405E0C
test ecx, ecx
.text:
00405E0E
jz short loc_405E20
.text:
00405E10
mov edx, [ecx
+
68h
] ; 从TrapFrame中取出eip赋给edx
.text:
00405E13
mov eax, offset _ExpInterlockedPopEntrySListResume@
0
; ExpInterlockedPopEntrySListResume()
.text:
00405E18
cmp
edx, eax
.text:
00405E1A
jnb loc_41137B
.text:
00405E20
.text:
00405E20
loc_405E20: ; CODE XREF: KiDeliverApc(x,x,x)
+
D↑j
.text:
00405E20
; KiDeliverApc(x,x,x)
+
B580↓j ...
.text:
00405E20
push ebx
.text:
00405E21
push esi
.text:
00405E22
push edi
.text:
00405E23
mov eax, large fs:
124h
; 将线程对象地址赋给eax
.text:
00405E29
mov esi, eax ; 将线程对象地址赋给edi
.text:
00405E2B
mov eax, [esi
+
_KTHREAD.TrapFrame]
.text:
00405E31
mov [ebp
+
var_TrapFrame], eax
.text:
00405E34
mov eax, [esi
+
_KTHREAD.ApcState.Process]
.text:
00405E37
mov [esi
+
_KTHREAD.TrapFrame], ecx
.text:
00405E3D
lea ecx, [esi
+
_KTHREAD.ApcQueueLock] ; SpinLock
.text:
00405E43
lea edx, [ebp
+
LockHandle] ; LockHandle
.text:
00405E46
mov [ebp
+
var_EPROCESS], eax
.text:
00405E49
call ds:__imp_@KeAcquireInStackQueuedSpinLock@
8
; KeAcquireInStackQueuedSpinLock(x,x)
.text:
00405E4F
mov [esi
+
_KTHREAD.ApcState.KernelApcPending],
0
; 将KernelApcPending赋值为
0
.text:
00405E01
;
int
__stdcall KiDeliverApc(KPROCESSOR_MODE PreviousMode,
int
,
int
)
.text:
00405E01
public _KiDeliverApc@
12
.text:
00405E01
_KiDeliverApc@
12
proc near ; CODE XREF: KiUnlockDispatcherDatabase(x)
+
CA↑p
.text:
00405E01
; _KiServiceExit
+
54
↓p ...
.text:
00405E01
.text:
00405E01
LockHandle
=
_KLOCK_QUEUE_HANDLE ptr
-
28h
.text:
00405E01
var_TrapFrame
=
dword ptr
-
1Ch
.text:
00405E01
var_EPROCESS
=
dword ptr
-
18h
.text:
00405E01
var_KernelRoutine
=
dword ptr
-
14h
.text:
00405E01
NormalContext
=
dword ptr
-
10h
.text:
00405E01
SystemArgument1
=
dword ptr
-
0Ch
.text:
00405E01
SystemArgument2
=
dword ptr
-
8
.text:
00405E01
NormalRoutine
=
dword ptr
-
4
.text:
00405E01
PreviousMode
=
byte ptr
8
.text:
00405E01
ExceptionFrame
=
dword ptr
0Ch
.text:
00405E01
TrapFrame
=
dword ptr
10h
.text:
00405E01
.text:
00405E01
mov edi, edi
.text:
00405E03
push ebp
.text:
00405E04
mov ebp, esp
.text:
00405E06
sub esp,
28h
.text:
00405E09
mov ecx, [ebp
+
TrapFrame] ; 将TrapFrame地址赋给ecx
.text:
00405E0C
test ecx, ecx
.text:
00405E0E
jz short loc_405E20
.text:
00405E10
mov edx, [ecx
+
68h
] ; 从TrapFrame中取出eip赋给edx
.text:
00405E13
mov eax, offset _ExpInterlockedPopEntrySListResume@
0
; ExpInterlockedPopEntrySListResume()
.text:
00405E18
cmp
edx, eax
.text:
00405E1A
jnb loc_41137B
.text:
00405E20
.text:
00405E20
loc_405E20: ; CODE XREF: KiDeliverApc(x,x,x)
+
D↑j
.text:
00405E20
; KiDeliverApc(x,x,x)
+
B580↓j ...
.text:
00405E20
push ebx
.text:
00405E21
push esi
.text:
00405E22
push edi
.text:
00405E23
mov eax, large fs:
124h
; 将线程对象地址赋给eax
.text:
00405E29
mov esi, eax ; 将线程对象地址赋给edi
.text:
00405E2B
mov eax, [esi
+
_KTHREAD.TrapFrame]
.text:
00405E31
mov [ebp
+
var_TrapFrame], eax
.text:
00405E34
mov eax, [esi
+
_KTHREAD.ApcState.Process]
.text:
00405E37
mov [esi
+
_KTHREAD.TrapFrame], ecx
.text:
00405E3D
lea ecx, [esi
+
_KTHREAD.ApcQueueLock] ; SpinLock
.text:
00405E43
lea edx, [ebp
+
LockHandle] ; LockHandle
.text:
00405E46
mov [ebp
+
var_EPROCESS], eax
.text:
00405E49
call ds:__imp_@KeAcquireInStackQueuedSpinLock@
8
; KeAcquireInStackQueuedSpinLock(x,x)
.text:
00405E4F
mov [esi
+
_KTHREAD.ApcState.KernelApcPending],
0
; 将KernelApcPending赋值为
0
.text:
00405E53
lea ebx, [esi
+
_KTHREAD.ApcState]
.text:
00405E56
.text:
00405E56
loc_405E56: ; CODE XREF: KiDeliverApc(x,x,x)
+
14FDD
↓j
.text:
00405E56
; KiDeliverApc(x,x,x)
+
15E53
↓j ...
.text:
00405E56
cmp
[ebx
+
LIST_ENTRY.Flink], ebx
.text:
00405E58
jnz loc_41BBEF
.text:
00405E53
lea ebx, [esi
+
_KTHREAD.ApcState]
.text:
00405E56
.text:
00405E56
loc_405E56: ; CODE XREF: KiDeliverApc(x,x,x)
+
14FDD
↓j
.text:
00405E56
; KiDeliverApc(x,x,x)
+
15E53
↓j ...
.text:
00405E56
cmp
[ebx
+
LIST_ENTRY.Flink], ebx
.text:
00405E58
jnz loc_41BBEF
.text:
0041BBEF
loc_41BBEF: ; CODE XREF: KiDeliverApc(x,x,x)
+
57
↑j
.text:
0041BBEF
mov eax, [ebx
+
LIST_ENTRY.Flink] ; 获取内核APC链表中的APC对象
.text:
0041BBF1
lea edi, [eax
-
0Ch
] ; 获取APC对象的地址
.text:
0041BBEF
loc_41BBEF: ; CODE XREF: KiDeliverApc(x,x,x)
+
57
↑j
.text:
0041BBEF
mov eax, [ebx
+
LIST_ENTRY.Flink] ; 获取内核APC链表中的APC对象
.text:
0041BBF1
lea edi, [eax
-
0Ch
] ; 获取APC对象的地址
.text:
0041BBEF
loc_41BBEF: ; CODE XREF: KiDeliverApc(x,x,x)
+
57
↑j
.text:
0041BBEF
mov eax, [ebx
+
LIST_ENTRY.Flink] ; 获取内核APC链表中的APC对象
.text:
0041BBF1
lea edi, [eax
-
0Ch
] ; 获取APC对象的地址
.text:
0041BBF4
mov ecx, [edi
+
KAPC.KernelRoutine]
.text:
0041BBF7
mov [ebp
+
var_KernelRoutine], ecx
.text:
0041BBFA
mov ecx, [edi
+
KAPC.NormalRoutine]
.text:
0041BBFD
test ecx, ecx ; 判断NormalRoutine是否为NULL
.text:
0041BBFF
mov [ebp
+
NormalRoutine], ecx
.text:
0041BC02
mov edx, [edi
+
KAPC.NormalContext]
.text:
0041BC05
mov [ebp
+
NormalContext], edx
.text:
0041BC08
mov edx, [edi
+
KAPC.SystemArgument1]
.text:
0041BC0B
mov [ebp
+
SystemArgument1], edx
.text:
0041BC0E
mov edx, [edi
+
KAPC.SystemArgument2]
.text:
0041BC11
mov [ebp
+
SystemArgument2], edx
.text:
0041BC14
jnz loc_41AD60
.text:
0041BBEF
loc_41BBEF: ; CODE XREF: KiDeliverApc(x,x,x)
+
57
↑j
.text:
0041BBEF
mov eax, [ebx
+
LIST_ENTRY.Flink] ; 获取内核APC链表中的APC对象
.text:
0041BBF1
lea edi, [eax
-
0Ch
] ; 获取APC对象的地址
.text:
0041BBF4
mov ecx, [edi
+
KAPC.KernelRoutine]
.text:
0041BBF7
mov [ebp
+
var_KernelRoutine], ecx
.text:
0041BBFA
mov ecx, [edi
+
KAPC.NormalRoutine]
.text:
0041BBFD
test ecx, ecx ; 判断NormalRoutine是否为NULL
.text:
0041BBFF
mov [ebp
+
NormalRoutine], ecx
.text:
0041BC02
mov edx, [edi
+
KAPC.NormalContext]
.text:
0041BC05
mov [ebp
+
NormalContext], edx
.text:
0041BC08
mov edx, [edi
+
KAPC.SystemArgument1]
.text:
0041BC0B
mov [ebp
+
SystemArgument1], edx
.text:
0041BC0E
mov edx, [edi
+
KAPC.SystemArgument2]
.text:
0041BC11
mov [ebp
+
SystemArgument2], edx
.text:
0041BC14
jnz loc_41AD60
.text:
0041BC1A
mov ecx, [eax
+
LIST_ENTRY.Flink] ; 将APC对象从链表中删除
.text:
0041BC1C
mov eax, [eax
+
LIST_ENTRY.Blink]
.text:
0041BC1F
mov [eax
+
LIST_ENTRY.Flink], ecx
.text:
0041BC21
mov [ecx
+
LIST_ENTRY.Blink], eax
.text:
0041BC24
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
0041BC27
mov [edi
+
KAPC.Inserted],
0
; 将Inserted赋值为
0
.text:
0041BC2B
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
; KeReleaseInStackQueuedSpinLock(x)
.text:
0041BC31
lea eax, [ebp
+
SystemArgument2]
.text:
0041BC34
push eax
.text:
0041BC35
lea eax, [ebp
+
SystemArgument1]
.text:
0041BC38
push eax
.text:
0041BC39
lea eax, [ebp
+
NormalContext]
.text:
0041BC3C
push eax
.text:
0041BC3D
lea eax, [ebp
+
NormalRoutine]
.text:
0041BC40
push eax
.text:
0041BC41
push edi
.text:
0041BC42
call [ebp
+
var_KernelRoutine]
.text:
0041BC45
lea edx, [ebp
+
LockHandle] ; LockHandle
.text:
0041BC48
lea ecx, [esi
+
_KTHREAD.ApcQueueLock] ; SpinLock
.text:
0041BC4E
call ds:__imp_@KeAcquireInStackQueuedSpinLock@
8
; KeAcquireInStackQueuedSpinLock(x,x)
.text:
0041BC54
jmp loc_405E56
.text:
0041BC1A
mov ecx, [eax
+
LIST_ENTRY.Flink] ; 将APC对象从链表中删除
.text:
0041BC1C
mov eax, [eax
+
LIST_ENTRY.Blink]
.text:
0041BC1F
mov [eax
+
LIST_ENTRY.Flink], ecx
.text:
0041BC21
mov [ecx
+
LIST_ENTRY.Blink], eax
.text:
0041BC24
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
0041BC27
mov [edi
+
KAPC.Inserted],
0
; 将Inserted赋值为
0
.text:
0041BC2B
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
; KeReleaseInStackQueuedSpinLock(x)
.text:
0041BC31
lea eax, [ebp
+
SystemArgument2]
.text:
0041BC34
push eax
.text:
0041BC35
lea eax, [ebp
+
SystemArgument1]
.text:
0041BC38
push eax
.text:
0041BC39
lea eax, [ebp
+
NormalContext]
.text:
0041BC3C
push eax
.text:
0041BC3D
lea eax, [ebp
+
NormalRoutine]
.text:
0041BC40
push eax
.text:
0041BC41
push edi
.text:
0041BC42
call [ebp
+
var_KernelRoutine]
.text:
0041BC45
lea edx, [ebp
+
LockHandle] ; LockHandle
.text:
0041BC48
lea ecx, [esi
+
_KTHREAD.ApcQueueLock] ; SpinLock
.text:
0041BC4E
call ds:__imp_@KeAcquireInStackQueuedSpinLock@
8
; KeAcquireInStackQueuedSpinLock(x,x)
.text:
0041BC54
jmp loc_405E56
.text:
0041AD60
loc_41AD60: ; CODE XREF: KiDeliverApc(x,x,x)
+
15E13
↓j
.text:
0041AD60
cmp
[esi
+
_KTHREAD.ApcState.KernelApcInProgress],
0
.text:
0041AD64
jnz loc_405E6B
.text:
0041AD6A
cmp
[esi
+
_KTHREAD.KernelApcDisable],
0
.text:
0041AD71
jnz loc_405E6B
.text:
0041AD60
loc_41AD60: ; CODE XREF: KiDeliverApc(x,x,x)
+
15E13
↓j
.text:
0041AD60
cmp
[esi
+
_KTHREAD.ApcState.KernelApcInProgress],
0
.text:
0041AD64
jnz loc_405E6B
.text:
0041AD6A
cmp
[esi
+
_KTHREAD.KernelApcDisable],
0
.text:
0041AD71
jnz loc_405E6B
.text:
00405E6B
loc_405E6B: ; CODE XREF: KiDeliverApc(x,x,x)
+
A6CD↓j
.text:
00405E6B
; KiDeliverApc(x,x,x)
+
A6D7↓j ...
.text:
00405E6B
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
00405E6E
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
.text:
00405E6B
loc_405E6B: ; CODE XREF: KiDeliverApc(x,x,x)
+
A6CD↓j
.text:
00405E6B
; KiDeliverApc(x,x,x)
+
A6D7↓j ...
.text:
00405E6B
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
00405E6E
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
.text:
0041AD77
mov ecx, [eax
+
LIST_ENTRY.Flink]
.text:
0041AD79
mov eax, [eax
+
LIST_ENTRY.Blink]
.text:
0041AD7C
mov [eax
+
LIST_ENTRY.Flink], ecx
.text:
0041AD7E
mov [ecx
+
LIST_ENTRY.Blink], eax
.text:
0041AD81
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
0041AD84
mov [edi
+
KAPC.Inserted],
0
.text:
0041AD88
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
.text:
0041AD77
mov ecx, [eax
+
LIST_ENTRY.Flink]
.text:
0041AD79
mov eax, [eax
+
LIST_ENTRY.Blink]
.text:
0041AD7C
mov [eax
+
LIST_ENTRY.Flink], ecx
.text:
0041AD7E
mov [ecx
+
LIST_ENTRY.Blink], eax
.text:
0041AD81
lea ecx, [ebp
+
LockHandle] ; LockHandle
.text:
0041AD84
mov [edi
+
KAPC.Inserted],
0
.text:
0041AD88
call ds:__imp_@KeReleaseInStackQueuedSpinLock@
4
.text:
0041AD8E
lea eax, [ebp
+
SystemArgument2]
.text:
0041AD91
push eax
.text:
0041AD92
lea eax, [ebp
+
SystemArgument1]
.text:
0041AD95
push eax
.text:
0041AD96
lea eax, [ebp
+
NormalContext]
.text:
0041AD99
push eax
.text:
0041AD9A
lea eax, [ebp
+
NormalRoutine]
.text:
0041AD9D
push eax
.text:
0041AD9E
push edi
.text:
0041AD9F
call [ebp
+
var_KernelRoutine]
.text:
0041AD8E
lea eax, [ebp
+
SystemArgument2]
.text:
0041AD91
push eax
.text:
0041AD92
lea eax, [ebp
+
SystemArgument1]
.text:
0041AD95
push eax
.text:
0041AD96
lea eax, [ebp
+
NormalContext]
.text:
0041AD99
push eax
.text:
0041AD9A
lea eax, [ebp
+
NormalRoutine]
.text:
0041AD9D
push eax
.text:
0041AD9E
push edi
.text:
0041AD9F
call [ebp
+
var_KernelRoutine]
.text:
0041ADA2
cmp
[ebp
+
NormalRoutine],
0
.text:
0041ADA6
jz short loc_41ADCB
.text:
0041ADA2
cmp
[ebp
+
NormalRoutine],
0
.text:
0041ADA6
jz short loc_41ADCB
.text:
0041ADA8
xor cl, cl ; NewIrql
.text:
0041ADAA
mov [esi
+
_KTHREAD.ApcState.KernelApcInProgress],
1
.text:
0041ADAE
call ds:__imp_@KfLowerIrql@
4
.text:
0041ADA8
xor cl, cl ; NewIrql
.text:
0041ADAA
mov [esi
+
_KTHREAD.ApcState.KernelApcInProgress],
1
.text:
0041ADAE
call ds:__imp_@KfLowerIrql@
4
.text:
0041ADB4
push [ebp
+
SystemArgument2]
.text:
0041ADB7
push [ebp
+
SystemArgument1]
.text:
0041ADBA
push [ebp
+
NormalContext]
.text:
0041ADBD
call [ebp
+
NormalRoutine]
.text:
0041ADB4
push [ebp
+
SystemArgument2]
.text:
0041ADB7
push [ebp
+
SystemArgument1]
.text:
0041ADBA
push [ebp
+
NormalContext]
.text:
0041ADBD
call [ebp
+
NormalRoutine]
.text:
0041ADC0
mov cl,
1
; NewIrql
.text:
0041ADC2
call ds:__imp_@KfRaiseIrql@
4
; KfRaiseIrql(x)
.text:
0041ADC8
mov [ebp
+
LockHandle.OldIrql], al
.text:
0041ADC0
mov cl,
1
; NewIrql
.text:
0041ADC2
call ds:__imp_@KfRaiseIrql@
4
; KfRaiseIrql(x)
.text:
0041ADC8
mov [ebp
+
LockHandle.OldIrql], al
.text:
0041ADCB
loc_41ADCB: ; CODE XREF: KiDeliverApc(x,x,x)
+
14FA5
↑j
.text:
0041ADCB
lea edx, [ebp
+
LockHandle] ; LockHandle
.text:
0041ADCE
lea ecx, [esi
+
_KTHREAD.ApcQueueLock] ; SpinLock
.text:
0041ADD4
call ds:__imp_@KeAcquireInStackQueuedSpinLock@
8
; KeAcquireInStackQueuedSpinLock(x,x)
.text:
0041ADDA
mov [esi
+
_KTHREAD.ApcState.KernelApcInProgress],
0
.text:
0041ADDE
jmp loc_405E56
.text:
0041ADCB
loc_41ADCB: ; CODE XREF: KiDeliverApc(x,x,x)
+
14FA5
↑j
.text:
0041ADCB
lea edx, [ebp
+
LockHandle] ; LockHandle
.text:
0041ADCE
lea ecx, [esi
+
_KTHREAD.ApcQueueLock] ; SpinLock
[培训]内核驱动高级班,冲击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