首页 > windows 系统枚举任意内核进程对象的问题

windows 系统枚举任意内核进程对象的问题

原文地址:http://www.tuicool.com/articles/vaeAB3

最后一个方法 void EnumObjInfo(LPVOID pBuffer, DWORD pid)

pBuffer 是传什么进去?

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
//#include "ntsecapi.h"


typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation,              // 0        Y        N
    SystemProcessorInformation,          // 1        Y        N
    SystemPerformanceInformation,        // 2        Y        N
    SystemTimeOfDayInformation,          // 3        Y        N
    SystemNotImplemented1,               // 4        Y        N
    SystemProcessesAndThreadsInformation, // 5       Y        N
    SystemCallCounts,                    // 6        Y        N
    SystemConfigurationInformation,      // 7        Y        N
    SystemProcessorTimes,                // 8        Y        N
    SystemGlobalFlag,                    // 9        Y        Y
    SystemNotImplemented2,               // 10       Y        N
    SystemModuleInformation,             // 11       Y        N
    SystemLockInformation,               // 12       Y        N
    SystemNotImplemented3,               // 13       Y        N
    SystemNotImplemented4,               // 14       Y        N
    SystemNotImplemented5,               // 15       Y        N
    SystemHandleInformation,             // 16       Y        N
    SystemObjectInformation,             // 17       Y        N
    SystemPagefileInformation,           // 18       Y        N
    SystemInstructionEmulationCounts,    // 19       Y        N
    SystemInvalidInfoClass1,             // 20
    SystemCacheInformation,              // 21       Y        Y
    SystemPoolTagInformation,            // 22       Y        N
    SystemProcessorStatistics,           // 23       Y        N
    SystemDpcInformation,                // 24       Y        Y
    SystemNotImplemented6,               // 25       Y        N
    SystemLoadImage,                     // 26       N        Y
    SystemUnloadImage,                   // 27       N        Y
    SystemTimeAdjustment,                // 28       Y        Y
    SystemNotImplemented7,               // 29       Y        N
    SystemNotImplemented8,               // 30       Y        N
    SystemNotImplemented9,               // 31       Y        N
    SystemCrashDumpInformation,          // 32       Y        N
    SystemExceptionInformation,          // 33       Y        N
    SystemCrashDumpStateInformation,     // 34       Y        Y/N
    SystemKernelDebuggerInformation,     // 35       Y        N
    SystemContextSwitchInformation,      // 36       Y        N
    SystemRegistryQuotaInformation,      // 37       Y        Y
    SystemLoadAndCallImage,              // 38       N        Y
    SystemPrioritySeparation,            // 39       N        Y
    SystemNotImplemented10,              // 40       Y        N
    SystemNotImplemented11,              // 41       Y        N
    SystemInvalidInfoClass2,             // 42
    SystemInvalidInfoClass3,             // 43
    SystemTimeZoneInformation,           // 44       Y        N
    SystemLookasideInformation,          // 45       Y        N
    SystemSetTimeSlipEvent,              // 46       N        Y
    SystemCreateSession,                 // 47       N        Y
    SystemDeleteSession,                 // 48       N        Y
    SystemInvalidInfoClass4,             // 49
    SystemRangeStartInformation,         // 50       Y        N
    SystemVerifierInformation,           // 51       Y        Y
    SystemAddVerifier,                   // 52       N        Y
    SystemSessionProcessesInformation    // 53       Y        N
} SYSTEM_INFORMATION_CLASS;

typedef NTSTATUS(WINAPI *ZWQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
typedef enum _OBJECT_INFORMATION_CLASS {
    ObjectBasicInformation,
    ObjectNameInformation,
    ObjectTypeInformation,
    ObjectAllInformation,
    ObjectDataInformation,
} OBJECT_INFORMATION_CLASS;
typedef NTSTATUS(NTAPI *NTQUERYOBJECT)(
    HANDLE Handle,
    OBJECT_INFORMATION_CLASS ObjectInformationClass,
    PVOID ObjectInformation,
    ULONG ObjectInformationLength,
    PULONG ReturnLength
    );
typedef struct _UNICODE_STRING {
    USHORT  Length;     //UNICODE占用的内存字节数,个数*2;
    USHORT  MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_NAME_INFORMATION {
    UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG ProcessId;
    UCHAR ObjectTypeNumber;
    UCHAR Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
}SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_INFORMATION Information[1];
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
#define SystemHandleInformation 0x10  // 16



ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;// = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwQuerySystemInformation");
NTQUERYOBJECT    NtQueryObject;// = (NTQUERYOBJECT)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryObject");
                               /*功能函数体*/
void EnumObjInfo(LPVOID pBuffer, DWORD pid);
int _tmain1(int argc, _TCHAR* argv[])
{
     ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "ZwQuerySystemInformation");
        NtQueryObject = (NTQUERYOBJECT)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQueryObject");
    
    EnumObjInfo("Mutant",3816);

}

void EnumObjInfo(LPVOID pBuffer, DWORD pid)
{
    char szType[128] = { 0 };
    char szName[512] = { 0 };
    DWORD dwFlags = 0;

    POBJECT_NAME_INFORMATION pNameInfo;
    POBJECT_NAME_INFORMATION pNameType;

    PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;
    ULONG OldPID = 0;
    for (DWORD i = 0; i < pInfo->NumberOfHandles; i++)
    {
        if (OldPID != pInfo->Information[i].ProcessId)
        {
            if (pInfo->Information[i].ProcessId == pid)
            {

                HANDLE newHandle;
                DuplicateHandle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, pInfo->Information[i].ProcessId), (HANDLE)pInfo->Information[i].Handle, GetCurrentProcess(), &newHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS);
                NTSTATUS status1 = NtQueryObject(newHandle, ObjectNameInformation, szName, 512, &dwFlags);
                NTSTATUS status2 = NtQueryObject(newHandle, ObjectTypeInformation, szType, 128, &dwFlags);
                if (strcmp(szName, "") && strcmp(szType, "") && status1 != 0xc0000008 && status2 != 0xc0000008)
                {
                    pNameInfo = (POBJECT_NAME_INFORMATION)szName;
                    pNameType = (POBJECT_NAME_INFORMATION)szType;
                    printf("%wZ   ", pNameType);
                    printf("%wZ \n", pNameInfo);
                }
            }
        }
    }

}

首先:

PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer

所以pBuffer就是PSYSTEM_HANDLE_INFORMATION_EX,然后我们来看它的定义:

typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_INFORMATION Information[1];
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX

这是一个SYSTEM_HANDLE_INFORAMTION的数组,但是有点不同的是,前面需要一个NumberOfHandlers来告诉你Information到底有多长。于是如果你要提供一个长度为5的数组,那你需要malloc的大小就是

sizeof(ULONG) + 5 * sizeof(SYSTEM_HANDLE_INFORMATION)

不过我很奇怪的是,为什么main函数里面要传一个字符串进去?这个函数的pBuffer肯定不是一个字符串。从代码里面可以看出,这个pBuffer就是你贴的文章里面的GetSystemProcessHandleInfo函数分配出来的。ZwQuerySystemInformation最后会按照上面的格式填充你给的buffer(但是他没告诉你要多长,所以才需要用一个循环不断地尝试),填满了所有的这些信息,然后你才能在EnumObjInfo里面打印出来。

所以你应该首先调用GetSystemProcessHandleInfo,然后直接丢给EnumObjInfo就可以了。


从代码中看pBuffer代表的是内核对象类型名称。Mutant是突变体,另外还有Section是内存文件映射,Semaphore是信号量,Thread和Process不解释了,Event是事件,File是文件,IoCompletion是完成端口……还有其他类型的内核对象,具体请参考WRK。

【热门文章】
【热门文章】