PsLookupProcessByProcessId分析

本文是在讨论枚举进程的时候产生的,枚举进程有很多方法,Ring3就是ZwQuerySystemInformation(),传入SysProcessesAndThreadsInformation这个宏,或者用CreateToolhelp32Snapshot系统快照的方式枚举进程,还用就是用WTSOpenServer这个第三方库的函数,Ring0就是进程活动链表,系统句柄表中枚举。然后就是PsLookupProcessByProcessId了。

NrOpenProcess -> PsProcessByProcessId ->关闭APC,调用ExMapHandleToPointer->调用ExpLookupHandleTableEntry找到HANDLE_TABLE_ENTRY在调用ExpLockHandleTableEntry锁定,判断是否调试状态,成功返回->PsProcessByProcessId之后增加引用计数,解锁APC,成功返回。

首先看一下函数原型

1 NTSTATUS
2
3 PsLookupProcessByProcessId(
4
5     __in HANDLE ProcessId,   //进程ID
6
7     __deref_out PEPROCESS *Process //返回的EPROCESS
8
9     )

第一个参数是进程ID,第二个参数就是进程体了

下面我们从OD跟进这个函数

kd> u PsLookupProcessByProcessId l 20
nt!PsLookupProcessByProcessId:
805ca38a 8bff            mov     edi,edi
805ca38c 55              push    ebp
805ca38d 8bec            mov     ebp,esp
805ca38f 53              push    ebx
805ca390 56              push    esi
805ca391 64a124010000    mov     eax,dword ptr fs:[00000124h]
805ca397 ff7508          push    dword ptr [ebp+8]
805ca39a 8bf0            mov     esi,eax
805ca39c ff8ed4000000    dec     dword ptr [esi+0D4h]
805ca3a2 ff3560b25580    push    dword ptr [nt!PspCidTable (8055b260)]
805ca3a8 e84bb50300      call    nt!ExMapHandleToPointer (806058f8)

首先使APC无效

    CurrentThread = PsGetCurrentThread ();
    KeEnterCriticalRegionThread (&CurrentThread->Tcb); 

然后调用了函数ExMapHandleToPointer函数,传入的参数就是PspCidTable系统句柄表的指针。我们跟踪ExMapHandleToPointer函数

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

        ExUnlockHandleTableEntry(PspCidTable, CidEntry);
    }

此函数调用了ExpLookupHandleTableEntry函数,但是在之前做了参数检查

    LocalHandle.GenericHandleOverlay = Handle;

    HandleTableEntry = ExpLookupHandleTableEntry( HandleTable,
                                                  LocalHandle );

    if (HandleTableEntry == NULL) {

        return NULL;
    }

判断进程ID的有效性

然后调用ExpLookupHandleTableEntry,这个函数就是在句柄表的三层结构中找到对应的对象,返回HANDLE_TABLE_ENTRY结构,再返回之后就会调用ExpLockHandleTableEntry函数来锁定当前的HANDLE_TABLE_ENTRY

    HandleTableEntry = ExpLookupHandleTableEntry( HandleTable,
                                                  LocalHandle );

    if (HandleTableEntry == NULL) {

        return NULL;
    }

在ExpLockHandleTableEntry中就会调用InterlockedCompareExchangePointer,如果不成功,则可能是进程句柄处于被调试状态,可以通过HandleTableEntry中的debugInfo来判断句柄是否处于调试状态

  if ((HandleTableEntry == NULL) ||
        !ExpLockHandleTableEntry( HandleTable, HandleTableEntry)) {
        //
        // If we are debugging handle operations then save away the details
        //

        if (HandleTable->DebugInfo != NULL) {
            ExpUpdateDebugInfo(HandleTable, PsGetCurrentThread (), Handle, HANDLE_TRACE_DB_BADREF);
        }
        return NULL;
    }

如果处于调试状态,则用ExpUpdateDebugInfo函数填充HANDLE_TRACE_DEBUG_INFO结构,保存调试信息,否则返回NULL,调用失败

当函数调用成功就返回到PsLookupProcessByProcessId中,将HANDLE_TABLE_ENTRY中的Object转化成EPROCESS对象,确保这个对象是ProcessObject且有继承权,则引用计数加1,

  CidEntry = ExMapHandleToPointer(PspCidTable, ThreadId);
    Status = STATUS_INVALID_PARAMETER;
    if (CidEntry != NULL) {
        lThread = (PETHREAD)CidEntry->Object;
        if (lThread != (PETHREAD)PSP_INVALID_ID && lThread->Tcb.Header.Type == ThreadObject && lThread->GrantedAccess ) {

            ObReferenceObject(lThread);
            *Thread = lThread;
            Status = STATUS_SUCCESS;
        }

        ExUnlockHandleTableEntry(PspCidTable, CidEntry);
    }

然后装入参数EPROCESS,解锁当前的handle table entry,恢复当前内核线程的APC,成功返回。

时间: 2024-10-24 23:28:27

PsLookupProcessByProcessId分析的相关文章

CVE-2014-1767 利用分析(2015.2)

