看流星社区

 找回密码
 注册账号
查看: 3161|回复: 1

PsLookupProcessByProcessId

[复制链接]

该用户从未签到

发表于 2016-8-7 14:12:56 | 显示全部楼层 |阅读模式
昨天为了这个破API蓝屏了一整天,估计达20次以上,特此纪念之。

调试定位的过程极其痛苦,不过今天早上终于搞定,简单说说吧。调用完PsLookupProcessByProcessId之后记住要调用ObDereferenceObject,否则Object还会在内存中不被释放,进而导致调用这个API的进程在“退出”后,会有两种状态:在User层的状态是退出了,但在Kernel层的状态还是deleting(用softice的proc命令可以看到),这样当下次再访问这个进程的内存的时候就会蓝屏。奇怪的是在WinXP下才会这样,Win2000中貌似没事,不知道是巧合还是操作系统做了点什么手脚?(这也从另一个侧面反映出Win2000其实不够健壮),懒得细究了,反正弄清楚了也没法维护世界的和平。

源码之前,了无秘密。(private\ntos\ps\pscid.c)

NTSTATUS
PsLookupProcessByProcessId(
    IN HANDLE ProcessId,
    OUT PEPROCESS *Process
    )

/*++

Routine Description:

    This function accepts the process id of a process and returns a
    referenced pointer to the process.

Arguments:

    ProcessId - Specifies the Process ID of the process.

    Process - Returns a referenced pointer to the process specified by the
        process id.

Return Value:

    STATUS_SUCCESS - A process was located based on the contents of
        the process id.

    STATUS_INVALID_PARAMETER - The process was not found.

--*/

{

    PHANDLE_TABLE_ENTRY CidEntry;
    PEPROCESS lProcess;
    NTSTATUS Status;

    CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId);
    Status = STATUS_INVALID_PARAMETER;
    if (CidEntry != NULL) {
        lProcess = (PEPROCESS)CidEntry->Object;
        if (lProcess != (PEPROCESS)PSP_INVALID_ID && lProcess->Pcb.Header.Type == ProcessObject && lProcess->GrantedAccess ) {
            ObReferenceObject(lProcess);
            *Process = lProcess;
            Status = STATUS_SUCCESS;
        }

        ExUnlockHandleTableEntry(PspCidTable, CidEntry);
    }

    return Status;
}

是由代码中的这行: ObReferenceObject(lProcess);   导致的。

该用户从未签到

发表于 2016-8-9 16:52:58 | 显示全部楼层

我就是来看看~么么哒~~
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-19 08:25

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表