您的位置:首页 > 其它

x64通过PspCidTable遍历进程

2016-06-05 03:10 246 查看
PspCidTable可以在PsLookupProcessByProcessId下寻找

我这硬编码了 只适用于win7 x64 其它版本需要自己改下特征码

#include <ntddk.h>

extern "C" NTKERNELAPI PVOID NTAPI
ObGetObjectType(
IN PVOID pObject
);

extern "C" NTKERNELAPI UCHAR*
PsGetProcessImageFileName(
IN PEPROCESS Process
);

#define MAX_ENTRY_COUNT (0x1000/16) //一级表中的 HANDLE_TABLE_ENTRY个数
#define MAX_ADDR_COUNT (0x1000/8) //二级表和 三级表中的地址个数

ULONG g_ProcessCount = 0;

typedef struct _EX_PUSH_LOCK // 7 elements, 0x8 bytes (sizeof)
{
union // 3 elements, 0x8 bytes (sizeof)
{
struct // 5 elements, 0x8 bytes (sizeof)
{
/*0x000*/ UINT64 Locked : 1; // 0 BitPosition
/*0x000*/ UINT64 Waiting : 1; // 1 BitPosition
/*0x000*/ UINT64 Waking : 1; // 2 BitPosition
/*0x000*/ UINT64 MultipleShared : 1; // 3 BitPosition
/*0x000*/ UINT64 Shared : 60; // 4 BitPosition
};
/*0x000*/ UINT64 Value;
/*0x000*/ VOID* Ptr;
};
}EX_PUSH_LOCK, *PEX_PUSH_LOCK;

typedef struct _HANDLE_TRACE_DB_ENTRY // 4 elements, 0xA0 bytes (sizeof)
{
/*0x000*/ struct _CLIENT_ID ClientId; // 2 elements, 0x10 bytes (sizeof)
/*0x010*/ VOID* Handle;
/*0x018*/ ULONG32 Type;
/*0x01C*/ UINT8 _PADDING0_[0x4];
/*0x020*/ VOID* StackTrace[16];
}HANDLE_TRACE_DB_ENTRY, *PHANDLE_TRACE_DB_ENTRY;

typedef struct _HANDLE_TRACE_DEBUG_INFO // 6 elements, 0xF0 bytes (sizeof)
{
/*0x000*/ LONG32 RefCount;
/*0x004*/ ULONG32 TableSize;
/*0x008*/ ULONG32 BitMaskFlags;
/*0x00C*/ UINT8 _PADDING0_[0x4];
/*0x010*/ struct _FAST_MUTEX CloseCompactionLock; // 5 elements, 0x38 bytes (sizeof)
/*0x048*/ ULONG32 CurrentStackIndex;
/*0x04C*/ UINT8 _PADDING1_[0x4];
/*0x050*/ struct _HANDLE_TRACE_DB_ENTRY TraceDb[];
}HANDLE_TRACE_DEBUG_INFO, *PHANDLE_TRACE_DEBUG_INFO;

typedef struct _HANDLE_TABLE_ENTRY // 8 elements, 0x10 bytes (sizeof)
{
union // 4 elements, 0x8 bytes (sizeof)
{
/*0x000*/ VOID* Object;
/*0x000*/ ULONG32 ObAttributes;
/*0x000*/ struct _HANDLE_TABLE_ENTRY_INFO* InfoTable;
/*0x000*/ UINT64 Value;
};
union // 3 elements, 0x8 bytes (sizeof)
{
/*0x008*/ ULONG32 GrantedAccess;
struct // 2 elements, 0x8 bytes (sizeof)
{
/*0x008*/ UINT16 GrantedAccessIndex;
/*0x00A*/ UINT16 CreatorBackTraceIndex;
/*0x00C*/ UINT8 _PADDING0_[0x4];
};
/*0x008*/ ULONG32 NextFreeTableEntry;
};
}HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

typedef struct _HANDLE_TABLE
{
ULONG64 TableCode;
PEPROCESS QuotaProcess;
PVOID UniqueProcessId;
EX_PUSH_LOCK HandleLock;
LIST_ENTRY HandleTableList;
EX_PUSH_LOCK HandleContentionEvent;
PHANDLE_TRACE_DEBUG_INFO DebugInfo;
LONG ExtraInfoPages;
ULONG Flags;
//ULONG StrictFIFO : 1;
LONG64 FirstFreeHandle;
PHANDLE_TABLE_ENTRY LastFreeHandleEntry;
LONG HandleCount;
ULONG NextHandleNeedingPool;
} HANDLE_TABLE, *PHANDLE_TABLE;

typedef BOOLEAN (*MY_ENUMERATE_HANDLE_ROUTINE)(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter);

SIZE_T FindCidTable()
{
SIZE_T CidTableAddr = 0;
UNICODE_STRING ustPsFuncName;
RtlInitUnicodeString(&ustPsFuncName, L"PsLookupProcessByProcessId");
PUCHAR startAddr = (PUCHAR)MmGetSystemRoutineAddress(&ustPsFuncName);

for (ULONG64 i = 0; i < 100; i++)
{
if (*(startAddr + i) == 0x48 &&
*(startAddr + i + 1) == 0x8b &&
*(startAddr + i + 2) == 0x0d)
{
CidTableAddr = (SIZE_T)(*(PULONG)(startAddr + i + 3) + (startAddr + i + 3 + 4)) & 0xFFFFFFFEFFFFFFFF;
DbgPrint("CidTableAddr:%p\n", CidTableAddr);
break;
}
}
return CidTableAddr;
}

BOOLEAN MyEnumerateHandleRoutine(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter
)
{
BOOLEAN Result = FALSE;
ULONG64 ProcessObject;
POBJECT_TYPE ObjectType;
PVOID Object;
UNICODE_STRING ustObjectName;

UNREFERENCED_PARAMETER(EnumParameter);
UNREFERENCED_PARAMETER(ustObjectName);
ProcessObject = (HandleTableEntry->Value)&~7; //掩去低三位
Object = (PVOID)((ULONG64)HandleTableEntry->Object&~7);

ObjectType = (POBJECT_TYPE)ObGetObjectType(Object);
if (MmIsAddressValid(HandleTableEntry))
{
if (ObjectType == *PsProcessType)//判断是否为Process
{
//注意PID其实就是Handle,而 不是从EPROCESS中取,可以对付伪pid
g_ProcessCount++;
DbgPrint("PID=%4d\t EPROCESS=0x%p %s\n", Handle, ProcessObject, PsGetProcessImageFileName((PEPROCESS)ProcessObject));
}
}
return Result;//返回FALSE继续
}

//自己实现一个山寨的MyEnumHandleTable,接口和ExEnumHandleTable一样
BOOLEAN
MyEnumHandleTable(
PHANDLE_TABLE HandleTable,
MY_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
PVOID EnumParameter,
PHANDLE Handle
)
{
ULONG64 i, j, k;
ULONG_PTR CapturedTable;
ULONG64 TableLevel;
PHANDLE_TABLE_ENTRY TableLevel1, *TableLevel2, **TableLevel3;
BOOLEAN CallBackRetned = FALSE;
BOOLEAN ResultValue = FALSE;
ULONG64 MaxHandle;
//判断几个参数是否有效
if (!HandleTable
&& !EnumHandleProcedure
&& !MmIsAddressValid(Handle))
{
return ResultValue;
}
//取表基址和表的级数
CapturedTable = (HandleTable->TableCode)&~3;
TableLevel = (HandleTable->TableCode) & 3;
MaxHandle = HandleTable->NextHandleNeedingPool;
DbgPrint("句柄上限值为0x%X\n", MaxHandle);
//判断表的等级
switch (TableLevel)
{
case 0:
{
//一级表
TableLevel1 = (PHANDLE_TABLE_ENTRY)CapturedTable;
DbgPrint("解析一级表 0x%p...\n", TableLevel1);
for (i = 0; i < MAX_ENTRY_COUNT; i++)
{
*Handle = (HANDLE)(i * 4);
if (TableLevel1[i].Object && MmIsAddressValid(TableLevel1[i].Object))
{
//对象有效时,再调用回调函数
CallBackRetned = EnumHandleProcedure(&TableLevel1[i], *Handle, EnumParameter);
if (CallBackRetned) break;
}
}
ResultValue = TRUE;

}
break;
case 1:
{
//二级表
TableLevel2 = (PHANDLE_TABLE_ENTRY*)CapturedTable;
DbgPrint("解析二级表 0x%p...\n", TableLevel2);
DbgPrint("二级表的个 数:%d\n", MaxHandle / (MAX_ENTRY_COUNT*4));
for (j = 0; j < MaxHandle / (MAX_ENTRY_COUNT * 4); j++)
{
TableLevel1 = TableLevel2[j];
if (!TableLevel1)
break; //为零则跳出
for (i = 0; i < MAX_ENTRY_COUNT; i++)
{
*Handle = (HANDLE)(j*MAX_ENTRY_COUNT * 4 + i * 4);
if (TableLevel1[i].Object && MmIsAddressValid(TableLevel1[i].Object))
{
//对象有效时,再调用回调函数
CallBackRetned = EnumHandleProcedure(&TableLevel1[i], *Handle, EnumParameter);
if (CallBackRetned) break;
}
}
}
ResultValue = TRUE;
}
break;
case 2:
{
//三级表
TableLevel3 = (PHANDLE_TABLE_ENTRY**)CapturedTable;
DbgPrint("解析三级表 0x%p...\n", TableLevel3);
DbgPrint("三级表的个 数:%d\n", MaxHandle / (MAX_ENTRY_COUNT * 4 * MAX_ADDR_COUNT));
for (k = 0; k < MaxHandle / (MAX_ENTRY_COUNT * 4 * MAX_ADDR_COUNT); k++)
{
TableLevel2 = TableLevel3[k];
if (!TableLevel2)
break; //为零则跳出
for (j = 0; j < MaxHandle / (MAX_ENTRY_COUNT * 4); j++)
{
TableLevel1 = TableLevel2[j];
if (!TableLevel1)
break; //为零则跳出
for (i = 0; i < MAX_ENTRY_COUNT; i++)
{
*Handle = (HANDLE)(k*MAX_ENTRY_COUNT*MAX_ADDR_COUNT + j*MAX_ENTRY_COUNT + i * 4);
if (TableLevel1[i].Object && MmIsAddressValid(TableLevel1[i].Object))
{
//对象有效时,再调用回调函数
CallBackRetned = EnumHandleProcedure(&TableLevel1[i], *Handle, EnumParameter);
if (CallBackRetned) break;
}
}
}
}
ResultValue = TRUE;
}
break;
default:
{
DbgPrint("BOOM!\n");
}
break;
}
DbgPrint("ProcessCount:0x%x",g_ProcessCount);
return ResultValue;
}

void EnumProcessByPspCidTable()
{
PHANDLE_TABLE pHandleTable = NULL;
pHandleTable =(PHANDLE_TABLE)*(PSIZE_T)FindCidTable();
HANDLE hHanel;
UNICODE_STRING usObGetObjectType;
DbgPrint("pHandleTable:%p\n", pHandleTable);
MyEnumHandleTable(pHandleTable, MyEnumerateHandleRoutine, NULL, &hHanel);
}

void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UNREFERENCED_PARAMETER(pDriverObject);
DbgPrint("GoodBye!\n");
}

extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegPath)
{
UNREFERENCED_PARAMETER(pRegPath);

pDriverObject->DriverUnload = DriverUnload;

DbgPrint("DriverEntry!\n");

EnumProcessByPspCidTable();

return STATUS_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息