CVE-2014-1767利用分析 参考这篇文章利用思路,重现利用,主要说明自己在实现的时候遇到的坑. 利用思路 1. 第一次 IoControl,释放 MDL,我们通过 VirtualAddress 和 Length 设置此时被释放 的 MDL 内存大小为 0xA0. 2. NtCreateWorkerFactory 申请新的 WorkerFactoy 对象,占据[1]中被释放掉的内 存. 3. 第二次 IoControl,double free会释放掉刚刚申请的 WorkerFactoy 对

分析恶意驱动

用IDA也有好些时间了,以前就只会用F5功能玩无壳无保护的裸驱动,感觉太坑了,这两天就开始看网上大牛的逆向. 今天记录一下sudami曾经逆向过的fuck.sys.第一遍自己走的时候漏掉了好多东西,然后看他的新驱动,一步步比较, 最后把驱动文件分析的比较明朗了. 首先这个文件有的别多的花指令,jz,jnz .jb,jnb.jo,jno,js.jns. 通过idc脚本去除花指令,快捷键是shift+f2 这是DriverEntry里面的代码,首先传递[ebp+0Ch] 给函数,了解栈帧的话,就知道

爱奇艺、优酷、腾讯视频竞品分析报告2016(一)

1 背景 1.1 行业背景 1.1.1 移动端网民规模过半,使用时长份额超PC端 2016年1月22日,中国互联网络信息中心 (CNNIC)发布第37次<中国互联网络发展状况统计报告>,报告显示,网民的上网设备正在向手机端集中,手机成为拉动网民规模增长的主要因素.截至2015年12月,我国手机网民规模达6.20亿,有90.1%的网民通过手机上网. 图 1  2013Q1~2015Q3在线视频移动端和PC端有效使用时长份额对比 根据艾瑞网民行为监测系统iUserTracker及mUserTrac

Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)

原文:http://www.cnblogs.com/heshan664754022/archive/2013/03/27/2984357.html Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量) 用文本编辑工具打开用于启动Tomcat的批处理文件startup.bat,仔细阅读.在这个文件中,首先判断CATALINA_HOME环境变量是否为空,如果为空,就将当前目录设为CATALINA_HOME的值.接着判断当前目录下是否存在bin\catalina.bat,如果文件

C# 最佳工具集合: IDE 、分析、自动化工具等

C#是企业中广泛使用的编程语言,特别是那些依赖微软的程序语言.如果您使用C#构建应用程序,则最有可能使用Visual Studio,并且已经寻找了一些扩展来对您的开发进行管理.但是,这个工具列表可能会改变您编写C#代码的方式. C#编程的最佳工具有以下几类: IDE VS扩展 编译器.编辑器和序列化 反编译和代码转换工具 构建自动化和合并工具 版本控制 测试工具和VS扩展 性能分析 APM 部署自动化 容器 使用上面的链接直接跳转到特定工具,或继续阅读以浏览完整列表.

秒杀系统架构分析与实战

0 系列目录 秒杀系统架构 秒杀系统架构分析与实战 1 秒杀业务分析 正常电子商务流程 (1)查询商品:(2)创建订单:(3)扣减库存:(4)更新订单:(5)付款:(6)卖家发货 秒杀业务的特性 (1)低廉价格:(2)大幅推广:(3)瞬时售空:(4)一般是定时上架:(5)时间短.瞬时并发量高: 2 秒杀技术挑战 假设某网站秒杀活动只推出一件商品,预计会吸引1万人参加活动,也就说最大并发请求数是10000,秒杀系统需要面对的技术挑战有: 对现有网站业务造成冲击 秒杀活动只是网站营销的一个附加活动,

Openfire分析之二:主干程序分析

引言 宇宙大爆炸,于是开始了万物生衍,从一个连人渣都还没有的时代,一步步进化到如今的花花世界. 然而沧海桑田,一百多亿年过去了-. 好复杂,但程序就简单多了,main()函数运行,敲个回车,一行Hello World就出来了,所以没事多敲敲回车,可以练手感-. 一.程序入口 Java的程序入口是main方法,Openfire也不例外.可以全局检索一下"void main",可以看到,Openfire的main函数有两个: (1)org.jivesoftware.openfire.lau

gecode FunctionBranch 源码分析

从名字上看,这个类的核心就在于function, 那么看代码: /// Function to call SharedData<std::function<void(Space& home)>> f; /// Call function just once bool done; 的确是定义了一个function,然后一个状态,猜测是调用了function之后会设置为true,往下看代码: ExecStatus FunctionBranch::commit(Space&

爬虫难点分析

难点分析 1.网站采取反爬策略 2.网站模板定期变动 3.网站url抓取失败 4.网站频繁抓取ip被封 1.网站采取反爬策略 >网站默认对方正常访问的方式是浏览器访问而不是代码访问,为了防止对方使用大规模服务器进行爬虫从而导致自身服务器承受过大的压力,通常网站会采取反爬策略 根据这一特性,我们用代码模拟实现浏览器访问 2.网站模板定期变动-解决方案 >标签变动,比如<div>变动,那么我们不能把代码给写死了 (1)不同配置文件配置不同网站的模板规则 (2)数据库存储不同网站的模板规