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;
}