实验环境:win10 1909 64
(2022/03/24,在 win11 10.0.2200.318上,调用ZwQuerySystemInformation获取句柄信息,返回错误:0xc0000005)
首先,获取系统的句柄信息;然后,在句柄信息表中进行搜索,通过数据结构进行匹配;最后,确定系统进程和当前进程的eprocess;
主要数据结构如下:
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
成员的含义:
UniqueProcessId,表示进程号,也就是该句柄所属的进程。比如进程a(进程号为0x336)打开了文件b,产生了一个句柄c(其值为0x1900);以上过程会产生一个系统句柄表项:
{
USHORT UniqueProcessId=0x336
USHORT CreatorBackTraceIndex; //暂空
UCHAR ObjectTypeIndex=0x25;//0x25 对应文件类型对象
UCHAR HandleAttributes;//暂空
USHORT HandleValue=0x1900;//句柄值
PVOID Object;//对应一个文件对象
ULONG GrantedAccess;//暂空
}
利用上面的数据信息,获取系统进程和当前进程的eprocess:
# define ProcessObjectTypeIndex 0x7
# define SystemProcessId 0x4
# define SystemProcessHandleValue 0x4
//
//通过进程号(ProcessId),获取进程对象eprocess
// 获取系统进程和当前进程的eprocess
//参数:PID
ULONG64 GetEprocessFromPid(ULONG PID)
{
NTSTATUS status;
PVOID buf = NULL;
ULONG size = 0x1000;
ULONG result = 0;
ULONG NumOfHandle = 0;
PSYSTEM_HANDLE_TABLE_ENTRY_INFO h_info = NULL;
HANDLE hCurrentProcess = INVALID_HANDLE_VALUE;
printf("[++]enter GetEprocessFromPid(*)\n");
//申请当前进程的句柄
printf("[++]Current Process ID:%d\n", PID);
hCurrentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
do {
buf = malloc(size);
status = NtQuerySystemInformation(SystemHandleInformation, buf, size, &result);
if (!NT_SUCCESS(status))
{
if (STATUS_INFO_LENGTH_MISMATCH == status)
{
free(buf);
buf = NULL;
size = size * 2;
continue;
}
else
{
printf("ZwQuerySystemInformation() failed");
return status;
}
}
else
{
break;
}
} while (true);
//返回到缓冲区的首先是一个ULONG类型的数据,表示有多少数组
printf("[++]get system handle information\n");
NumOfHandle = ((PSYSTEM_HANDLE_INFORMATION)buf)->NumberOfHandles;
printf("[++]there are %d entries!\n", NumOfHandle);
h_info = ((PSYSTEM_HANDLE_INFORMATION)buf)->Handles;
for (i = 0; i < NumOfHandle; i++)
{
if ((h_info[i].ObjectTypeIndex == ProcessObjectTypeIndex))
{
//获取系统进程(system)的eprocess
//系统进程中的句柄值为0x4的句柄,通常对应的系统进程
if (h_info[i].UniqueProcessId == SystemProcessId&&h_info[i].HandleValue==SystemProcessHandleValue)
{
printf("System Process Object 0x%p\n", h_info[i].Object);
}
//获取当前进程的eprocess
//与之前获取的当前进程的句柄值进行对比
if (h_info[i].UniqueProcessId == PID&&(h_info[i].HandleValue==(USHORT)hCurrentProcess))
{
printf("Current Process Object 0x%p\n", h_info[i].Object);
}
}
}
if (hCurrentProcess)
{
CloseHandle(hCurrentProcess);
}
if (buf != NULL)
{
free(buf);
buf = NULL;
}
return(FALSE);
}
测试结构: