zoukankan      html  css  js  c++  java
  • 《Windows核心编程》第3章——handle复制相关实验

    •  先写一个程序,用来查看进程的内核对象,这样我们就能比较子进程是否继承了父进程的某个句柄:
    #include <windows.h>
    #include <stdio.h>
    
    #define NT_SUCCESS(x) ((x) >= 0)
    #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
    
    #define SystemHandleInformation 16
    #define ObjectBasicInformation 0
    #define ObjectNameInformation 1
    #define ObjectTypeInformation 2
    
    typedef NTSTATUS(NTAPI *_NtQuerySystemInformation)(
        ULONG SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength
        );
    
    typedef NTSTATUS(NTAPI *_NtDuplicateObject)(
        HANDLE SourceProcessHandle,
        HANDLE SourceHandle,
        HANDLE TargetProcessHandle,
        PHANDLE TargetHandle,
        ACCESS_MASK DesiredAccess,
        ULONG Attributes,
        ULONG Options
        );
    
    typedef NTSTATUS(NTAPI *_NtQueryObject)(
        HANDLE ObjectHandle,
        ULONG ObjectInformationClass,
        PVOID ObjectInformation,
        ULONG ObjectInformationLength,
        PULONG ReturnLength
        );
    
    typedef struct _UNICODE_STRING
    {
        USHORT Length;
        USHORT MaximumLength;
        PWSTR Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    typedef struct _SYSTEM_HANDLE
    {
        ULONG ProcessId;
        BYTE ObjectTypeNumber;
        BYTE Flags;
        USHORT Handle;
        PVOID Object;
        ACCESS_MASK GrantedAccess;
    } SYSTEM_HANDLE, *PSYSTEM_HANDLE;
    
    typedef struct _SYSTEM_HANDLE_INFORMATION
    {
        ULONG HandleCount;
        SYSTEM_HANDLE Handles[1];
    } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
    
    typedef enum _POOL_TYPE
    {
        NonPagedPool,
        PagedPool,
        NonPagedPoolMustSucceed,
        DontUseThisType,
        NonPagedPoolCacheAligned,
        PagedPoolCacheAligned,
        NonPagedPoolCacheAlignedMustS
    } POOL_TYPE, *PPOOL_TYPE;
    
    typedef struct _OBJECT_TYPE_INFORMATION
    {
        UNICODE_STRING Name;
        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 ValidAccess;
        BOOLEAN SecurityRequired;
        BOOLEAN MaintainHandleCount;
        USHORT MaintainTypeList;
        POOL_TYPE PoolType;
        ULONG PagedPoolUsage;
        ULONG NonPagedPoolUsage;
    } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
    
    PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
    {
        return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
    }
    
    int main(int argc, WCHAR *argv[])
    {
        NTSTATUS status;
        ULONG pid;
        HANDLE processHandle;
        ULONG handleInfoSize = 0x10000;
        PSYSTEM_HANDLE_INFORMATION handleInfo;
        HANDLE dupHandle = NULL;
        ULONG returnLength;
        int nCount = 0;
        pid = 13104;//Input which process do you want to query.
    
        _NtQuerySystemInformation NtQuerySystemInformation =
            (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
        if (NULL == NtQuerySystemInformation){
            printf("Get address of NtQuerySystemInformation failed!
    ");
            return FALSE;
        }
    
        _NtDuplicateObject NtDuplicateObject =
            (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
        if (NULL == NtDuplicateObject){
            printf("Get address of NtDuplicateObject failed!
    ");
            return FALSE;
        }
    
        _NtQueryObject NtQueryObject =
            (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
        if (NULL == NtQueryObject){
            printf("Get address of NtQueryObject failed!
    ");
            return FALSE;
        }
    
        if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid))){
            printf("Open process failed!
    ");
            return FALSE;
        }
    
        handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
        while ((status = NtQuerySystemInformation(//Query system handle information, if return STATUS_INFO_LENGTH_MISMATCH, you should realloc space.
            SystemHandleInformation,
            handleInfo,
            handleInfoSize,
            NULL
            )) == STATUS_INFO_LENGTH_MISMATCH){
            handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);//assign new value to handleInfoSize
    
        }
        if (!NT_SUCCESS(status))
        {
            return FALSE;
        }
    
        for (int i = 0; i < handleInfo->HandleCount; i++)//reverse all handles
        {
            SYSTEM_HANDLE handle = handleInfo->Handles[i];
            POBJECT_TYPE_INFORMATION objectTypeInfo;
            PVOID objectNameInfo;
            UNICODE_STRING objectName;
    
            if (handle.ProcessId != pid)
                continue;
    
            if (!NT_SUCCESS(status = NtDuplicateObject(//duplicate handle information into self.
                processHandle,
                (HANDLE)handle.Handle,
                GetCurrentProcess(),
                &dupHandle,
                0,
                0,
                0
                )))
            {
                continue;
            }
    
            ////////////////////////////////////////////////////////////////////////////////////
            //you can query objectNameInfo directly.
            objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
            if (!NT_SUCCESS(status = NtQueryObject(//Get the object according handle.
                dupHandle,
                ObjectTypeInformation,
                objectTypeInfo,
                0x1000,
                NULL
                )))
            {
                printf("Query [%#x] Error:%x!
    ", handle.Handle, status);
                CloseHandle(dupHandle);
                continue;
            }
    
            if (handle.GrantedAccess == 0x0012019f)
            {
                /* We have the type, so display that. */
                printf(
                    "[%#x] %.*S: (did not get name)
    ",
                    handle.Handle,
                    objectTypeInfo->Name.Length / 2,
                    objectTypeInfo->Name.Buffer
                    );
                free(objectTypeInfo);
                CloseHandle(dupHandle);
                continue;
            }
    
            objectNameInfo = malloc(0x1000);
            if (!NT_SUCCESS(NtQueryObject(
                dupHandle,
                ObjectNameInformation,
                objectNameInfo,
                0x1000,
                &returnLength
                ))){
                objectNameInfo = realloc(objectNameInfo, returnLength);
                if (!NT_SUCCESS(NtQueryObject(
                    dupHandle,
                    ObjectNameInformation,
                    objectNameInfo,
                    returnLength,
                    NULL
                    )))
                {
                    /* We have the type name, so just display that. */
                    printf(
                        "[%#x] %.*S: (could not get name)
    ",
                        handle.Handle,
                        objectTypeInfo->Name.Length / 2,
                        objectTypeInfo->Name.Buffer
                        );
                    free(objectTypeInfo);
                    free(objectNameInfo);
                    CloseHandle(dupHandle);
                    continue;
                }
            }
            objectName = *(PUNICODE_STRING)objectNameInfo;
    
            if (objectName.Length)
            {
                /* The object has a name. */
                printf(
                    "[%#x] %.*S: %.*S
    ",
                    handle.Handle,
                    objectTypeInfo->Name.Length / 2,
                    objectTypeInfo->Name.Buffer,
                    objectName.Length / 2,
                    objectName.Buffer
                    );
            }
            else
            {
                /* Print something else. */
                printf(
                    "[%#x] %.*S: (unnamed)
    ",
                    handle.Handle,
                    objectTypeInfo->Name.Length / 2,
                    objectTypeInfo->Name.Buffer
                    );
            }
    
            nCount++;
            free(objectTypeInfo);
            free(objectNameInfo);
            CloseHandle(dupHandle);
        }
        printf("Handle Count:%d
    ", nCount);
    
        free(handleInfo);
        CloseHandle(processHandle);
        getchar();
    }
    • 然后父进程就随便写一个,主要是为了创建三个命名内核对象,然后让子进程继承其中的两个:
    #include <iostream>
    #include <windows.h>
    void main(){
        SECURITY_ATTRIBUTES sa;
        sa.nLength = sizeof(sa);
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = TRUE;//if the handle can be inherited.
    
        HANDLE hMuxtex1 = CreateMutex(&sa, FALSE, "TestHandle1");
        HANDLE hMuxtex2 = CreateMutex(NULL, FALSE, "TestHandle2");
        HANDLE hMuxtex3 = CreateMutex(&sa, FALSE, "TestHandle3");
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        CreateProcess(NULL, "E:\Coding\Cpp\test\Windows_Core\P96_3\Debug\P96_3.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
        while (TRUE);
    }
    • 验证结果

    父进程创建的三个互斥量句柄:

    然后再去查看子进程:

    果然之继承了其中的1和3句柄。

  • 相关阅读:
    Vue优化首页加载速度 CDN引入
    vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践
    node.js
    keep-alive前进没有刷新
    移动端ios和安卓input问题
    前端技术原理
    Vue给子组件传值为空
    使用vue开发输入型组件更好的一种解决方式(子组件向父组件传值,基于2.2.0)
    Vue路由参数设置可有可无
    Vue组件的三种调用方式
  • 原文地址:https://www.cnblogs.com/predator-wang/p/8537319.html
Copyright © 2011-2022 走看看