通过遍历系统句柄信息(SystemHandleInformation),获取系统进程和当前进程的eprocess

2023-05-16

实验环境:win10 1909 64

(2022/03/24,在 win11 10.0.2200.318上,调用ZwQuerySystemInformation获取句柄信息,返回错误:0xc0000005)

参考:获得进程的EPROCESS_尘埃落定-CSDN博客

首先,获取系统的句柄信息;然后,在句柄信息表中进行搜索,通过数据结构进行匹配;最后,确定系统进程和当前进程的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);
}

测试结构:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过遍历系统句柄信息(SystemHandleInformation),获取系统进程和当前进程的eprocess 的相关文章

随机推荐