admin 发表于 2024-12-29 22:33:29

内核EATHOOK

eathook.h

```c
#include <ntddk.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;

NTSYSAPI
        NTSTATUS
        NTAPI
        ZwQuerySystemInformation(
        IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
        IN OUT PVOID SystemInformation,
        IN ULONG SystemInformationLength,
        OUT PULONG ReturnLength OPTIONAL
        );

typedef struct _SYSTEM_MODULE_INFORMATION { // Information Class 11
        ULONG Reserved;
        PVOID Base;
        ULONG Size;
        ULONG Flags;
        USHORT Index;
        USHORT Unknown;
        USHORT LoadCount;
        USHORT ModuleNameOffset;
        CHAR ImageName;
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef unsigned short                              WORD;
typedef unsigned char BYTE;
typedef unsigned long DWORD;

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
        WORD   e_magic;                     // Magic number
        WORD   e_cblp;                      // Bytes on last page of file
        WORD   e_cp;                        // Pages in file
        WORD   e_crlc;                      // Relocations
        WORD   e_cparhdr;                   // Size of header in paragraphs
        WORD   e_minalloc;                  // Minimum extra paragraphs needed
        WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        WORD   e_ss;                        // Initial (relative) SS value
        WORD   e_sp;                        // Initial SP value
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // Initial IP value
        WORD   e_cs;                        // Initial (relative) CS value
        WORD   e_lfarlc;                  // File address of relocation table
        WORD   e_ovno;                      // Overlay number
        WORD   e_res;                  // Reserved words
        WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;                   // OEM information; e_oemid specific
        WORD   e_res2;                  // Reserved words
        LONG   e_lfanew;                  // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {
        DWORD   VirtualAddress;
        DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

typedef struct _IMAGE_OPTIONAL_HEADER {
        //
        // Standard fields.
        //

        WORD    Magic;
        BYTE    MajorLinkerVersion;
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;
        DWORD   SizeOfInitializedData;
        DWORD   SizeOfUninitializedData;
        DWORD   AddressOfEntryPoint;
        DWORD   BaseOfCode;
        DWORD   BaseOfData;

        //
        // NT additional fields.
        //

        DWORD   ImageBase;
        DWORD   SectionAlignment;
        DWORD   FileAlignment;
        WORD    MajorOperatingSystemVersion;
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;
        DWORD   SizeOfImage;
        DWORD   SizeOfHeaders;
        DWORD   CheckSum;
        WORD    Subsystem;
        WORD    DllCharacteristics;
        DWORD   SizeOfStackReserve;
        DWORD   SizeOfStackCommit;
        DWORD   SizeOfHeapReserve;
        DWORD   SizeOfHeapCommit;
        DWORD   LoaderFlags;
        DWORD   NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory;
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef IMAGE_OPTIONAL_HEADER32             IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER32            PIMAGE_OPTIONAL_HEADER;

typedef struct _IMAGE_THUNK_DATA32 {
        union {
                DWORD ForwarderString;      // PBYTE
                DWORD Function;             // PDWORD
                DWORD Ordinal;
                DWORD AddressOfData;      // PIMAGE_IMPORT_BY_NAME
        } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32            IMAGE_THUNK_DATA;
typedef PIMAGE_THUNK_DATA32             PIMAGE_THUNK_DATA;

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
                DWORD   Characteristics;            // 0 for terminating null import descriptor
                DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
        };
        DWORD   TimeDateStamp;                  // 0 if not bound,
        // -1 if bound, and real date\time stamp
        //   in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
        // O.W. date/time stamp of DLL bound to (Old BIND)

        DWORD   ForwarderChain;               // -1 if no forwarders
        DWORD   Name;
        DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;


typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;   // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;// RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;


#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_EXPORT          0

typedef unsigned char *PBYTE;

typedef struct _GENERATE_NAME_CONTEXT {
        USHORTChecksum;
        BOOLEAN CheckSumInserted;
        UCHAR   NameLength;
        WCHAR   NameBuffer;
        ULONG   ExtensionLength;
        WCHAR   ExtensionBuffer;
        ULONG   LastIndexValue;
} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT;


typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;
        WORD    NumberOfSections;
        DWORD   TimeDateStamp;
        DWORD   PointerToSymbolTable;
        DWORD   NumberOfSymbols;
        WORD    SizeOfOptionalHeader;
        WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

#define SEC_IMAGE        0x01000000
#define SEC_BASED 0x00200000
typedef struct _SECTION_IMAGE_INFORMATION {
        PVOID                   EntryPoint;
        ULONG                   StackZeroBits;
        ULONG                   StackReserved;
        ULONG                   StackCommit;
        ULONG                   ImageSubsystem;
        WORD                  SubsystemVersionLow;
        WORD                  SubsystemVersionHigh;
        ULONG                   Unknown1;
        ULONG                   ImageCharacteristics;
        ULONG                   ImageMachineType;
        ULONG                   Unknown2;
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;

typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

NTSYSAPI
        NTSTATUS
        NTAPI
        ZwCreateSection(
        OUT PHANDLESectionHandle,
        IN ACCESS_MASKDesiredAccess,
        IN POBJECT_ATTRIBUTESObjectAttributes OPTIONAL,
        IN PLARGE_INTEGERMaximumSize OPTIONAL,
        IN ULONGSectionPageProtection,
        IN ULONGAllocationAttributes,
        IN HANDLEFileHandle OPTIONAL
        );

typedef struct
{
        ULONG        NumberOfModules;
        SYSTEM_MODULE_INFORMATION        smi;
} MODULES, *PMODULES;

NTSYSAPI
        NTSTATUS
        NTAPI
        NtQuerySystemInformation(
        IN ULONG SysInfoClass,
        IN OUT PVOID SystemInformation,
        IN ULONG SystemInformationLength,
        OUT PULONG RetLen
        );

typedef HANDLE (*PSGETCURRENTPROCESSID)();
PSGETCURRENTPROCESSID g_OriginalPsGetCurrentProcessId;

typedef NTSTATUS(*PSSETCREATEPROCESSNOTIFYROUTINE)(
        PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
        BOOLEAN Remove);
PSSETCREATEPROCESSNOTIFYROUTINE g_OriginalPsSetCreateProcessNotifyRoutine;
```

eathook.c

```c
#include "EATHook.h"

HANDLE HookPsGetCurrentProcessId()
{
        DbgPrint("HookPsGetCurrentProcessId called!\n");
        return g_OriginalPsGetCurrentProcessId();
}

NTSTATUS NTAPI HookPsSetCreateProcessNotifyRoutine(
        PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
        BOOLEAN Remove)
{
        DbgPrint("HookPsSetCreateProcessNotifyRoutine called!\n");
        return g_OriginalPsSetCreateProcessNotifyRoutine(NotifyRoutine,Remove);
}

PVOID GetModlueBaseAdress(char* ModlueName)
{
        ULONG size,index;
        PULONG buf;
        NTSTATUS status;
        PSYSTEM_MODULE_INFORMATION module;
        PVOID driverAddress = 0;

        ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);
        if(NULL == (buf = (PULONG)ExAllocatePool(PagedPool, size)))
        {
                DbgPrint("failed alloc memory failed\n");
                return 0;
        }
        status = ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);
        if(!NT_SUCCESS( status ))
        {
                DbgPrint("failedquery\n");
                ExFreePool(buf);
                return 0;
        }
        module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
        for(index = 0; index < *buf; index++)
        {
                if (_stricmp(module.ImageName + module.ModuleNameOffset, ModlueName) == 0)
                {
                        driverAddress = module.Base;
                        DbgPrint("Module found at:%x\n",driverAddress);
                }
        }
        ExFreePool(buf);       
        return driverAddress;
}

//EATHook是安装钩子和卸载钩子,如果        Options == 1表示安装,否则表示卸载
VOID EATHook(IN PCSTR FunName, IN /*unsigned int*/BOOLEAN Options)
{
        HANDLE hMod;
        PUCHAR BaseAddress = NULL;
        IMAGE_DOS_HEADER * dosheader;
        IMAGE_OPTIONAL_HEADER * opthdr;
        PIMAGE_EXPORT_DIRECTORY exports;

        USHORT        index = 0;
        ULONG        addr ,i;


        PUCHAR pFuncName = NULL;
        PULONG pAddressOfFunctions,pAddressOfNames;
        PUSHORT pAddressOfNameOrdinals;

        //用NtQuerySystemInformation取得内核模块ntkrnlpa.exe或ntoskrnl.exe的基址
        NTSTATUS ntStatus;
        PMODULES pModules;
        ULONG NeededSize;

        pModules = (PMODULES)&pModules;
        ntStatus = NtQuerySystemInformation(SystemModuleInformation, pModules, 4, &NeededSize);

        if(ntStatus == STATUS_INFO_LENGTH_MISMATCH)
        {
                pModules = (PMODULES)ExAllocatePool(PagedPool, NeededSize);
                if(!pModules)
                        return STATUS_INSUFFICIENT_RESOURCES;

                ntStatus = NtQuerySystemInformation(SystemModuleInformation, pModules, NeededSize, NULL);

                if(!NT_SUCCESS(ntStatus))
                {
                        ExFreePool(pModules);
                        return ntStatus;
                }
        }
        if(!NT_SUCCESS(ntStatus))
        {
                return ntStatus;
        }

        BaseAddress = (ULONG)pModules->smi.Base;
        //BaseAddress = GetModlueBaseAdress("ntkrnlpa.exe");
        DbgPrint("Map BaseAddress is:%x\n",BaseAddress);
        hMod = BaseAddress;

        dosheader = (IMAGE_DOS_HEADER *)hMod;
        opthdr = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
        exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+ opthdr->DataDirectory.VirtualAddress);

        pAddressOfFunctions = (ULONG*)((BYTE*)hMod+exports->AddressOfFunctions);   
        pAddressOfNames = (ULONG*)((BYTE*)hMod+exports->AddressOfNames);         
        pAddressOfNameOrdinals = (USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals);

        for (i = 0; i < exports->NumberOfNames; i++)
        {
                index = pAddressOfNameOrdinals;
                pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames);
                if (_stricmp( (char*)pFuncName,FunName) == 0)
                {
                        addr = pAddressOfFunctions;
                        break;
                }
        }

        if(Options)       
        {

                _asm
                {
                        CLI                                       
                                MOV        EAX, CR0               
                                AND EAX, NOT 10000H
                                MOV        CR0, EAX               
                }       

                DbgPrint("PsGetCurrentProcessId is:%x\n",(PUCHAR)hMod + pAddressOfFunctions);
                g_OriginalPsGetCurrentProcessId =(PUCHAR)hMod + pAddressOfFunctions;
                DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
                pAddressOfFunctions = ( PCHAR )HookPsGetCurrentProcessId - BaseAddress;

                DbgPrint("PsSetCreateProcessNotifyRoutine is:%x\n",(PUCHAR)hMod + pAddressOfFunctions);
                g_OriginalPsSetCreateProcessNotifyRoutine =(PUCHAR)hMod + pAddressOfFunctions;
                DbgPrint("g_OriginalPsSetCreateProcessNotifyRoutine is:%x\n",g_OriginalPsSetCreateProcessNotifyRoutine);
                pAddressOfFunctions = ( PCHAR )HookPsSetCreateProcessNotifyRoutine - BaseAddress;

                _asm
                {
                        MOV        EAX, CR0               
                                OR        EAX, 10000H                       
                                MOV        CR0, EAX                       
                                STI                                       
                }       
        }
        else
        {
                _asm
                {
                        CLI                                       
                                MOV        EAX, CR0               
                                AND EAX, NOT 10000H
                                MOV        CR0, EAX               
                }       

                pAddressOfFunctions = ( PCHAR )g_OriginalPsGetCurrentProcessId - BaseAddress;
                pAddressOfFunctions = ( PCHAR )g_OriginalPsSetCreateProcessNotifyRoutine - BaseAddress;


                _asm
                {
                        MOV        EAX, CR0               
                                OR        EAX, 10000H                       
                                MOV        CR0, EAX                       
                                STI                                       
                }       
        }
}



VOID Unload(PDRIVER_OBJECT DriverObject)
{
        EATHook("PsGetCurrentProcessId",FALSE);
        EATHook("PsSetCreateProcessNotifyRoutine",FALSE);

        DbgPrint("Unload Callled\n");
}


NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str)
{
        EATHook("PsGetCurrentProcessId",TRUE);
        EATHook("PsSetCreateProcessNotifyRoutine",TRUE);

        DriverObject->DriverUnload = Unload;
        return STATUS_SUCCESS;
}


```

页: [1]
查看完整版本: 内核EATHOOK