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

如题,在使用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得知,它获取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

在这里插入图片描述

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,因此不会错。

在这里插入图片描述


// 例如 A 附加到B进程
    PEPROCESS pProcess =  PsGetCurrentProcess();
    HANDLE AttachedPID = PsGetProcessId(pProcess);  // 得到的是B进程的PID
	HANDLE pid = PsGetCurrentProcessId();  // 得到的是A进程的PID

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值