1.原因,不多说。
2.关于网上遍历对象目录的方法,思路可以借鉴,但似乎拿过来并不能遍历出我们想要的结果。
3.谢谢
FaEry 枚举办法,因为你写的那个支持的是Win10 ,所以不能满足我的效果,但给我的思路很重要。
4,进入正题:
此次要求的是操作系统,Windows XP ,下一篇将继续Win 7的研究,原因是因为系统过渡中的结构体发生了改变。
接下来是我个人分析XP对象的思路。
1.要了解怎么去遍历对象,必须明白对象是怎么样的一个结构。请参照Windbg + XP调试。可以看到这是对根目录对象的枚举
Object: e1001300(根目录对象地址) Type: (8a29f040) Directory(根目录对象类型)
ObjectHeader: e10012e8 (old version)(根目录对象的头,我猜XP被称为老版本,)
HandleCount: 0 PointerCount: 39
Directory Object: 00000000 Name: \(根目录对象的名字)
不明白,那我们再试一次 枚举设备对象(由于枚举过长,请尝试的亲们自己试一下,可以注意到,枚举的次数必然是37以内)
看到这些数据,满满的感动。确定我要枚举设备对象的思路是没有问题的。
那么根据编码,必须要确定他们的结构
根据这个,我推断出来对象头的结构是,请不要随便更改这个结构,XP上验证后再更改:
typedef struct _OBJECT_HEADER
{
ULONG PointerCount;
union
{
ULONG HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PVOID SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, * POBJECT_HEADER;
typedef struct _OBJECT_HEADER
{
ULONG PointerCount;
union
{
ULONG HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PVOID SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, * POBJECT_HEADER;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
PVOID RootDirectory;
PVOID ParseContext;
CHAR ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PVOID SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
}OBJECT_CREATE_INFORMATION,* POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
PVOID RootDirectory;
PVOID ParseContext;
CHAR ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PVOID SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
}OBJECT_CREATE_INFORMATION,* POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_HEADER_NAME_INFO
{
POBJECT_DIRECTORY Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
typedef struct _OBJECT_HEADER_NAME_INFO
{
POBJECT_DIRECTORY Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
typedef struct _OBJECT_TYPE_INITIALIZER
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
struct _OBJECT_TYPE_INITIALIZER *TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4];
USHORT Length ;
UCHAR UseDefaultObject ;
UCHAR CaseInsensitive ;
ULONG InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
ULONG ValidAccessMask ;
UCHAR SecurityRequired ;
UCHAR MaintainHandleCount ;
UCHAR MaintainTypeList ;
POOL_TYPE PoolType ;
ULONG DefaultPagedPoolCharge ;
ULONG DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
PLONG OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
PLONG ParseProcedure ;
PLONG SecurityProcedure ;
PLONG QueryNameProcedure ;
PUCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
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 ;
ULONG Key ;
ERESOURCE ObjectLocks[4] ;
} OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT_TYPE_INITIALIZER
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
struct _OBJECT_TYPE_INITIALIZER *TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4];
USHORT Length ;
UCHAR UseDefaultObject ;
UCHAR CaseInsensitive ;
ULONG InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
ULONG ValidAccessMask ;
UCHAR SecurityRequired ;
UCHAR MaintainHandleCount ;
UCHAR MaintainTypeList ;
POOL_TYPE PoolType ;
ULONG DefaultPagedPoolCharge ;
ULONG DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
PLONG OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
PLONG ParseProcedure ;
PLONG SecurityProcedure ;
PLONG QueryNameProcedure ;
PUCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
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 ;
ULONG Key ;
ERESOURCE ObjectLocks[4] ;
} OBJECT_TYPE, *POBJECT_TYPE;
请注意,查看这个对象头,它很有用,因为它里面的
NameInfoOffset 偏移指向的地址 指向了标志了对象的名字,
Type中 的Name标志了对象的类型。
那么枚举他们,我们就可以获取到对象的类型,对象的地址,以及名字(没名字也没关系)。
至于为什么他们是这样的,请参照毛德操的Windows内核源码分析中的第4章讲解了对象管理的知识。我这里不多加赘述。
迭代枚举,枚举的下一节是对象目录,如果一下节是对象目录就又迭代枚举,而目录对象的类型是用Directory标志的,所以这样我的思路就出来了。
请注意,网上那种自己算偏移得到的地址可能不适用于XP版本,故得到的结果并不正确,您可以作为参考硬编码使用。
直接上代码:(您可以直接copy,然后进行WDK编译,如有问题请联系并附上您的编译版本和操作系统)
///////////////////////////////////////////////////
//作者:wo最爱吃大白兔
//时间:2018/3/28
////////////////////////////////////////////////////
#include <ntifs.h>
#define NUMBER_HASH_BUCKETS 37
//提前声明结构体别名
typedef struct _OBJECT_DIRECTORY *POBJECT_DIRECTORY;
typedef struct _OBJECT_DIRECTORY_ENTRY *POBJECT_DIRECTORY_ENTRY;
typedef struct _DEVICE_MAP
{
POBJECT_DIRECTORY DosDevicesDirectory;
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
ULONG ReferenceCount;
ULONG DriveMap;
UCHAR DriveType[32];
} DEVICE_MAP, * PDEVICE_MAP;
typedef struct _OBJECT_DIRECTORY_ENTRY
{
POBJECT_DIRECTORY_ENTRY ChainLink;
PVOID Object;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_DIRECTORY
{
POBJECT_DIRECTORY_ENTRY HashBuckets[NUMBER_HASH_BUCKETS];
EX_PUSH_LOCK Lock;
PDEVICE_MAP DeviceMap;
ULONG SessionId;
USHORT Reserved;
USHORT SymbolicLinkUsageCount;
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
PVOID RootDirectory;
PVOID ParseContext;
CHAR ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PVOID SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
}OBJECT_CREATE_INFORMATION,* POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_HEADER
{
ULONG PointerCount;
union
{
ULONG HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PVOID SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, * POBJECT_HEADER;
typedef struct _OBJECT_HEADER_NAME_INFO
{
POBJECT_DIRECTORY Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
typedef struct _OBJECT_TYPE_INITIALIZER
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
struct _OBJECT_TYPE_INITIALIZER *TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4];
USHORT Length ;
UCHAR UseDefaultObject ;
UCHAR CaseInsensitive ;
ULONG InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
ULONG ValidAccessMask ;
UCHAR SecurityRequired ;
UCHAR MaintainHandleCount ;
UCHAR MaintainTypeList ;
POOL_TYPE PoolType ;
ULONG DefaultPagedPoolCharge ;
ULONG DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
PLONG OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
PLONG ParseProcedure ;
PLONG SecurityProcedure ;
PLONG QueryNameProcedure ;
PUCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
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 ;
ULONG Key ;
ERESOURCE ObjectLocks[4] ;
} OBJECT_TYPE, *POBJECT_TYPE;
//获取到对象的结构体部分
#define OBJECT_TO_OBJECT_HEADER( o ) \
CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
//根据对象的头获取到它的名字信息部分
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
//传入要遍历的目录
void EnumDirectory(POBJECT_DIRECTORY pObejctDirectory)
{
POBJECT_DIRECTORY_ENTRY pObjectDirectoryEntry;
POBJECT_HEADER pObjectHeader;
POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo;
int i;
POBJECT_TYPE pObjectType;
UNICODE_STRING ustrName;
RtlInitUnicodeString(&ustrName,L"Directory");
KdPrint(("------------------------------------正在遍历目录对象:[0x%08x]----------------------.\n",pObejctDirectory));
for(i = 0; i < NUMBER_HASH_BUCKETS; i ++)
{
pObjectDirectoryEntry = pObejctDirectory->HashBuckets[i];
if (!MmIsAddressValid(pObjectDirectoryEntry))
{
//KdPrint(("-->此节点遍历目录连接对象POBJECT_DIRECTORY_ENTRY无效.\n"));
continue;
}
do
{
if (!MmIsAddressValid(pObjectDirectoryEntry->Object))
{
//KdPrint(("-->此节点遍历到的对象pObjectDirectoryEntry->Object无效.\n"));
break;
}
pObjectHeader = OBJECT_TO_OBJECT_HEADER(pObjectDirectoryEntry->Object);//根据对象来获取到对象
KdPrint(("[节点 = %02d] 此对象地址为:[0x%08x] , 对象类型为:[%wZ] ,",i,pObjectDirectoryEntry->Object,&(pObjectHeader->Type->Name)));
if (pObjectHeader->NameInfoOffset > 0)
{
pObjectHeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(pObjectHeader);//获取到对象名结构体
KdPrint(("此对象名称为:[%wZ].\n",&(pObjectHeaderNameInfo->Name)));
}
else
{
KdPrint(("此对象没有名称.\n"));
}
//如果还是目录对象应该将其展开再次遍历
if (RtlCompareUnicodeString(&(pObjectHeader->Type->Name),&ustrName,TRUE) == 0)
{
EnumDirectory((POBJECT_DIRECTORY)pObjectDirectoryEntry->Object);
}
pObjectDirectoryEntry = pObjectDirectoryEntry->ChainLink;
}while(pObjectDirectoryEntry != NULL);
}
}
void DriverUnload(PDRIVER_OBJECT drv)
{
}
NTSTATUS myDispatchFunction(PDEVICE_OBJECT device,PIRP irp)
{
// 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
size_t i;
NTSTATUS status;
OBJECT_ATTRIBUTES oaDirectory;
UNICODE_STRING ustrDirectory;
PVOID DirectoryObject = NULL;
HANDLE hDirectory;
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
driver->MajorFunction[i] = myDispatchFunction;
}
driver->DriverUnload = DriverUnload;
//获取目录对象
RtlInitUnicodeString(&ustrDirectory, L"\\");
InitializeObjectAttributes(&oaDirectory, &ustrDirectory, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenDirectoryObject(&hDirectory, 0, &oaDirectory);
if (NT_SUCCESS(status) )
{
//提供对象句柄访问许可,获取到对应目录对象
status = ObReferenceObjectByHandle(hDirectory, 0x10000000, 0, 0, &DirectoryObject, 0);
if ( NT_SUCCESS(status) )
{
//从根目录对对象进行遍利,迭代算法
EnumDirectory((POBJECT_DIRECTORY)DirectoryObject);
//解除对象引用
ObfDereferenceObject(DirectoryObject);
}
status = ZwClose(hDirectory);
}
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////
//作者:wo最爱吃大白兔
//时间:2018/3/28
////////////////////////////////////////////////////
#include <ntifs.h>
#define NUMBER_HASH_BUCKETS 37
//提前声明结构体别名
typedef struct _OBJECT_DIRECTORY *POBJECT_DIRECTORY;
typedef struct _OBJECT_DIRECTORY_ENTRY *POBJECT_DIRECTORY_ENTRY;
typedef struct _DEVICE_MAP
{
POBJECT_DIRECTORY DosDevicesDirectory;
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
ULONG ReferenceCount;
ULONG DriveMap;
UCHAR DriveType[32];
} DEVICE_MAP, * PDEVICE_MAP;
typedef struct _OBJECT_DIRECTORY_ENTRY
{
POBJECT_DIRECTORY_ENTRY ChainLink;
PVOID Object;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_DIRECTORY
{
POBJECT_DIRECTORY_ENTRY HashBuckets[NUMBER_HASH_BUCKETS];
EX_PUSH_LOCK Lock;
PDEVICE_MAP DeviceMap;
ULONG SessionId;
USHORT Reserved;
USHORT SymbolicLinkUsageCount;
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
PVOID RootDirectory;
PVOID ParseContext;
CHAR ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PVOID SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
}OBJECT_CREATE_INFORMATION,* POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_HEADER
{
ULONG PointerCount;
union
{
ULONG HandleCount;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-3-28 15:02
被wo爱吃大白兔编辑
,原因: