• 内核空间与内核模块


    一、内核空间

    高2G内存里的内容都是一样的,低2G内存都是各进程的

     二、内核模块

    每个驱动程序都是一个模块,称为内核模块,都可以加载到内核中,都遵循PE结构,但本质上讲,任意一个.sys文件与内核文件没有区别

    1、DRIVER_OBJECT结构体

    每个内核模块都有一个对应的结构体,来描述这个模块在内核中:位置、大小、名称等等

    0: kd> dt _DRIVER_OBJECT
    ntdll!_DRIVER_OBJECT
       +0x000 Type             : Int2B
       +0x002 Size             : Int2B
       +0x004 DeviceObject     : Ptr32 _DEVICE_OBJECT
       +0x008 Flags            : Uint4B
       +0x00c DriverStart      : Ptr32 Void  //驱动的位置
       +0x010 DriverSize       : Uint4B    //驱动大小
       +0x014 DriverSection    : Ptr32 Void  
       +0x018 DriverExtension  : Ptr32 _DRIVER_EXTENSION
       +0x01c DriverName       : _UNICODE_STRING  //驱动名
       +0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
       +0x028 FastIoDispatch   : Ptr32 _FAST_IO_DISPATCH
       +0x02c DriverInit       : Ptr32     long 
       +0x030 DriverStartIo    : Ptr32     void 
       +0x034 DriverUnload     : Ptr32     void 
       +0x038 MajorFunction    : [28] Ptr32     long 

    咱们可以实验一下打印pDriver的地址在查看其结构,测试代码如下

    #include<ntddk.h>
    
    VOID DriverUnload(PDRIVER_OBJECT driver)
    {
        DbgPrint("驱动停止运行.
    ");
    }
    
    extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
    {
        DbgPrint("My Driver");
        DbgPrint("Driver addr:%x", pDriver);
    
        pDriver->DriverUnload = DriverUnload;
    
        return STATUS_SUCCESS;
    }

    运行驱动后

    0: kd> dt _DRIVER_OBJECT 89d1c978
    ntdll!_DRIVER_OBJECT
       +0x000 Type             : 0n4
       +0x002 Size             : 0n168
       +0x004 DeviceObject     : (null) 
       +0x008 Flags            : 0x12
       +0x00c DriverStart      : 0xf7817000 Void
       +0x010 DriverSize       : 0x6000
       +0x014 DriverSection    : 0x8996d780 Void
       +0x018 DriverExtension  : 0x89d1ca20 _DRIVER_EXTENSION
       +0x01c DriverName       : _UNICODE_STRING "DriverKMDFDriver1"
       +0x024 HardwareDatabase : 0x8069c210 _UNICODE_STRING "REGISTRYMACHINEHARDWAREDESCRIPTIONSYSTEM"
       +0x028 FastIoDispatch   : (null) 
       +0x02c DriverInit       : 0xf781b000     long SYMSRV:  BYINDEX: 0x5

    其中DriverSection是一个指针,指向下一个驱动模块的指针,其相对应的结构体是

    _LDR_DATA_TABLE_ENTRY

    0: kd> dt _LDR_DATA_TABLE_ENTRY
    ntdll!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY
       +0x008 InMemoryOrderLinks : _LIST_ENTRY
       +0x010 InInitializationOrderLinks : _LIST_ENTRY
       +0x018 DllBase          : Ptr32 Void
       +0x01c EntryPoint       : Ptr32 Void
       +0x020 SizeOfImage      : Uint4B
       +0x024 FullDllName      : _UNICODE_STRING
       +0x02c BaseDllName      : _UNICODE_STRING
       +0x034 Flags            : Uint4B
       +0x038 LoadCount        : Uint2B
       +0x03a TlsIndex         : Uint2B
       +0x03c HashLinks        : _LIST_ENTRY
       +0x03c SectionPointer   : Ptr32 Void
       +0x040 CheckSum         : Uint4B
       +0x044 TimeDateStamp    : Uint4B
       +0x044 LoadedImports    : Ptr32 Void
       +0x048 EntryPointActivationContext : Ptr32 Void
       +0x04c PatchInformation : Ptr32 Void

    我们查看上一个样例的试试

    0: kd> dt _LDR_DATA_TABLE_ENTRY 8996d780
    ntdll!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x805644c0 - 0x89c57ae0 ]
       +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0xffffffff - 0xffffffff ]
       +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x630069 - 0x0 ]
       +0x018 DllBase          : 0xf7817000 Void
       +0x01c EntryPoint       : 0xf781b000 Void
       +0x020 SizeOfImage      : 0x6000
       +0x024 FullDllName      : _UNICODE_STRING "??C:Documents and SettingsAdministrator桌面KMDFDriver1.sys"
       +0x02c BaseDllName      : _UNICODE_STRING "KMDFDriver1.sys"
       +0x034 Flags            : 0x9104000
       +0x038 LoadCount        : 1
       +0x03a TlsIndex         : 0x49
       +0x03c HashLinks        : _LIST_ENTRY [ 0xffffffff - 0xc7af ]
       +0x03c SectionPointer   : 0xffffffff Void
       +0x040 CheckSum         : 0xc7af
       +0x044 TimeDateStamp    : 0xfffffffe
       +0x044 LoadedImports    : 0xfffffffe Void
       +0x048 EntryPointActivationContext : (null) 
       +0x04c PatchInformation : 0x004d004b Void

    指向的是我们运行的驱动程序

    DLLBase成员代表我们的内核模块从哪里开始

    InLoadOrderLinks可以遍历下一个内核模块

    也就是说只要找到这个成员就可以遍历所有的内核模块

     三、内核模块链表DriverSection

    既然我们DriverSection可以遍历链表,那么我们来尝试一下,代码与实验结果如下

    #include<ntddk.h>
    
    typedef struct
    {
        LIST_ENTRY InLoadOrderLinks;
        LIST_ENTRY InMemoryOrderLinks;
        LIST_ENTRY InInitializationOrderLinks;
        PVOID DllBase;
        PVOID EntryPoint;
        UINT32 SizeOfImage;
        UNICODE_STRING FullDllName;
        UNICODE_STRING BaseDllName;
        UINT32 Flags;
        UINT16 LoadCount;
        UINT16 TlsIndex;
        LIST_ENTRY HashLinks;
        PVOID SectionPointer;
        UINT32 CheckSum;
        UINT32 TimeDateStamp;
        PVOID LoadedImports;
        PVOID EntryPointActivationContext;
        PVOID PatchInformation;
    
    }LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
    
    VOID DriverUnload(PDRIVER_OBJECT driver)
    {
        DbgPrint("驱动停止运行.
    ");
    }
    
    extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
    {
        DbgPrint("My Driver");
        DbgPrint("Driver addr:%x", pDriver);
        pDriver->DriverUnload = DriverUnload;
    
        PLDR_DATA_TABLE_ENTRY pdte = (PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
        PLDR_DATA_TABLE_ENTRY head = pdte;
        do
        {
            PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pdte, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
            DbgPrint("DllBase: %p, SizeOfImage: %08X %wZ
    ", pdte->DllBase, pdte->SizeOfImage, &(pdte->FullDllName));
            pdte = (PLDR_DATA_TABLE_ENTRY)pdte->InLoadOrderLinks.Flink;
        } while (pdte != head);
    
        return STATUS_SUCCESS;
    }

     通过特征码查找函数PspTerminateProcess

    #include<ntifs.h>
    #include<ntddk.h>
    
    typedef struct
    {
        LIST_ENTRY InLoadOrderLinks;
        LIST_ENTRY InMemoryOrderLinks;
        LIST_ENTRY InInitializationOrderLinks;
        PVOID DllBase;
        PVOID EntryPoint;
        UINT32 SizeOfImage;
        UNICODE_STRING FullDllName;
        UNICODE_STRING BaseDllName;
        UINT32 Flags;
        UINT16 LoadCount;
        UINT16 TlsIndex;
        LIST_ENTRY HashLinks;
        PVOID SectionPointer;
        UINT32 CheckSum;
        UINT32 TimeDateStamp;
        PVOID LoadedImports;
        PVOID EntryPointActivationContext;
        PVOID PatchInformation;
    
    }LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
    
    typedef NTSTATUS(*_PspTerminateProcess)(PEPROCESS pEprocess, NTSTATUS ExitCode);
    
    
    VOID DriverUnLoad(PDRIVER_OBJECT driver)
    {
        DbgPrint("Driver already shut off");
    }
    
    VOID FindDriver(PDRIVER_OBJECT pDriver,PVOID* KernelBase,PUINT32 uKernelImageSize)
    {
        PLDR_DATA_TABLE_ENTRY pldte=(PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
        PLDR_DATA_TABLE_ENTRY head = pldte;
        UNICODE_STRING usKernelBaseDllName;
        
        RtlInitUnicodeString(&usKernelBaseDllName, L"ntoskrnl.exe");
    
        do
        {
            if (RtlCompareUnicodeString(&pldte->BaseDllName, &usKernelBaseDllName, TRUE) == 0)
            {
                *KernelBase=pldte->DllBase;
                *uKernelImageSize = pldte->SizeOfImage;
                return;
            }
            pldte=(PLDR_DATA_TABLE_ENTRY)pldte->InLoadOrderLinks.Flink;
        } while (head != pldte);
        return;
    }
    
    PVOID MemorySearch(PVOID KernelBase, UINT32 uKernelImageSize, PVOID ByteCode,UINT32 ByteLength)
    {
        PVOID cur=KernelBase;
        while ((UINT32)cur!=(UINT32)KernelBase+uKernelImageSize)
        {
            if (RtlCompareMemory(cur, ByteCode, ByteLength) == ByteLength)
            {
                __asm int 3;
                return (PVOID)(((UINT32)cur) - 0x6);
            }
            cur = (PVOID)((UINT32)cur+1);
        }
    }
    
    extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING reg_path)
    {
        pDriver->DriverUnload = DriverUnLoad;
    
        PVOID pKernelBase=NULL;
        UINT32 uKernelImageSize;
        
        UINT32 ByteCode[] = { 0x0124a164, 0x758b0000, 0x44703b08, 0x0db80775,
            0xebc00000, 0xbe8d575a, 0x00000248, 0x200147f6,
            0x868d1274, 0x00000174
        };
    
        _PspTerminateProcess PspTerminateProcess;
    
    
        FindDriver(pDriver, &pKernelBase, &uKernelImageSize);
        PspTerminateProcess=(_PspTerminateProcess)MemorySearch(pKernelBase, uKernelImageSize, ByteCode, sizeof(ByteCode));
        DbgPrint("PspTerminateProcess Addr:%p", PspTerminateProcess);
    
        PEPROCESS pE;
        PsLookupProcessByProcessId((HANDLE)1244, &pE);
        PspTerminateProcess(pE, 0);
        DbgPrint("记事本关闭了");
        return STATUS_SUCCESS;
    }

    非常感谢hambaga师傅,我的博客都是学着他写的,因为他写的很有调理,所以非常感谢

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/13948331.html
Copyright © 2020-2023  润新知