登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 156|回复: 0

内核EATHOOK

[复制链接]

91

主题

9

回帖

494

积分

管理员

积分
494
发表于 2024-12-29 22:33:29 | 显示全部楼层 |阅读模式

eathook.h

#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[2];
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT Unknown;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    CHAR ImageName[256];
} 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[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // 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_NUMBEROF_DIRECTORY_ENTRIES];
} 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 {
    USHORT  Checksum;
    BOOLEAN CheckSumInserted;
    UCHAR   NameLength;
    WCHAR   NameBuffer[8];
    ULONG   ExtensionLength;
    WCHAR   ExtensionBuffer[4];
    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[3];
} 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 PHANDLE  SectionHandle,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
    IN PLARGE_INTEGER  MaximumSize OPTIONAL,
    IN ULONG  SectionPageProtection,
    IN ULONG  AllocationAttributes,
    IN HANDLE  FileHandle 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

#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("failed  query\n");
        ExFreePool(buf);
        return 0;
    }
    module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
    for(index = 0; index < *buf; index++)
    {
        if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0)  
        {
            driverAddress = module[index].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[IMAGE_DIRECTORY_ENTRY_EXPORT].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[i];
        pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames[i]);
        if (_stricmp( (char*)pFuncName,FunName) == 0)
        {
            addr = pAddressOfFunctions[index];
            break;
        }
    }

    if(Options) 
    {

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

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

        DbgPrint("PsSetCreateProcessNotifyRoutine is:%x\n",(PUCHAR)hMod + pAddressOfFunctions[index]);
        g_OriginalPsSetCreateProcessNotifyRoutine =  (PUCHAR)hMod + pAddressOfFunctions[index];
        DbgPrint("g_OriginalPsSetCreateProcessNotifyRoutine is:%x\n",g_OriginalPsSetCreateProcessNotifyRoutine);
        pAddressOfFunctions[index] = ( 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[index] = ( PCHAR )g_OriginalPsGetCurrentProcessId - BaseAddress;
        pAddressOfFunctions[index] = ( 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;
}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-2-5 20:01 , Processed in 0.068570 second(s), 26 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表