遍历PspCidTable枚举进程

//测试环境:win7 32位  1 // DriverEntry.cpp
  2
  3 #include "ntddk.h"
  4 #include <ntddvol.h>
  5 #include <ntdef.h>
  6 #include "header.h"
  7
  8 extern "C" POBJECT_TYPE ObGetObjectType(IN PVOID Object);
  9 extern "C" NTSTATUS DefaultDispatch (
 10     __in struct _DEVICE_OBJECT *DeviceObject,
 11     __inout struct _IRP *Irp
 12     )
 13 {
 14     Irp->IoStatus.Status = STATUS_SUCCESS;
 15     Irp->IoStatus.Information = 0;
 16     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 17
 18     return STATUS_SUCCESS;
 19 }
 20 VOID DriverUnload (
 21     __in struct _DRIVER_OBJECT *DriverObject
 22     )
 23 {
 24
 25 }
 26
 27 extern "C" void* GetPspCidTable()
 28 {
 29     UNICODE_STRING sysRoutineName;
 30     RtlInitUnicodeString(&sysRoutineName, L"PsLookupProcessByProcessId");
 31     PUCHAR pFun = (PUCHAR)MmGetSystemRoutineAddress(&sysRoutineName);
 32     if (pFun)
 33     {
 34         do
 35         {
 36             if(!MmIsAddressValid(pFun) || !MmIsAddressValid((PUCHAR)pFun + 6))
 37             {
 38                 return NULL;
 39             }
 40             if (*(PSHORT)pFun == 0X3D8B && *((PUCHAR)pFun + 6) == 0Xe8)
 41             {
 42                 unsigned int pspCidTable =  *((unsigned int *)((PUCHAR)pFun + 2));
 43                 DbgPrint("%x", pspCidTable);
 44                 return (void*)pspCidTable;
 45                 //break;
 46             }
 47             pFun++;
 48         } while (1);
 49     }
 50     return NULL;
 51 }
 52
 53 void EnumLevel1Tabel(PUCHAR pLevel1Table)
 54 {
 55     DbgPrint("Table1:%x\n", pLevel1Table);
 56     PHANDLE_TABLE_ENTRY phte = (PHANDLE_TABLE_ENTRY)pLevel1Table;
 57     for (ULONG i = 0; i < 512; i++)   //512为一级表项数,单位:HANDLE_TABLE_ENTRY
 58     {
 59         PEPROCESS pProcess = (PEPROCESS)phte->Object;
 60         POBJECT_TYPE objType;
 61         objType = *PsProcessType;
 62         pProcess = (PEPROCESS)((ULONG)pProcess & 0xfffffff8);  //后三位不知干什么。
 63         if (pProcess != NULL && objType == ObGetObjectType(pProcess))
 64         {
 65             DbgPrint("Process Name:%s\n", (PUCHAR)pProcess + 0x16c);
 66         }
 67         phte++;
 68     }
 69 }
 70
 71 void EnumLevel2Tabel(PULONG pLevel2Table)
 72 {
 73     DbgPrint("EnumLevel2Tabel:%x\n", pLevel2Table);
 74     for (ULONG i = 0; i < 1024; i++) //1024为二级表项数,单位:PHANDLE_TABLE_ENTRY
 75     {
 76         if (*pLevel2Table != 0)
 77         {
 78             EnumLevel1Tabel((PUCHAR)*pLevel2Table);
 79         }
 80         else
 81         {
 82             break;
 83         }
 84         pLevel2Table++;
 85     }
 86 }
 87 void EnumLevel3Tabel(PULONG pLevel3Table)
 88 {
 89     DbgPrint("EnumLevel3Tabel:%x\n", pLevel3Table);
 90     for (ULONG i = 0; i < 32; i++) //32为三级表项数,单位:PHANDLE_TABLE_ENTRY*
 91     {
 92         if (*pLevel3Table != 0)
 93         {
 94             EnumLevel2Tabel((PULONG)*pLevel3Table);
 95         }
 96         else
 97         {
 98             break;
 99         }
100         pLevel3Table++;
101     }
102 }
103 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
104 {
105     for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
106     {
107         DriverObject->MajorFunction[i] = DefaultDispatch;
108     }
109     DriverObject->DriverUnload = DriverUnload;
110     PHANDLE_TABLE * pPspCidTable = (PHANDLE_TABLE* )GetPspCidTable();
111     if (pPspCidTable == NULL)
112     {
113         return STATUS_UNSUCCESSFUL;
114     }
115     __asm {int 3}
116     DbgPrint("pPspCidTable:%x\n", pPspCidTable);
117
118     PHANDLE_TABLE pspCidTable = *pPspCidTable;
119     ULONG level = pspCidTable->TableCode & 3;  //取后2位,得出句柄表的级数。
120     PUCHAR tableBase = (PUCHAR)pspCidTable->TableCode - level;
121     DbgPrint("level:%d\n", level);
122     DbgPrint("tableBase:%d\n", tableBase);
123     switch(level)
124     {
125     case 0:
126         {
127             EnumLevel1Tabel((PUCHAR)tableBase);
128         }
129         break;
130     case 1:
131         {
132             EnumLevel2Tabel((PULONG)tableBase);
133         }
134         break;
135     case  2:
136         {
137             EnumLevel3Tabel((PULONG)tableBase);
138         }
139
140     }
141     return STATUS_SUCCESS;
142 }
 1 //header.h
 2 #ifndef HEADER_H
 3 #define HEADER_H
 4 typedef struct  _HANDLE_TABLE
 5 {
 6     ULONG_PTR TableCode;
 7     PEPROCESS QuotaProcess;
 8     PVOID UniqueProcessId;
 9     PVOID HandleLock;
10     LIST_ENTRY HandleTableList;
11     PVOID HandleContentionEvent;
12     PVOID DebugInfo;
13     LONG ExtraInfoPages;
14     union
15     {
16     ULONG Flags;
17     UCHAR StrictFIFO:1;
18     };
19     LONG FirstFreeHandle;
20     PVOID    LastFreeHandleEntry;
21     LONG HandleCount;
22     ULONG NextHandleNeedingPool;
23     ULONG HandleCountHighWatermark;
24 }HANDLE_TABLE, *PHANDLE_TABLE;
25
26
27 typedef struct _HANDLE_TABLE_ENTRY
28 {
29     union
30     {
31         PVOID Object;
32         ULONG_PTR ObAttributes;
33         PVOID InfoTable;
34         ULONG_PTR Value;
35     };
36     union
37     {
38         ULONG GrantedAccess;
39         struct
40         {
41             USHORT GrantedAccessIndex;
42             USHORT CreatorBackTraceIndex;
43         };
44         LONG NextFreeTableEntry;
45     };
46 } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
47 #endif
时间: 2024-12-15 11:05:11

