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

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

  首先看一下函数原型

 NTSTATUS
PsLookupProcessByProcessId(
__in HANDLE ProcessId, //进程ID
__deref_out PEPROCESS *Process //返回的EPROCESS
)

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

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

  kd> u PsLookupProcessByProcessId l
nt!PsLookupProcessByProcessId:05ca38a 8bff mov edi,edi
805ca38c push ebp
805ca38d 8bec mov ebp,esp
805ca38f push ebx
805ca390 push esi
805ca391 64a124010000 mov eax,dword ptr fs:[00000124h]
805ca397 ff7508 push dword ptr [ebp+]
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)

  PsLookupProcessByHandle首先使APC无效

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

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

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

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

      LocalHandle.GenericHandleOverlay = Handle;  //会判断句柄的有效性

      HandleTableEntry = ExpLookupHandleTableEntry( HandleTable,
LocalHandle );
if (HandleTableEntry == NULL) {
return NULL;
}

  ExMapHandleToPointer调用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,成功返回。

PsLookupProcessByProcessId分析的更多相关文章

  1. 由枚举模块到ring0内存结构 (分析NtQueryVirtualMemory)

    是由获得进程模块而引发的一系列的问题,首先,在ring3层下枚举进程模块有ToolHelp,Psapi,还可以通过在ntdll中获得ZwQuerySystemInformation的函数地址来枚举,其 ...

  2. 分析恶意驱动(进程启动apc注入dll)

    一.前言  用IDA也有好些时间了,以前就只会用F5功能玩无壳无保护的裸驱动,感觉太坑了,这两天就开始看网上大牛的逆向. 今天记录一下sudami曾经逆向过的fuck.sys.第一遍自己走的时候漏掉了 ...

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

    CVE-2014-1767利用分析 参考这篇文章利用思路,重现利用,主要说明自己在实现的时候遇到的坑. 利用思路 1. 第一次 IoControl,释放 MDL,我们通过 VirtualAddress ...

  4. alias导致virtualenv异常的分析和解法

    title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...

  5. 火焰图分析openresty性能瓶颈

    注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...

  6. 一起来玩echarts系列(一)------箱线图的分析与绘制

    一.箱线图 Box-plot 箱线图一般被用作显示数据分散情况.具体是计算一组数据的中位数.25%分位数.75%分位数.上边界.下边界,来将数据从大到小排列,直观展示数据整体的分布情况. 大部分正常数 ...

  7. 应用工具 .NET Portability Analyzer 分析迁移dotnet core

    大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易.如果您创建与 .NET Core 兼容的.NET 标准库,那么现在比以往任何时候 ...

  8. UWP中新加的数据绑定方式x:Bind分析总结

    UWP中新加的数据绑定方式x:Bind分析总结 0x00 UWP中的x:Bind 由之前有过WPF开发经验,所以在学习UWP的时候直接省略了XAML.数据绑定等几个看着十分眼熟的主题.学习过程中倒是也 ...

  9. 查看w3wp进程占用的内存及.NET内存泄露,死锁分析

    一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...

随机推荐

  1. UVa 1152 4 Values whose Sum is 0

    题意:给出n,四个集合a,b,c,d每个集合分别有n个数,分别从a,b,c,d中选取一个数相加,问使得a+b+c+d=0的选法有多少种 看的紫书,先试着用hash写了一下, 是用hash[]记录下来a ...

  2. EF4.0和EF5.0增删改查写法区别

    1 public T AddEntity(T entity) 2 { 3 //EF4.0的写法 4 添加实体 5 //db.CreateObjectSet<T>().AddObject(e ...

  3. C++实现String

    # include <iostream> # include <memory> # include <cstring> using namespace std; c ...

  4. RTP/RTCP(一)-H264关于RTP协议的实现

    H264关于RTP协议的实现2010-07-22 13:35完整的C/S架构的基于RTP/RTCP的H.264视频传输方案.此方案中,在服务器端和客户端分别进行了功能模块设计.服务器端:RTP封装模块 ...

  5. liunx上运行mybase

    mybase 是个人知识管理软件,国内用他的人很多,尤其是程序员.我也是mybase的忠实使用者,有大量的积累.    以前一直用Windows,mybase使用完全没有问题,后来转投ubuntu阵营 ...

  6. 【转】cocos2d-x 3.2 Fast TileMap

    概述 在游戏中常常会有丰富的背景元素,如果直接使用大的背景图实现,这会造成资源浪费.TileMap就是为了解决这问题而产生的.Cocos2d-x支持使用Tile地图编辑器创建的TMX格式的地图. Co ...

  7. 通过简单的Linux内核启动程序代码窥探操作系统的启动原理

    作者:吴乐  山东师范大学 <Linux内核分析> 孟宁 MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.程序设计与分析 ...

  8. aggregation(2):adaptive Boosting (AdaBoost)

    给你这些水果图片,告诉你哪些是苹果.那么现在,让你总结一下哪些是苹果? 1)苹果都是圆的.我们发现,有些苹果不是圆的.有些水果是圆的但不是苹果, 2)其中到这些违反"苹果都是圆的" ...

  9. [.NET源码学习]实例化Font,遭遇字体不存在的情况。

    实例化Font类时,当传入参数为不存在或未安装的字体时,Windows系统会用Microsoft Sans Serif字体替代该字体. Msdn: "For more information ...

  10. HDU5806:NanoApe Loves Sequence Ⅱ(尺取法)

    题目链接:HDU5806 题意:找出有多少个区间中第k大数不小于m. 分析:用尺取法可以搞定,CF以前有一道类似的题目. #include<cstdio> using namespace ...