介绍
创建一个进程是通过NtCreateProcess开始执行的,它通过简单的对参数处理把任务交付给NtCreateProcessEx,然后NtCreateProcessEx检查ProcessHandle句柄是否可写,把真正的创建任务交给PspCreateProcess,所以PspCreateProcess才是真正的创建进程的函数。
在IDA的交叉引用中可以看到PspCreateProcess被三个函数引用,分别是NtCreateProcessEx、PsCreateSystemProcess 和PspInitPhase0。PspInitPhase0是系统初始化时调用的,PsCreateSystemProcess 用于创建系统进程,所以PspCreateProcess是创建进程真正的函数。
PspCreateProcess逆向
PAGE:004A92F6 64 A1 24 01 00 00 mov eax, large fs:_KPCR.PrcbData.CurrentThread ; 获取当前线程
PAGE:004A92FC 89 85 7C FF FF FF mov [ebp+MyCurrentThread], eax
PAGE:004A9302 8A 88 40 01 00 00 mov cl, [eax+_KTHREAD.PreviousMode] ; 获取PreviousMode先前模式
PAGE:004A9308 88 4D DF mov [ebp+PreviousMode], cl
PAGE:004A930B 8B 40 44 mov eax, [eax+_KTHREAD.ApcState.Process] ; 获取当前进程
PAGE:004A930E 89 45 A8 mov [ebp+Process], eax
PAGE:004A9311 33 F6 xor esi, esi
PAGE:004A9313 C6 45 E3 00 mov [ebp+var_1D], 0
PAGE:004A9317 89 75 B8 mov [ebp+var_48], esi
PAGE:004A931A 89 75 BC mov [ebp+var_44], esi
PAGE:004A931D F7 45 18 F0 FF FF FF test [ebp+Flags], 0FFFFFFF0h
PAGE:004A9324 0F 85 BE A2 07 00 jnz loc_5235E8 ; 判断FLAG为FFFFFFF0则ret
PAGE:004A9324
PAGE:004A932A 39 75 14 cmp [ebp+ParentProcess], esi ; 如果存在父进程 跳转
PAGE:004A932D 0F 84 54 B1 04 00 jz loc_4F4487
PAGE:004A932D
PAGE:004A9333 56 push esi ; HandleInformation
PAGE:004A9334 8D 45 80 lea eax, [ebp+var_80]
PAGE:004A9337 50 push eax ; Object
PAGE:004A9338 FF 75 DF push dword ptr [ebp+PreviousMode] ; AccessMode
PAGE:004A933B FF 35 58 A4 48 00 push _PsProcessType ; ObjectType
PAGE:004A9341 68 80 00 00 00 push 80h ; DesiredAccess
PAGE:004A9346 FF 75 14 push [ebp+ParentProcess] ; Handle
PAGE:004A9349 E8 9A 48 FE FF call _ObReferenceObjectByHandle@24 ; 对句柄进行访问验证
PAGE:004A9349 ; 根据提供的 Handle 值得到 Object
PAGE:004A9349
PAGE:004A934E 8B 4D 80 mov ecx, [ebp+var_80] ; Object
PAGE:004A9351 89 4D E4 mov [ebp+var_1C], ecx
PAGE:004A9354 3B C6 cmp eax, esi ; 判断返回值
PAGE:004A9356 0F 8C 4D 04 00 00 jl loc_4A97A9
PAGE:004A9356
PAGE:004A935C 39 75 28 cmp [ebp+arg_20], esi ; JobMemberLevel 是否为空
PAGE:004A935F 0F 85 72 A2 07 00 jnz loc_5235D7
1.首先PspCreateProcess通过ObReferenceObjectByHandle对父进程句柄进行检查(↑)
PAGE:004A9365 loc_4A9365: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+7A2F6↓j
PAGE:004A9365 8B 41 5C mov eax, [ecx+5Ch]
PAGE:004A9365
PAGE:004A9368
PAGE:004A9368 loc_4A9368: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+4B1A8↓j
PAGE:004A9368 89 45 9C mov [ebp+var_64], eax
PAGE:004A936B A1 30 7B 5B 00 mov eax, ds:_PsMinimumWorkingSet
PAGE:004A9370 89 45 A0 mov dword ptr [ebp+var_60], eax
PAGE:004A9373 A1 34 7B 5B 00 mov eax, ds:_PsMaximumWorkingSet
PAGE:004A9378 89 45 98 mov [ebp+var_68], eax
PAGE:004A937B 8D 45 AC lea eax, [ebp+process]
PAGE:004A937E 50 push eax ; int
PAGE:004A937F 56 push esi ; int
PAGE:004A9380 56 push esi ; int
PAGE:004A9381 68 60 02 00 00 push 260h ; int
PAGE:004A9386 56 push esi ; int
PAGE:004A9387 FF 75 DF push dword ptr [ebp+PreviousMode] ; BackTraceHash
PAGE:004A938A FF 75 10 push [ebp+arg_8] ; int
PAGE:004A938D FF 35 58 A4 48 00 push _PsProcessType ; int
PAGE:004A9393 FF 75 DF push dword ptr [ebp+PreviousMode] ; PreviousMode
PAGE:004A9396 E8 CB 51 FE FF call _ObCreateObject@36 ; 创建内核对象
PAGE:004A9396
PAGE:004A939B 8B F8 mov edi, eax ; ret
PAGE:004A939D 3B FE cmp edi, esi ; 判断是否成功创建内核对象
PAGE:004A939F 0F 8C F6 03 00 00 jl loc_4A979B
PAGE:004A939F
PAGE:004A93A5 B9 98 00 00 00 mov ecx, 98h ; 对创建的EPROCESS类型的内核对象设为NULL
PAGE:004A93AA 33 C0 xor eax, eax ; 此时EBX为EPROCESS
PAGE:004A93AC 8B 5D AC mov ebx, [ebp+process]
PAGE:004A93AF 8B FB mov edi, ebx
PAGE:004A93B1 F3 AB rep stosd
PAGE:004A93B3 89 B3 80 00 00 00 mov [ebx+_EPROCESS.RundownProtect.___u0.Count], esi ; 线程的停止保护锁z置NULL
PAGE:004A93B9 89 73 6C mov [ebx+_EPROCESS.ProcessLock.___u0.__s0._bf_0], esi ; 进程锁置空
PAGE:004A93BC 8D 83 90 01 00 00 lea eax, [ebx+_EPROCESS.ThreadListHead]
PAGE:004A93C2 89 40 04 mov [eax+LIST_ENTRY32.Blink], eax ; ThreadListHead初始化
PAGE:004A93C5 89 00 mov [eax], eax
PAGE:004A93C7 FF 75 E4 push [ebp+ParentObject]
PAGE:004A93CA 53 push ebx
PAGE:004A93CB E8 71 0F 00 00 call _PspInheritQuota@8 ; PspInheritQuota(x,x)
PAGE:004A93CB
PAGE:004A93D0 FF 75 E4 push [ebp+ParentObject]
PAGE:004A93D3 53 push ebx
PAGE:004A93D4 E8 FF F8 FF FF call _ObInheritDeviceMap@8 ; 继承父进程的资源
PAGE:004A93D4
PAGE:004A93D9 8B 7D E4 mov edi, [ebp+ParentObject] ; 判断父进程对象是否为空
PAGE:004A93DC 3B FE cmp edi, esi
PAGE:004A93DE 0F 84 B0 B0 04 00 jz loc_4F4494 ; 如果父进程为空 硬件错误设为1,父进程id设为0
PAGE:004A93DE
PAGE:004A93E4 8B 87 A8 01 00 00 mov eax, [edi+_EPROCESS.DefaultHardErrorProcessing] ; 指定默认的硬件错误
PAGE:004A93EA 89 83 A8 01 00 00 mov [ebx+_EPROCESS.DefaultHardErrorProcessing], eax ; 继承父进程的默认硬件错误
PAGE:004A93F0 8B 87 84 00 00 00 mov eax, [edi+_EPROCESS.UniqueProcessId]
PAGE:004A93F6 89 83 4C 01 00 00 mov [ebx+_EPROCESS.InheritedFromUniqueProcessId], eax ; 写入父进程的id
PAGE:004A93F6
PAGE:004A93FC
PAGE:004A93FC loc_4A93FC: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+4B1BD↓j
PAGE:004A93FC 39 75 1C cmp [ebp+arg_14], esi ; 判断是否为空 SectionHandle
PAGE:004A93FF 0F 84 A4 B0 04 00 jz loc_4F44A9
PAGE:004A93FF
PAGE:004A9405 56 push esi ; HandleInformation
PAGE:004A9406 8D 85 78 FF FF FF lea eax, [ebp+var_88]
PAGE:004A940C 50 push eax ; Object
PAGE:004A940D FF 75 DF push dword ptr [ebp+PreviousMode] ; AccessMode
PAGE:004A9410 FF 35 40 89 48 00 push _MmSectionObjectType ; ObjectType
PAGE:004A9416 6A 08 push 8 ; DesiredAccess
PAGE:004A9418 FF 75 1C push [ebp+arg_14] ; Handle
PAGE:004A941B E8 C8 47 FE FF call _ObReferenceObjectByHandle@24 ; 如果不为空,根据提供的sectionhandle获得object
PAGE:004A941B
PAGE:004A9420 8B 8D 78 FF FF FF mov ecx, [ebp+var_88]
PAGE:004A9426 89 4D D8 mov [ebp+SectionObject], ecx
PAGE:004A9429 8B F8 mov edi, eax ; 判断是否成功
PAGE:004A942B 3B C6 cmp eax, esi
PAGE:004A942D 0F 8C 61 03 00 00 jl loc_4A9794
PAGE:004A942D
PAGE:004A9433 8B 7D E4 mov edi, [ebp+ParentObject]
2.通过ObCreateObject创建一个EPROCESS内核对象,并进行一系列的初始化(↑)
PAGE:004A9436 8B 45 D8 mov eax, [ebp+SectionObject]
PAGE:004A9439 89 83 38 01 00 00 mov [ebx+_EPROCESS.SectionObject], eax ; 写入创建进程的SectionObject
PAGE:004A943F 39 75 20 cmp [ebp+DebugPort], esi ; 判断参数DebugPort是否为空
PAGE:004A9442 0F 85 AA A1 07 00 jnz loc_5235F2
PAGE:005235F2 loc_5235F2: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+15B↑j
PAGE:005235F2 56 push esi ; HandleInformation
PAGE:005235F3 8D 45 88 lea eax, [ebp+var_78]
PAGE:005235F6 50 push eax ; Object
PAGE:005235F7 FF 75 DF push dword ptr [ebp+PreviousMode] ; AccessMode
PAGE:005235FA FF 35 40 02 48 00 push _DbgkDebugObjectType ; ObjectType
PAGE:00523600 6A 02 push 2 ; DesiredAccess
PAGE:00523602 FF 75 20 push [ebp+DebugPort] ; Handle
PAGE:00523605 E8 DE A5 F6 FF call _ObReferenceObjectByHandle@24 ; 获取debugport句柄
PAGE:00523605
PAGE:0052360A 8B F8 mov edi, eax ; 判断是否获取成功
PAGE:0052360C 3B FE cmp edi, esi
PAGE:0052360E 0F 8C 80 61 F8 FF jl loc_4A9794
PAGE:0052360E
PAGE:00523614 8B 45 88 mov eax, [ebp+var_78] ; DebugPortObject
PAGE:00523617 89 83 BC 00 00 00 mov [ebx+_EPROCESS.DebugPort], eax ; 复制debugport
PAGE:0052361D F6 45 18 02 test byte ptr [ebp+Flags], 2
PAGE:00523621 0F 84 2C 5E F8 FF jz loc_4A9453
PAGE:00523621
PAGE:00523627 6A 02 push 2
PAGE:00523629 58 pop eax
PAGE:0052362A 8D 8B 48 02 00 00 lea ecx, [ebx+248h]
PAGE:00523630 F0 09 01 lock or [ecx], eax
PAGE:00523633 E9 1B 5E F8 FF jmp loc_4A9453
3.根据参数DebugPort赋值_EPROCESS.DebugPort(↑)
PAGE:004A9453 39 75 24 cmp [ebp+ExceptionPort], esi ; 判断参数是否不为空ExceptionPort
PAGE:004A9456 0F 85 1B A2 07 00 jnz loc_523677
PAGE:00523677 loc_523677: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+16F↑j
PAGE:00523677 56 push esi ; HandleInformation
PAGE:00523678 8D 45 8C lea eax, [ebp+var_74]
PAGE:0052367B 50 push eax ; Object
PAGE:0052367C FF 75 DF push dword ptr [ebp+PreviousMode] ; AccessMode
PAGE:0052367F FF 35 08 3C 48 00 push _LpcPortObjectType ; ObjectType
PAGE:00523685 56 push esi ; DesiredAccess
PAGE:00523686 FF 75 24 push [ebp+ExceptionPort] ; Handle
PAGE:00523689 E8 5A A5 F6 FF call _ObReferenceObjectByHandle@24 ; 获取ExceptionPort的object
PAGE:00523689
PAGE:0052368E 8B F8 mov edi, eax ; 判断是否执行成功
PAGE:00523690 3B FE cmp edi, esi
PAGE:00523692 0F 8C FC 60 F8 FF jl loc_4A9794
PAGE:00523692
PAGE:00523698 8B 45 8C mov eax, [ebp+var_74]
PAGE:0052369B 89 83 C0 00 00 00 mov [ebx+_EPROCESS.ExceptionPort], eax ; 赋值ExceptionPort
PAGE:005236A1 E9 B6 5D F8 FF jmp loc_4A945C
4.根据参数ExceptionPort赋值_EPROCESS.ExceptionPort(↑)
PAGE:004A945C loc_4A945C: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+7A3BA↓j
PAGE:004A945C C7 83 4C 02 00 00 03 01 00 00 mov [ebx+_EPROCESS.ExitStatus], 103h ; 设置退出状态
PAGE:004A9466 53 push ebx ; int
PAGE:004A9467 FF 75 E4 push [ebp+ParentObject] ; Process
PAGE:004A946A E8 1C 0F 00 00 call _PspInitializeProcessSecurity@8 ; 设置父进程的保护状态
PAGE:004A946A
PAGE:004A946F 8B F8 mov edi, eax
PAGE:004A9471 3B FE cmp edi, esi ; 判断是否执行成功
PAGE:004A9473 0F 8C 1B 03 00 00 jl loc_4A9794
PAGE:004A9473
PAGE:004A9479 8B 7D E4 mov edi, [ebp+ParentObject] ; 判断父进程是否为空
PAGE:004A947C 3B FE cmp edi, esi
PAGE:004A947E 0F 84 B5 41 05 00 jz loc_4FD639
PAGE:004A947E
PAGE:004A9484 8D 45 B8 lea eax, [ebp+var_48] ; 如果存在
PAGE:004A9487 50 push eax ; int
PAGE:004A9488 53 push ebx ; int
PAGE:004A9489 FF 75 A0 push dword ptr [ebp+var_60] ; KIRQL
PAGE:004A948C E8 B8 C7 F7 FF call _MmCreateProcessAddressSpace@12 ; 创建地址空间
PAGE:004A948C
PAGE:004A9491 84 C0 test al, al ; 判断是否执行成功
PAGE:004FD639 loc_4FD639: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+197↑j
PAGE:004FD639 ; __unwind { // __SEH_prolog
PAGE:004FD639 8B 45 A8 mov eax, [ebp+Process]
PAGE:004FD63C 8B 80 C4 00 00 00 mov eax, [eax+_EPROCESS.ObjectTable]
PAGE:004FD642 89 83 C4 00 00 00 mov [ebx+_EPROCESS.ObjectTable], eax ; 复制句柄表
PAGE:004FD648 8D 45 B8 lea eax, [ebp+var_48]
PAGE:004FD64B 50 push eax
PAGE:004FD64C 53 push ebx
PAGE:004FD64D E8 0A 00 00 00 call _MmInitializeHandBuiltProcess@8 ; 进程地址空间初始化
PAGE:004FD64D
PAGE:004FD652 E9 42 BE FA FF jmp loc_4A9499
PAGE:004FD652 ; } // starts at 4FD639
5.进程地址空间初始化,如果父进程不为空,则创建地址空间,否则复制当前进程的句柄表至新进程的句柄表(↑)
PAGE:004A94FE loc_4A94FE: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+5443D↓j
PAGE:004A94FE 53 push ebx
PAGE:004A94FF 8B 45 18 mov eax, [ebp+Flags]
PAGE:004A9502 24 04 and al, 4
PAGE:004A9504 F6 D8 neg al
PAGE:004A9506 1B C0 sbb eax, eax
PAGE:004A9508 23 45 E4 and eax, [ebp+ParentObject]
PAGE:004A950B 50 push eax
PAGE:004A950C E8 78 FA FF FF call _ObInitProcess@8 ; 初始化创建进程的句柄表,如果父进程存在,父进程的句柄表被复制且HandleCount加1
PAGE:004A950C
6.初始化进程的句柄表(↑)
PAGE:004A9511 loc_4A9511: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+54436↓j
PAGE:004A9511 ; PAGE:005236AB↓j
PAGE:004A9511 8B F8 mov edi, eax
PAGE:004A9513 3B FE cmp edi, esi
PAGE:004A9515 0F 8C 79 02 00 00 jl loc_4A9794 ; 判断是否成功
PAGE:004A9515
PAGE:004A951B 89 75 CC mov [ebp+var_34], esi
PAGE:004A951E 39 75 1C cmp [ebp+SectionHandle], esi ; 判断可执行映像内存区对象是否为空
PAGE:004A9521 0F 84 96 AF 04 00 jz loc_4F44BD ; 如果为空
PAGE:004A9521
PAGE:004A9527 8D 83 F4 01 00 00 lea eax, [ebx+1F4h]
PAGE:004A952D 50 push eax ; int
PAGE:004A952E FF 75 D8 push [ebp+SectionObject] ; int
PAGE:004A9531 56 push esi ; int
PAGE:004A9532 53 push ebx ; Process
PAGE:004A9533 E8 81 CB F7 FF call _MmInitializeProcessAddressSpace@16 ; 如果不为空则直接初始化地址空间
7.1如果SectionHandle存在直接初始化进程空间(↑)
PAGE:004F44BD loc_4F44BD: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+23A↑j
PAGE:004F44BD 8B 45 E4 mov eax, [ebp+ParentObject]
PAGE:004F44C0 3B C6 cmp eax, esi ; 如果父进程为空
PAGE:004F44C2 0F 84 92 50 FB FF jz loc_4A955A ; 系统的引导程序
PAGE:004F44C2
PAGE:004F44C8 E9 E3 F1 02 00 jmp loc_5236B0 ; 如果父进程存在
7.2如果sectionhandle不存在且父进程为空,则是系统引导程序。(↑)
PAGE:005236B0 loc_5236B0: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+4B1E1↑j
PAGE:005236B0 ; __unwind { // __SEH_prolog ; int
PAGE:005236B0 56 push esi
PAGE:005236B1 56 push esi ; int
PAGE:005236B2 3B 05 54 A4 48 00 cmp eax, _PsInitialSystemProcess
PAGE:005236B8 74 7E jz short loc_523738 ; 判断父进程是否是PsInitialSystemProcess
PAGE:00523738 loc_523738: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+7A3D1↑j
PAGE:00523738 56 push esi ; int
PAGE:00523739 53 push ebx ; Process
PAGE:0052373A E8 7A 29 F0 FF call _MmInitializeProcessAddressSpace@16 ; 初始化进程地址空间
7.3如果sectionhandle不存在,父进程PsInitialSystemProcess,直接初始化进程空间(↑)
PAGE:005236BA 8B 88 3C 01 00 00 mov ecx, [eax+_EPROCESS.SectionBaseAddress]
PAGE:005236C0 89 8B 3C 01 00 00 mov [ebx+_EPROCESS.SectionBaseAddress], ecx ; 赋值该内存区对象的基地址为父进程的基地址
PAGE:005236C6 50 push eax ; int
PAGE:005236C7 53 push ebx ; Process
PAGE:005236C8 E8 EC 29 F0 FF call _MmInitializeProcessAddressSpace@16 ; 初始化地址空间
PAGE:005236C8
PAGE:005236CD 8B F8 mov edi, eax ; 父进程
PAGE:005236CF C6 45 E3 01 mov [ebp+var_1D], 1
PAGE:005236D3 3B FE cmp edi, esi
PAGE:005236D5 0F 8C B9 60 F8 FF jl loc_4A9794
PAGE:005236D5
PAGE:005236DB 8B 45 E4 mov eax, [ebp+ParentObject]
PAGE:005236DE 8B 80 F4 01 00 00 mov eax, [eax+_EPROCESS.SeAuditProcessCreationInfo.ImageFileName]
PAGE:005236E4 3B C6 cmp eax, esi ; 判断父进程映像名是否为空
PAGE:005236E6 0F 84 6E 5E F8 FF jz loc_4A955A
PAGE:005236E6
PAGE:005236EC 0F B7 78 02 movzx edi, word ptr [eax+2]
PAGE:005236F0 83 C7 08 add edi, 8
PAGE:005236F3 68 53 65 50 61 push 61506553h ; Tag
PAGE:005236F8 57 push edi ; NumberOfBytes
PAGE:005236F9 6A 01 push 1 ; PoolType
PAGE:005236FB E8 C4 0F F5 FF call _ExAllocatePoolWithTag@12 ; 申请空间
PAGE:005236FB
PAGE:00523700 89 83 F4 01 00 00 mov [ebx+_EPROCESS.SeAuditProcessCreationInfo.ImageFileName], eax ; 申请空间给imagefilename
PAGE:00523706 3B C6 cmp eax, esi
PAGE:00523708 74 62 jz short loc_52376C
PAGE:00523708
PAGE:0052370A 8B CF mov ecx, edi
PAGE:0052370C 8B 55 E4 mov edx, [ebp+ParentObject]
PAGE:0052370F 8B B2 F4 01 00 00 mov esi, [edx+_EPROCESS.SeAuditProcessCreationInfo.ImageFileName]
PAGE:00523715 8B F8 mov edi, eax
PAGE:00523717 8B C1 mov eax, ecx
PAGE:00523719 C1 E9 02 shr ecx, 2
PAGE:0052371C F3 A5 rep movsd
PAGE:0052371E 8B C8 mov ecx, eax
PAGE:00523720 83 E1 03 and ecx, 3
PAGE:00523723 F3 A4 rep movsb ; 把父进程的映像名赋值给新进程
PAGE:00523725 8B 83 F4 01 00 00 mov eax, [ebx+1F4h]
PAGE:0052372B 8D 48 08 lea ecx, [eax+8]
PAGE:0052372E 89 48 04 mov [eax+4], ecx
PAGE:00523731 33 F6 xor esi, esi
PAGE:00523733 E9 22 5E F8 FF jmp loc_4A955A
7.4如果sectionhandle不存在,父进程不是PsInitialSystemProcess,根据父进程来初始化进程地址空间。并且把父进程的映像名称字符串拷贝到新进程对象的数据结构中(↑)
PAGE:004A955A 8B BB C8 00 00 00 mov edi, [ebx+_EPROCESS.Token.___u0.Object]
PAGE:004A9560 83 E7 F8 and edi, 0FFFFFFF8h
PAGE:004A9563 53 push ebx
PAGE:004A9564 E8 40 6E F6 FF call _MmGetSessionId@4 ; 获取进程ID
PAGE:004A9564
PAGE:004A9569 50 push eax ; SessionId
PAGE:004A956A 57 push edi ; Token
PAGE:004A956B E8 44 10 00 00 call _SeSetSessionIdToken@8 ; 获取指定令牌的SessionId
PAGE:004A956B
PAGE:004A9570 89 5D 90 mov [ebp+var_70], ebx
PAGE:004A9573 89 75 94 mov [ebp+var_6C], esi
PAGE:004A9576 8D 45 90 lea eax, [ebp+var_70]
PAGE:004A9579 50 push eax
PAGE:004A957A FF 35 60 A4 48 00 push _PspCidTable
PAGE:004A9580 E8 C7 75 FE FF call _ExCreateHandle@8 ; 创建进程的句柄
PAGE:004A9580
PAGE:004A9585 89 83 84 00 00 00 mov [ebx+_EPROCESS.UniqueProcessId], eax ; 赋值给父进程ID
PAGE:004A958B 3B C6 cmp eax, esi
PAGE:004A958D 0F 84 D9 A1 07 00 jz loc_52376C ; 判断是否成功
PAGE:004A958D
PAGE:004A9593 8B 8B C4 00 00 00 mov ecx, [ebx+_EPROCESS.ObjectTable]
PAGE:004A9599 89 41 08 mov [ecx+8], eax ; 句柄加入句柄表
PAGE:004A959C 33 C9 xor ecx, ecx
PAGE:004A959E E8 36 A3 F7 FF call @SeDetailedAuditingWithToken@4 ; 设置token审计
PAGE:004A959E
PAGE:004A95A3 84 C0 test al, al
PAGE:004A95A5 0F 85 CB A1 07 00 jnz loc_523776 ; 如果执行成功跳转审计
PAGE:004A95A5
PAGE:004A95AB
8.创建进程ID,并进行审计(↑)
PAGE:004A95AB loc_4A95AB: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+7A495↓j
PAGE:004A95AB 8B 45 E4 mov eax, [ebp+ParentObject]
PAGE:004A95AE 3B C6 cmp eax, esi
PAGE:004A95B0 74 0E jz short loc_4A95C0
PAGE:004A95B0
PAGE:004A95B2 8B 80 34 01 00 00 mov eax, [eax+_EPROCESS.Job]
PAGE:004A95B8 3B C6 cmp eax, esi
PAGE:004A95BA 0F 85 C1 A1 07 00 jnz loc_523781 ; 判断进程是否属于job,如果属于JOB则新进程加入此job中
PAGE:004A95BA
PAGE:004A95C0
PAGE:00523781 loc_523781: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+2D3↑j
PAGE:00523781 8B B8 98 00 00 00 mov edi, [eax+_EJOB.LimitFlags]
PAGE:00523787 F7 C7 00 10 00 00 test edi, 1000h
PAGE:0052378D 0F 85 2D 5E F8 FF jnz loc_4A95C0
PAGE:0052378D
PAGE:00523793 F6 45 18 01 test byte ptr [ebp+Flags], 1
PAGE:00523797 74 1B jz short loc_5237B4 ; NEW
PAGE:00523797
PAGE:00523799 81 E7 00 08 00 00 and edi, 800h
PAGE:0052379F F7 DF neg edi
PAGE:005237A1 1B FF sbb edi, edi
PAGE:005237A3 81 E7 DE FF FF 3F and edi, 3FFFFFDEh
PAGE:005237A9 81 C7 22 00 00 C0 add edi, 0C0000022h
PAGE:005237AF E9 75 9F FD FF jmp loc_4FD729
PAGE:005237AF
PAGE:005237B4 ; ---------------------------------------------------------------------------
PAGE:005237B4
PAGE:005237B4 loc_5237B4: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+7A4B0↑j
PAGE:005237B4 8D 8B 34 01 00 00 lea ecx, [ebx+_EPROCESS.Job] ; NEW
PAGE:005237BA 51 push ecx ; int
PAGE:005237BB FF 75 28 push [ebp+arg_20] ; int
PAGE:005237BE 50 push eax ; Object
PAGE:005237BF E8 BF 55 03 00 call _PspGetJobFromSet@12 ; 新进程工作在父进程的job
PAGE:005237BF
PAGE:005237C4 8B F8 mov edi, eax ; 判断是否执行成功
PAGE:005237C6 3B FE cmp edi, esi
PAGE:005237C8 0F 8C C6 5F F8 FF jl loc_4A9794
PAGE:005237C8
PAGE:005237CE 8B 83 34 01 00 00 mov eax, [ebx+_EPROCESS.Job]
PAGE:005237D4 89 45 84 mov [ebp+var_7C], eax
PAGE:005237D7 53 push ebx ; PROCESS
PAGE:005237D8 50 push eax ; Semaphore
PAGE:005237D9 E8 CE 7B FA FF call _PspAddProcessToJob@8 ; 地址->job
PAGE:005237D9
PAGE:005237DE 8B F8 mov edi, eax
PAGE:005237E0 8B 45 84 mov eax, [ebp+var_7C]
PAGE:005237E3 8B 80 B8 00 00 00 mov eax, [eax+_EJOB.Token]
PAGE:005237E9 3B C6 cmp eax, esi
PAGE:005237EB 0F 84 38 9F FD FF jz loc_4FD729
PAGE:005237EB
PAGE:005237F1 56 push esi ; char
PAGE:005237F2 8D 4D A4 lea ecx, [ebp+var_5C]
PAGE:005237F5 51 push ecx ; int
PAGE:005237F6 50 push eax ; Object
PAGE:005237F7 E8 4F 6D F8 FF call _SeSubProcessToken@12 ; 创建令牌
PAGE:005237F7
PAGE:005237FC 8B F8 mov edi, eax
PAGE:005237FE 3B FE cmp edi, esi ; 判断是否创建成功
PAGE:00523800 0F 8C 8E 5F F8 FF jl loc_4A9794
PAGE:00523800
PAGE:00523806 FF 75 A4 push [ebp+var_5C] ; Object
PAGE:00523809 53 push ebx ; int
PAGE:0052380A E8 E2 9D FD FF call _SeAssignPrimaryToken@8 ; 创建主令牌
PAGE:0052380A
PAGE:0052380F 8B 4D A4 mov ecx, [ebp+var_5C] ; Object
PAGE:00523812 E8 39 E8 ED FF call @ObfDereferenceObject@4 ; 减少引用计数
PAGE:00523812
PAGE:00523817 E9 0D 9F FD FF jmp loc_4FD729
9.判断父进程是否属于job,如果属于job则新进程加入父进程所在的job(↑)
PAGE:004A95F9 loc_4A95F9: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+2DC↑j
PAGE:004A95F9 ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+2E2↑j
PAGE:004A95F9 ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+7A56B↓j
PAGE:004A95F9 8B BD 7C FF FF FF mov edi, [ebp+MyCurrentThread]
PAGE:004A95FF FF 8F D4 00 00 00 dec [edi+_ETHREAD.Tcb.KernelApcDisable]
PAGE:004A9605 B9 60 A3 48 00 mov ecx, offset _PspActiveProcessMutex ; FastMutex
PAGE:004A960A E8 B8 AC F5 FF call @ExAcquireFastMutexUnsafe@4 ; 创建互斥体锁
PAGE:004A960A
PAGE:004A960F 8D 83 88 00 00 00 lea eax, [ebx+_EPROCESS.ActiveProcessLinks] ; 获取进程链表
PAGE:004A9615 8B 0D 5C A3 48 00 mov ecx, _PsActiveProcessHead_0
PAGE:004A961B C7 00 58 A3 48 00 mov [eax+_LIST_ENTRY.Flink], offset _PsActiveProcessHead
PAGE:004A9621 89 48 04 mov [eax+_LIST_ENTRY.Blink], ecx
PAGE:004A9624 89 01 mov [ecx], eax
PAGE:004A9626 A3 5C A3 48 00 mov _PsActiveProcessHead_0, eax ; 将新进程加入进程链表中
PAGE:004A962B B9 60 A3 48 00 mov ecx, offset _PspActiveProcessMutex ; FastMutex
PAGE:004A9630 E8 B2 AC F5 FF call @ExReleaseFastMutexUnsafe@4 ; 释放锁
PAGE:004A9630
10.把新进程加入到全局的进程链表PsActiveProcessHead(↑)
PAGE:004A9677
PAGE:004A967C 8B F8 mov edi, eax
PAGE:004A967E 3B FE cmp edi, esi
PAGE:004A9680 0F 8C 0E 01 00 00 jl loc_4A9794
PAGE:004A9680
PAGE:004A9686 8D 45 D0 lea eax, [ebp+Handle]
PAGE:004A9689 50 push eax ; Handle
PAGE:004A968A 56 push esi ; NewObject
PAGE:004A968B 6A 01 push 1 ; ObjectPointerBias
PAGE:004A968D FF 75 0C push [ebp+DesiredAccess] ; DesiredAccess
PAGE:004A9690 8D 85 D4 FE FF FF lea eax, [ebp+PassedAccessState]
PAGE:004A9696 50 push eax ; PassedAccessState
PAGE:004A9697 53 push ebx ; Object
PAGE:004A9698 E8 9D 49 FE FF call _ObInsertObject@24 ; 把新进程插入当前进程的句柄表中
11.把新进程插入当前进程的句柄表中(↑)
PAGE:004A969D 8B F8 mov edi, eax
PAGE:004A969F 89 7D B0 mov [ebp+Priority], edi
PAGE:004A96A2 8D 85 D4 FE FF FF lea eax, [ebp+PassedAccessState]
PAGE:004A96A8 50 push eax
PAGE:004A96A9 E8 70 3B FE FF call _SeDeleteAccessState@4 ; 释放context
PAGE:004A96A9
PAGE:004A96AE 3B FE cmp edi, esi ; 判断是否成功
PAGE:004A96B0 0F 8C E5 00 00 00 jl loc_4A979B
PAGE:004A96B0
PAGE:004A96B6 C7 83 A4 01 00 00 01 00 00 00 mov [ebx+_EPROCESS.GrantedAccess], 1 ; 设置进程的访问权限
PAGE:004A96C0 56 push esi
PAGE:004A96C1 53 push ebx ; process
PAGE:004A96C2 E8 7C A6 FE FF call _PsSetProcessPriorityByClass@8 ; PsSetProcessPriorityByClass(x,x)
PAGE:004A96C2
PAGE:004A96C7 39 75 E4 cmp [ebp+ParentObject], esi
PAGE:004A96CA 0F 84 A0 CD 03 00 jz loc_4E6470
PAGE:004A96CA
PAGE:004A96D0 8B 45 E4 mov eax, [ebp+ParentObject]
PAGE:004A96D3 3B 05 54 A4 48 00 cmp eax, _PsInitialSystemProcess
PAGE:004A96D9 0F 84 91 CD 03 00 jz loc_4E6470
PAGE:004A96D9
PAGE:004A96DF 8D 45 C8 lea eax, [ebp+MemoryAllocated]
PAGE:004A96E2 50 push eax ; MemoryAllocated
PAGE:004A96E3 8D 45 D4 lea eax, [ebp+SecurityDescriptor]
PAGE:004A96E6 50 push eax ; SecurityDescriptor
PAGE:004A96E7 53 push ebx ; Object
PAGE:004A96E8 E8 41 55 FE FF call _ObGetObjectSecurity@12 ; 设置进程的优先级
PAGE:004A96E8
PAGE:004A96ED 8B F8 mov edi, eax
PAGE:004A96EF 89 7D B0 mov [ebp+Priority], edi
PAGE:004A96F2 3B FE cmp edi, esi ; 判断是否设置成功
PAGE:004A96F4 0F 8C 6E A1 07 00 jl loc_523868
PAGE:004A96F4
PAGE:004A96FA 89 9D 74 FF FF FF mov [ebp+SubjectSecurityContext.ProcessAuditId], ebx
PAGE:004A9700 53 push ebx ; Process
PAGE:004A9701 E8 B5 39 FE FF call _PsReferencePrimaryToken@4 ; 设置创建的进程主令牌引用计数递增
PAGE:004A9701 ; 获取进程主令牌地址
PAGE:004A9701
PAGE:004A9706 89 85 70 FF FF FF mov [ebp+SubjectSecurityContext.PrimaryToken], eax
PAGE:004A970C 89 B5 68 FF FF FF mov [ebp+SubjectSecurityContext.ClientToken], esi
PAGE:004A9712 8D 45 B4 lea eax, [ebp+AccessStatus]
PAGE:004A9715 50 push eax ; AccessStatus
PAGE:004A9716 8D 83 A4 01 00 00 lea eax, [ebx+_EPROCESS.GrantedAccess]
PAGE:004A971C 50 push eax ; GrantedAccess
PAGE:004A971D FF 75 DF push dword ptr [ebp+PreviousMode] ; AccessMode
PAGE:004A9720 A1 58 A4 48 00 mov eax, _PsProcessType
PAGE:004A9725 83 C0 68 add eax, 68h ; 'h'
PAGE:004A9728 50 push eax ; GenericMapping
PAGE:004A9729 56 push esi ; Privileges
PAGE:004A972A 56 push esi ; PreviouslyGrantedAccess
PAGE:004A972B 68 00 00 00 02 push 2000000h ; MAXIMUM_ALLOWED
PAGE:004A9730 56 push esi ; SubjectContextLocked
PAGE:004A9731 8D 85 68 FF FF FF lea eax, [ebp+SubjectSecurityContext]
PAGE:004A9737 50 push eax ; SubjectSecurityContext
PAGE:004A9738 FF 75 D4 push [ebp+SecurityDescriptor] ; SecurityDescriptor
PAGE:004A973B E8 08 42 FE FF call _SeAccessCheck@40 ; 判断是否可以授予访问权限
PAGE:004A973B
PAGE:004A9740 88 45 DE mov [ebp+var_22], al
PAGE:004A9743 8B 95 70 FF FF FF mov edx, [ebp+SubjectSecurityContext.PrimaryToken]
PAGE:004A9749 8D 8B C8 00 00 00 lea ecx, [ebx+0C8h]
PAGE:004A974F E8 0B B2 FE FF call @ObFastDereferenceObject@8 ; 删除增加的引用计数
PAGE:004A974F
PAGE:004A9754 FF 75 C8 push dword ptr [ebp+MemoryAllocated] ; MemoryAllocated
PAGE:004A9757 FF 75 D4 push [ebp+SecurityDescriptor] ; SecurityDescriptor
PAGE:004A975A E8 BB 55 FE FF call _ObReleaseObjectSecurity@8 ; 释放安全描述符相关的内存
PAGE:004A975A
PAGE:004A975F 80 7D DE 00 cmp [ebp+var_22], 0 ; 判断权限授予是否成功
PAGE:004A9763 0F 84 0F A1 07 00 jz loc_523878
PAGE:004A9763
12.设置进程的优先级及访问权限(↑)
PAGE:004A9773
PAGE:004A9773 loc_4A9773: ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+3D193↓j
PAGE:004A9773 8D 43 70 lea eax, [ebx+_EPROCESS.CreateTime]
PAGE:004A9776 50 push eax ; CurrentTime
PAGE:004A9777 E8 20 34 F6 FF call _KeQuerySystemTime@4 ; 获取当前系统时间设置为新进程的CurrentTime
PAGE:004A9777
PAGE:004A977C ; __try { // __except at loc_523891
PAGE:004A977C 89 75 FC mov [ebp+ms_exc.registration.TryLevel], esi
PAGE:004A977F 8B 45 08 mov eax, [ebp+ProcessHandle]
PAGE:004A9782 8B 4D D0 mov ecx, [ebp+Handle]
PAGE:004A9785 89 08 mov [eax], ecx ; 把创建的句柄传给输出参数ProcessHandle
PAGE:004A9785 ; } // starts at 4A977C
PAGE:004A9787 83 4D FC FF or [ebp+ms_exc.registration.TryLevel], 0FFFFFFFFh
PAGE:004A9787
13.设置创建时间,把创建进程的句柄传递给输出参数ProcessHandle。(↑)