Ring3枚举系统对象类型
刚开始想到的方式:
NtQueryObject(NULL或者INVALID_HANDLE_VALUE,ObjectTypesInformation,...);
#include <Windows.h>
#include <stdio.h>
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation, // OBJECT_BASIC_INFORMATION
ObjectNameInformation, // OBJECT_NAME_INFORMATION
ObjectTypeInformation, // OBJECT_TYPE_INFORMATION
ObjectTypesInformation, // OBJECT_TYPES_INFORMATION
ObjectHandleFlagInformation // OBJECT_HANDLE_FLAG_INFORMATION
} OBJECT_INFORMATION_CLASS;
typedef struct _UNICODE_STRING_
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
}UNICODE_STRING,*PUNICODE_STRING;
typedef struct _OBJECT_TYPE_INFORMATION
{
UNICODE_STRING TypeName;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG TotalPagedPoolUsage;
ULONG TotalNonPagedPoolUsage;
ULONG TotalNamePoolUsage;
ULONG TotalHandleTableUsage;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
ULONG HighWaterPagedPoolUsage;
ULONG HighWaterNonPagedPoolUsage;
ULONG HighWaterNamePoolUsage;
ULONG HighWaterHandleTableUsage;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
UCHAR TypeIndex; // since WINBLUE
CHAR ReservedByte;
ULONG PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef struct _OBJECT_TYPES_INFORMATION
{
ULONG NumberOfTypes;
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
ULONG bufferSize;
#define ALIGN_DOWN(Length, Type) ((ULONG)(Length) & ~(sizeof(Type) - 1))
#define ALIGN_UP(Length, Type) (ALIGN_DOWN(((ULONG)(Length) + sizeof(Type) - 1), Type))
NTSTATUS QueryObjectTyps(
_Out_ POBJECT_TYPES_INFORMATION *ObjectTypes
)
{
typedef
NTSTATUS(NTAPI *NtQueryObject )(
_In_ HANDLE Handle,
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength
);
NtQueryObject lpFnNtQueryObject =(NtQueryObject) GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQueryObject");
NTSTATUS status;
PVOID buffer;
bufferSize = 0x1000;
buffer = VirtualAlloc(NULL,bufferSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
while ((status = lpFnNtQueryObject(
INVALID_HANDLE_VALUE,
ObjectTypesInformation,
buffer,
bufferSize,
NULL
)) == STATUS_INFO_LENGTH_MISMATCH)
{
VirtualFree(buffer,bufferSize,MEM_RELEASE);
bufferSize *= 2;
buffer = VirtualAlloc(NULL,bufferSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
}
if (!NT_SUCCESS(status))
{
VirtualFree(buffer,bufferSize,MEM_RELEASE);
return status;
}
*ObjectTypes = (POBJECT_TYPES_INFORMATION)buffer;
return status;
}
typedef struct _OBJECT_TYPE_
{
WCHAR szObjectName[0x40];
}OBJECT_TYPE,*POBJECT_TYPE;
OBJECT_TYPE ObjectBuffer[80];
int main()
{
POBJECT_TYPES_INFORMATION objectTypes;
POBJECT_TYPE_INFORMATION objectType;
if (NT_SUCCESS(QueryObjectTyps(&objectTypes)))
{
objectType = (POBJECT_TYPE_INFORMATION)((PCHAR)objectTypes + sizeof(ULONG_PTR)); // 对齐问题
for (ULONG i = 0; i < objectTypes->NumberOfTypes; ++i) {
memcpy(ObjectBuffer[objectType->TypeIndex].szObjectName,objectType->TypeName.Buffer,(wcslen(objectType->TypeName.Buffer)+1)*sizeof(WCHAR));
printf("%d\t%S\r\n",objectType->TypeIndex,objectType->TypeName.Buffer);
objectType = (POBJECT_TYPE_INFORMATION)((PCHAR)(objectType + 1) + ALIGN_UP(objectType->TypeName.MaximumLength, ULONG_PTR));// 对齐问题,一定要注意了
}
printf("%d",objectTypes->NumberOfTypes);
}
else
{
MessageBox(NULL,"QueryObjectTypes Error","-_-",MB_OK);
}
VirtualFree(objectTypes,bufferSize,MEM_RELEASE);
getchar();
getchar();
return 0;
}
但是Wind10下获得不到下面罗列的这几个对象及其TypeIndexif"DmaAdapter""DmaDomain""DxgkSharedResource""DxgkSharedSyncObject""DxgkSharedSwapChainObject""FilterCommunicationPort""FilterConnectionPort""NdisCmState""PcwObject""VirtualKey""VRegConfigurationContext"
然后枚举进程对象的时候发现,可以获得且没有枚举出来的对象类型为:dwm 进程的 DxgkSharedResource 类型的句柄
关于dwm 进程:
http://www.cnblogs.com/technology/archive/2011/07/21/dwm_exe.html
后来想到一种方法:
根据需要来获得对象的类型名,设置一个全局的数组,然后给定的TypeIndex 对应的名称已经有了,直接使用,否则,NtQueryObject(TargetHandle,ObjectTypeInformation…)获得当前对象的类型,并存储在全局数组中。