for (i = 0; i < 1024; i++)
{
if (MmIsAddressValid((PVOID)((PULONG)TableLevel2)[i]))
{
for (j = 0; j < 512; j++)
{
if (MmIsAddressValid(TableLevel2[i][j].Object))
for (i = 0; i < 1024; i++)
{
if (MmIsAddressValid((PVOID)((PULONG)TableLevel3)[i]))
{
for (j = 0; j < 1024; j++)
{
if (MmIsAddressValid((PVOID)((PULONG*)TableLevel3)[i][j]))
{
for (k = 0; k < 512; k++)
{
if (MmIsAddressValid(TableLevel3[i][j][k].Object))
完整代码如下
#include <ntifs.h>typedef struct _LDR_DATA_TABLE_ENTRY{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
UINT16 LoadCount;
UINT16 TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
ULONG CheckSum;
ULONG TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;typedef struct _HANDLE_TABLE_ENTRY {
// // The pointer to the object overloaded with three ob attributes bits in // the lower order and the high bit to denote locked or unlocked entries //
union {
PVOID Object;
ULONG ObAttributes;
PHANDLE_TABLE_ENTRY_INFO InfoTable;
ULONG_PTR Value;
};
// // This field either contains the granted access mask for the handle or an // ob variation that also stores the same information. Or in the case of // a free entry the field stores the index for the next free entry in the // free list. This is like a FAT chain, and is used instead of pointers // to make table duplication easier, because the entries can just be // copied without needing to modify pointers. //
union {
union {
ACCESS_MASK GrantedAccess;
struct {
USHORT GrantedAccessIndex;
USHORT CreatorBackTraceIndex;
};
};
LONG NextFreeTableEntry;
};} HANDLE_TABLE_ENTRY, * PHANDLE_TABLE_ENTRY;typedef struct _OBJECT_TYPE {
ERESOURCE Mutex;
LIST_ENTRY TypeList;
UNICODE_STRING Name;
PVOID DefaultObject;
ULONG Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;#ifdef POOL_TAGGING ULONG Key;#endif //POOL_TAGGING ERESOURCE ObjectLocks[ OBJECT_LOCK_COUNT ];} OBJECT_TYPE, * POBJECT_TYPE;typedef struct _OBJECT_HEADER {
LONG PointerCount;
union {
LONG HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union {
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;} OBJECT_HEADER, * POBJECT_HEADER;VOID DriverUnload(PDRIVER_OBJECT pDriver);NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path);ULONG PspCidTable;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path){
typedef HANDLE_TABLE_ENTRY* L1P;
typedef volatile L1P* L2P;
typedef volatile L2P* L3P;
int i, j, k;
ULONG TableCode, TableLevel;
L1P TableLevel1;
L2P TableLevel2;
L3P TableLevel3;
UNICODE_STRING ProcessString, ThreadString;
ULONG HandleAddr;
PEPROCESS pEprocess;
PCHAR ImageFileName;
POBJECT_HEADER pObjectHeader;
PspCidTable = **(PULONG*)((ULONG)PsLookupProcessByProcessId + 26); // 找到PspCidTable的地址 DbgPrint("PspCidTable = %x\n", PspCidTable);
TableCode = *(PULONG)PspCidTable;
DbgPrint("TableCode = %x\n", TableCode);
TableLevel = TableCode & 0x03; // 句柄表等级 TableCode = TableCode & ~0x03; // 清除等级标志位 DbgPrint("TableLevel = %x\n", TableLevel);
DbgPrint("New_TableCode = %x\n", TableCode);
RtlInitUnicodeString(&ProcessString, L"Process");
RtlInitUnicodeString(&ThreadString, L"Thread");
switch (TableLevel)
{
case 0:
{
DbgPrint("\n一级句柄表\n");
TableLevel1 = (L1P)TableCode;
for (i = 0; i < 512; i++)
{
if (MmIsAddressValid(TableLevel1[i].Object))
{
HandleAddr = ((ULONG)(TableLevel1[i].Object) & ~0x03);
pObjectHeader = (POBJECT_HEADER)(HandleAddr - 0x18);
if (RtlCompareUnicodeString(&pObjectHeader->Type->Name, &ProcessString, TRUE) == 0)
{
pEprocess = (PEPROCESS)HandleAddr;
ImageFileName = (PCHAR)pEprocess + 0x174;
DbgPrint("进程名:%s\n", ImageFileName);
}
else if (RtlCompareUnicodeString(&pObjectHeader->Type->Name, &ThreadString, TRUE) == 0)
{
pEprocess = (PEPROCESS) * (PULONG)(HandleAddr + 0x220);
ImageFileName = (PCHAR)pEprocess + 0x174;
DbgPrint("ETHREAD: %x, 所属进程:%s\n", HandleAddr, ImageFileName);
}
else
{
DbgPrint("既不是线程也不是进程 0x%x\n", HandleAddr);
}
}
}
break;
}
case 1:
{
DbgPrint("\n二级句柄表\n");
TableLevel2 = (L2P)TableCode;
for (i = 0; i < 1024; i++)
{
if (MmIsAddressValid((PVOID)((PULONG)TableLevel2)[i]))
{
for (j = 0; j < 512; j++)
{
if (MmIsAddressValid(TableLevel2[i][j].Object))
{
HandleAddr = ((ULONG)(TableLevel2[i][j].Object) & ~0x03);
pObjectHeader = (POBJECT_HEADER)(HandleAddr - 0x18);
if (RtlCompareUnicodeString(&pObjectHeader->Type->Name, &ProcessString, TRUE) == 0)
{
pEprocess = (PEPROCESS)HandleAddr;
ImageFileName = (PCHAR)pEprocess + 0x174;
DbgPrint("进程名:%s\n", ImageFileName);
}
else if (RtlCompareUnicodeString(&pObjectHeader->Type->Name, &ThreadString, TRUE) == 0)
{
pEprocess = (PEPROCESS) * (PULONG)(HandleAddr + 0x220);
ImageFileName = (PCHAR)pEprocess + 0x174;
DbgPrint("ETHREAD: %x, 所属进程:%s\n", HandleAddr, ImageFileName);
}
else
{
DbgPrint("既不是线程也不是进程 0x%x\n", HandleAddr);
}
}
}
}
}
break;
}
case 2:
{
DbgPrint("\n三级句柄表\n");
TableLevel3 = (L3P)TableCode;
for (i = 0; i < 1024; i++)
{
if (MmIsAddressValid((PVOID)((PULONG)TableLevel3)[i]))
{
for (j = 0; j < 1024; j++)
{
if (MmIsAddressValid((PVOID)((PULONG*)TableLevel3)[i][j]))
{
for (k = 0; k < 512; k++)
{
if (MmIsAddressValid(TableLevel3[i][j][k].Object))
{
HandleAddr = ((ULONG)(TableLevel3[i][j][k].Object) & ~0x03);
pObjectHeader = (POBJECT_HEADER)(HandleAddr - 0x18);
if (RtlCompareUnicodeString(&pObjectHeader->Type->Name, &ProcessString, TRUE) == 0)
{
pEprocess = (PEPROCESS)HandleAddr;
ImageFileName = (PCHAR)pEprocess + 0x174;
DbgPrint("进程名:%s\n", ImageFileName);
}
else if (RtlCompareUnicodeString(&pObjectHeader->Type->Name, &ThreadString, TRUE) == 0)
{
pEprocess = (PEPROCESS) * (PULONG)(HandleAddr + 0x220);
ImageFileName = (PCHAR)pEprocess + 0x174;
DbgPrint("ETHREAD: %x, 所属进程:%s\n", HandleAddr, ImageFileName);
}
else
{
DbgPrint("既不是线程也不是进程 0x%x\n", HandleAddr);
}
}
}
}
}
}
}
break;
}
}
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;}VOID DriverUnload(PDRIVER_OBJECT pDriver){
DbgPrint("DriverUnload successfully!\n");}