欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

进程挂靠后使用PsGetCurrentProcessId获取的进程ID不准

程序员文章站 2022-07-03 18:26:16
...

如题,在使用KeStackAttachProcess挂靠到目标进程后,又调用了一系列子函数,此时并没有把EPROCESS传进去。

PEPROCESS    pProcess = NULL;
KAPC_STATE    apc;
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)pid, &pProcess);
if (NT_SUCCESS(status))
{
	KeStackAttachProcess(pProcess, &apc);
		SubRoutine(); // didn't pass target eprocess into sub routine.
	KeUnstackDetachProcess(&apc);
	ObDereferenceObject(pProcess);
}

但是在SubRoutine函数中又调用了PsGetCurrentProcessId() 来获取目标进程的PID,得到的结果是4

明显这是错误的,通过该查看当前环境信息确认已经附加到IE进程了!
进程挂靠后使用PsGetCurrentProcessId获取的进程ID不准

通过查看反汇编PsGetCurrentProcessId得知,它获取PID是从ethread结构中读取偏移0x3B0的数据

1: kd> uf PsGetCurrentProcessId
nt!PsGetCurrentProcessId:
fffff800`03eaccb0 65488b042588010000 mov   rax,qword ptr gs:[188h]
fffff800`03eaccb9 488b80b0030000  mov     rax,qword ptr [rax+3B0h]
fffff800`03eaccc0 c3              ret

1: kd> dt _ETHREAD
nt!_ETHREAD
   +0x000 Tcb              : _KTHREAD
   +0x360 CreateTime       : _LARGE_INTEGER
   +0x368 ExitTime         : _LARGE_INTEGER
   +0x368 KeyedWaitChain   : _LIST_ENTRY
   +0x378 ExitStatus       : Int4B
   +0x380 PostBlockList    : _LIST_ENTRY
   +0x380 ForwardLinkShadow : Ptr64 Void
   +0x388 StartAddress     : Ptr64 Void
   +0x390 TerminationPort  : Ptr64 _TERMINATION_PORT
   +0x390 ReaperLink       : Ptr64 _ETHREAD
   +0x390 KeyedWaitValue   : Ptr64 Void
   +0x398 ActiveTimerListLock : Uint8B
   +0x3a0 ActiveTimerListHead : _LIST_ENTRY
   +0x3b0 Cid              : _CLIENT_ID  《============= 这里读取的PID,进程挂靠后保存的还是原进程的PID

通过查看KeStackAttachProcess函数的源码,得知被附加进程的EPROCESS结构,保存在ethread->ApcState->Process

进程挂靠后使用PsGetCurrentProcessId获取的进程ID不准

1: kd> dx -id 0,0,fffffa801b803b30 -r1 (*((ntkrnlmp!_KTHREAD *)0xfffffa801ca40040))
(*((ntkrnlmp!_KTHREAD *)0xfffffa801ca40040))                 [Type: _KTHREAD]
    [+0x000] Header           [Type: _DISPATCHER_HEADER]
    [+0x018] CycleTime        : 0x6d92c1272 [Type: unsigned __int64]
    [+0x020] QuantumTarget    : 0x6dd003af2 [Type: unsigned __int64]
    [+0x028] InitialStack     : 0xfffff8800386cc70 [Type: void *]
    [+0x030] StackLimit       : 0xfffff88003867000 [Type: void *]
    [+0x038] KernelStack      : 0xfffff8800386b480 [Type: void *]
    [+0x040] ThreadLock       : 0x0 [Type: unsigned __int64]
    [+0x048] WaitRegister     [Type: _KWAIT_STATUS_REGISTER]
    [+0x049] Running          : 0x1 [Type: unsigned char]
    [+0x04a] Alerted          [Type: unsigned char [2]]
    [+0x04c ( 0: 0)] KernelStackResident : 0x1 [Type: unsigned long]
    [+0x04c ( 1: 1)] ReadyTransition  : 0x0 [Type: unsigned long]
    [+0x04c ( 2: 2)] ProcessReadyQueue : 0x0 [Type: unsigned long]
    [+0x04c ( 3: 3)] WaitNext         : 0x0 [Type: unsigned long]
    [+0x04c ( 4: 4)] SystemAffinityActive : 0x0 [Type: unsigned long]
    [+0x04c ( 5: 5)] Alertable        : 0x0 [Type: unsigned long]
    [+0x04c ( 6: 6)] GdiFlushActive   : 0x0 [Type: unsigned long]
    [+0x04c ( 7: 7)] UserStackWalkActive : 0x0 [Type: unsigned long]
    [+0x04c ( 8: 8)] ApcInterruptRequest : 0x0 [Type: unsigned long]
    [+0x04c ( 9: 9)] ForceDeferSchedule : 0x0 [Type: unsigned long]
    [+0x04c (10:10)] QuantumEndMigrate : 0x0 [Type: unsigned long]
    [+0x04c (11:11)] UmsDirectedSwitchEnable : 0x0 [Type: unsigned long]
    [+0x04c (12:12)] TimerActive      : 0x0 [Type: unsigned long]
    [+0x04c (13:13)] SystemThread     : 0x1 [Type: unsigned long]
    [+0x04c (31:14)] Reserved         : 0x0 [Type: unsigned long]
    [+0x04c] MiscFlags        : 8193 [Type: long]
    [+0x050] ApcState         [Type: _KAPC_STATE]  <=========  0x50


1: kd> dx -r1 (*((ntkrnlmp!_KAPC_STATE *)0xfffffa801ca40090))
(*((ntkrnlmp!_KAPC_STATE *)0xfffffa801ca40090))                 [Type: _KAPC_STATE]
    [+0x000] ApcListHead      [Type: _LIST_ENTRY [2]]
    [+0x020] Process          : 0xfffffa801b803b30 [Type: _KPROCESS *]  <<======= 0x20

通过分析PsGetCurrentProcess反汇编,正式利用了上面的偏移来获取的被附加进程的eprocess

1: kd> uf PsGetCurrentProcess
nt!PsGetCurrentProcess:
fffff800`03e9bbb0 65488b042588010000 mov   rax,qword ptr gs:[188h]  =======》ETHREAD
fffff800`03e9bbb9 488b4070        mov     rax,qword ptr [rax+70h]   =======》ETHREAD->ApcState->Process
fffff800`03e9bbbd c3              ret

因此,在附加进程后,想要通过某个函数获取被附加进程pid,不能直接使用PsGetCurrentProcessId

应该先通过PsGetCurrentProcess 获取目标进程的EPROCESS结构,再使用PsGetProcessId 来获取指定Eprocess的PID。

PsGetProcessId 的反汇编,可以看出是直接从传入参数Eprocess中读取的PID,因此不会错。

进程挂靠后使用PsGetCurrentProcessId获取的进程ID不准