遍历PspCidTable枚举进程的相关文章

遍历PspCidTable表检测隐藏进程

一.PspCidTable概述 PspCidTable也是一个句柄表,其格式与普通的句柄表是完全一样的,但它与每个进程私有的句柄表有以下不同: 1.PspCidTable中存放的对象是系统中所有的进程线程对象,其索引就是PID和TID. 2.PspCidTable中存放的直接是对象体(EPROCESS和ETHREAD),而每个进程私有的句柄表则存放的是对象头(OBJECT_HEADER). 3.PspCidTable是一个独立的句柄表,而每个进程私有的句柄表以一个双链连接起来.注意访问对象时要掩

delphi中获得进程列表或想要的进程(枚举进程、遍历进程)

一个常见的编程任务是枚举所有运行的"应用程序".Windows 任务管理器就是一个很好的例子.它用两种方式列出"应用程序".任务管理器的第一个选项卡列出桌面上的所有"应用程序窗口".第二个选项卡列出系统中的所有"进程".本文提供了如何执行这些任务的详细信息. 枚举顶层窗口如果将枚举进程与枚举桌面上的顶层窗口进行比较,那么枚举顶层窗口可能更容易一些.要枚举顶层窗口,请使用 EnumWindows() 函数.不要使用 GetWin

【旧文章搬运】遍历EPROCESS中的ActiveProcessLinks枚举进程

原文发表于百度空间,2008-7-25========================================================================== 前面对PEB的相关结构和其中的重要成员进行了分析和学习,现在开始真正进入内核,学习内核中的一些结构.这个EPROCESS结构在ntddk.h中有定义,但是并未给出具体的结构,因此要得到EPROCESS中一些重要的成员变量,只能通过偏移的方法,比如PID,ImageName等.这些偏移可以在Windbg中dt _

枚举进程再来两弹

看了刚出几个博友的博客,感觉人家的量大,详细,干货量实足啊, 所以我就把另外两种常见的枚举进程的方法简单说下心得, 一个是EnumProcesses和CreateToolhelp32Snapshot系列的Tool help API的 Process32First和Process32Next函数完成列举进程. 这两种都是比较简单实用的 https://github.com/Arsense/WindowsCode 蛮简单的  需要编译好的源码的 支持vs2015,低版本的VS想编译 简单右键工程 属

利用服务枚举进程

枚举进程的方法有许多,简单说一下它们的优缺点. 1.利用CreateToolhelp32Snapshot来枚举,这是最常用,也最简单的方法了,不用多说. 2.利用ZwQuerySystemInformation从ntdll.dll中获取,需要定义结构体SYSTEM_PROCESS_INFORMATION,还有对应的函数指针,但是要注意一点,申请内存之后,要判断ZwQuerySystemInformation的返回值是不是STATUS_INFO_LENGTH_MISMATCH,如果是,说明内存不足

暴力枚举进程模块

同学问过我进程体中EPROCESS的三条链断了怎么枚举模块,这也是也腾讯面试题.我当时听到也是懵逼的. 后来在网上看到了一些内存暴力枚举的方法ZwQueryVirtualMemory. 函数原型是 NTSTATUS NtQueryVirtualMemory(HANDLE ProcessHandle, //目标进程句柄 PVOID BaseAddress, //查询的基址 MEMORY_INFORMATION_CLASS MemoryInformationClass, //枚举宏 PVOID Me

C#实现二叉树的遍历

C#实现二叉树的前序.中序.后序遍历. public class BinaryTreeNode     {         int value;         BinaryTreeNode left;         BinaryTreeNode right;         /// <summary>         /// 前序遍历         /// </summary>         /// <param name="tree">&l

Android sqlite cursor的遍历

查询并获得了cursor对象后,用while(corsor.moveToNext()){}遍历,当corsor.moveToNext()方法调用,如果发现没有对象,会返回false public List<MMImage> getAll() { List<MMImage> list = new ArrayList<MMImage>(); Cursor c = null; try { c = database.query(TABLE, null, null, null,

【树4】二叉树的遍历

简介 遍历二叉树就是按照某种顺序,将树中的结点都枚举一遍,且每个结点仅仅访问一次.因为树不是线性的结构,遍历不像线性表那样简单,因此他的遍历需要特点的算法来完成. 从某种角度讲,对二叉树的遍历就是将树形结构转换为线性结构的操作. 二叉树的遍历方法主要有如下几种: 先序遍历:先访问root结点,再先序遍历左子树,再先序遍历右子树. 中序遍历:先中序遍历左子树,再访问root结点,再中序遍历右子树. 后序遍历:先后序遍历左子树,再后序遍历右子树,再访问root结点. 层遍历:从上到下,从左到右,一层