MalwareSourceCode/Win32/Proof of Concepts/CheckKernelEATHook/CheckKernelHookDrv/CheckKernelHook/KernelHookCheck.c
vxunderground 900263ea6f updates and moves
n/a
2022-04-11 20:00:13 -05:00

695 lines
27 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "KernelHookCheck.h"
#include "libdasm.h"
#include "Common.h"
#include "Reload.h"
ULONG IntHookCount; //记录Hook数量
extern DWORD OriginalKiServiceTable;
extern PSERVICE_DESCRIPTOR_TABLE OriginalServiceDescriptorTable;
extern ULONG_PTR SystemKernelModuleBase;
extern ULONG_PTR SystemKernelModuleSize;
extern ULONG_PTR ImageModuleBase;
BOOLEAN KernelHookCheck(PINLINEHOOKINFO InlineHookInfo)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_EXPORT_DIRECTORY ExportTable;
ULONG* FunctionAddresses;
ULONG* FunctionNames;
USHORT* FunctionIndexs;
ULONG ulIndex;
ULONG i;
CHAR* szFunctionName;
SIZE_T ViewSize=0;
ULONG_PTR ulFunctionAddress;
BOOL bIsZwFunction = FALSE;
ULONG ulOldAddress;
ULONG ulReloadAddress;
PUCHAR ulTemp;
__try{
NtHeader = RtlImageNtHeader((PVOID)ImageModuleBase);
if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){
ExportTable =(IMAGE_EXPORT_DIRECTORY*)((ULONG_PTR)ImageModuleBase + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
FunctionAddresses = (ULONG*)((ULONG_PTR)ImageModuleBase + ExportTable->AddressOfFunctions);
FunctionNames = (ULONG*)((ULONG_PTR)ImageModuleBase + ExportTable->AddressOfNames);
FunctionIndexs = (USHORT*)((ULONG_PTR)ImageModuleBase + ExportTable->AddressOfNameOrdinals);
for(i = 0; i < ExportTable->NumberOfNames; i++)
{
szFunctionName = (LPSTR)((ULONG_PTR)ImageModuleBase + FunctionNames[i]);
ulIndex = FunctionIndexs[i];
ulFunctionAddress = (ULONG_PTR)((ULONG_PTR)ImageModuleBase + FunctionAddresses[ulIndex]);
// ulIndex=*(ULONG*)(ulFunctionAddress+1); //32 bit 1 64 bit 4 //服务号
//对于非Zw系列函数 偏移到系统的该函数地址处
ulReloadAddress = ulFunctionAddress;
ulOldAddress = ulReloadAddress - (ULONG)ImageModuleBase + SystemKernelModuleBase;
if (!ulOldAddress ||
!MmIsAddressValid((PVOID)ulOldAddress) ||
!ulReloadAddress ||
!MmIsAddressValid((PVOID)ulReloadAddress))
{
continue;
}
bIsZwFunction = FALSE;
//检查下一层第一个call的函数的hook
if (*szFunctionName == 'Z' &&
*(szFunctionName+1) == 'w')
{
bIsZwFunction = TRUE;
ulIndex = *((WORD*)(ulFunctionAddress + 1)); //得到服务号
if (ulIndex > 0 &&
ulIndex <= OriginalServiceDescriptorTable->TableSize)
{
//对于Zw系列函数 获得系统Ntos中 对应的Nt函数的地址
ulReloadAddress = OriginalServiceDescriptorTable->ServiceTable[ulIndex];
ulOldAddress = ulReloadAddress - (ULONG)ImageModuleBase + SystemKernelModuleBase;
}
}
if (bIsZwFunction)
{
//如果 bIsZwFunction == TRUE 重新效验一下地址的有效性
if (!ulOldAddress ||
!MmIsAddressValid((PVOID)ulOldAddress) ||
!ulReloadAddress ||
!MmIsAddressValid((PVOID)ulReloadAddress))
{
continue;
}
}
else //下一层函数只扫描非Zw开头的并且只扫描未导出函数
{
GetNextFunctionAddress(ImageModuleBase,ulOldAddress,szFunctionName,InlineHookInfo);
}
ulTemp = NULL;
//对于Zw中的Nt函数 、 导出函数
//判断是否Ntos 导出表Hook
//ulOldAddress 是根据重载地址 - Base + KernelBase 真正函数的地址
ulTemp = (PUCHAR)GetEatHook(ulOldAddress,i,SystemKernelModuleBase,SystemKernelModuleSize); //比较EAT Hook
if(ulTemp)
{//导出表Hook了
FillInlineHookInfo(ulTemp,InlineHookInfo,szFunctionName,ulOldAddress,1); //EAT Hook 1
}
//是否是InlineHook
CheckFuncByOpcode((PVOID)ulReloadAddress,InlineHookInfo,szFunctionName,(PVOID)ulOldAddress);
}
}
}__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return STATUS_SUCCESS;
}
VOID FillInlineHookInfo(PUCHAR ulTemp,PINLINEHOOKINFO InlineHookInfo,CHAR* szFunctionName,ULONG ulOldAddress,ULONG HookType)
{
ULONG ulHookModuleBase;
ULONG ulHookModuleSize;
char lpszHookModuleImage[256];
ULONG IntHookCount = InlineHookInfo->ulCount;
memset(lpszHookModuleImage,0,sizeof(lpszHookModuleImage));
if (!IsAddressInSystem(
(ULONG)ulTemp,
&ulHookModuleBase,
&ulHookModuleSize,
lpszHookModuleImage))
{
memset(lpszHookModuleImage,0,sizeof(lpszHookModuleImage));
strcat(lpszHookModuleImage,"Unknown4");
ulHookModuleBase = 0;
ulHookModuleSize = 0;
}
InlineHookInfo->InlineHook[IntHookCount].ulMemoryHookBase = (ULONG)ulTemp;
memset(InlineHookInfo->InlineHook[IntHookCount].lpszFunction,0,sizeof(InlineHookInfo->InlineHook[IntHookCount].lpszFunction));
memset(InlineHookInfo->InlineHook[IntHookCount].lpszHookModuleImage,0,sizeof(InlineHookInfo->InlineHook[IntHookCount].lpszHookModuleImage));
memcpy(InlineHookInfo->InlineHook[IntHookCount].lpszFunction,szFunctionName,strlen(szFunctionName));
memcpy(InlineHookInfo->InlineHook[IntHookCount].lpszHookModuleImage,lpszHookModuleImage,strlen(lpszHookModuleImage));
InlineHookInfo->InlineHook[IntHookCount].ulMemoryFunctionBase = (ULONG)ulOldAddress;
InlineHookInfo->InlineHook[IntHookCount].ulHookModuleBase = ulHookModuleBase;
InlineHookInfo->InlineHook[IntHookCount].ulHookModuleSize = ulHookModuleSize;
InlineHookInfo->InlineHook[IntHookCount].ulHookType = HookType; //eat hook 1 Inline Hook 0
IntHookCount++;
InlineHookInfo->ulCount++;
}
VOID CheckFuncByOpcode(PVOID ulReloadAddress,PINLINEHOOKINFO InlineHookInfo,CHAR* szFunctionName,PVOID ulOldAddress)
{
INSTRUCTION Inst;
INSTRUCTION Instb;
ULONG ulHookFunctionAddress;
size_t ulCodeSize;
PUCHAR p;
PUCHAR ulTemp;
int Flagss;
if (GetFunctionCodeSize(ulOldAddress) == GetFunctionCodeSize(ulReloadAddress) &&
memcmp(ulReloadAddress,ulOldAddress,GetFunctionCodeSize(ulOldAddress)) != 0)
{//被Hook了
//开始扫描hooksss
ulCodeSize = GetFunctionCodeSize(ulOldAddress);
for (p = (PUCHAR)ulOldAddress ;(ULONG)p < (ULONG)ulOldAddress+ulCodeSize; p++)
{
//折半扫描,如果前面一半一样,则开始扫描下一半
if (memcmp(ulReloadAddress,ulOldAddress,ulCodeSize/2) == 0)
{
ulCodeSize = ulCodeSize + ulCodeSize/2;
continue;
}
if (*p == 0xcc ||
*p == 0xc2)
{
break;
}
ulHookFunctionAddress = (*(PULONG)(p + 1) + (ULONG)p + 5); //得到hook的地址
if (!MmIsAddressValid((PVOID)ulHookFunctionAddress))
{
continue;
}
ulTemp = NULL;
get_instruction(&Inst,p,MODE_32);
switch (Inst.type)
{
case INSTRUCTION_TYPE_JMP:
if(Inst.opcode==0xFF&&Inst.modrm==0x25)
{
//DIRECT_JMP
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0xEB)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE9)
{
//RELATIVE_JMP;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_CALL:
if(Inst.opcode==0xFF&&Inst.modrm==0x15)
{
//DIRECT_CALL
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0x9A)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE8)
{
//RELATIVE_CALL;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_PUSH:
if(!RMmIsAddressValid((PVOID)(p)))
{
break;
}
get_instruction(&Instb,(BYTE*)(p),MODE_32);
if(Instb.type == INSTRUCTION_TYPE_RET)
{
//StartAddress+len-inst.length-instb.length;
ulTemp = (PUCHAR)Instb.op1.displacement;
}
break;
}
if (ulTemp &&
RMmIsAddressValid(ulTemp) &&
RMmIsAddressValid(p)) //hook的地址也要有效才可以哦
{
if ((ULONG)ulTemp > SystemKernelModuleBase &&
(ULONG)ulTemp < SystemKernelModuleBase+SystemKernelModuleSize) //太近的跳也不是
{
goto Next;
}
//ulTemp也不能小于 SystemKernelModuleBase
if ((ULONG)ulTemp < SystemKernelModuleBase)
{
goto Next;
}
//KdPrint(("%08x-%08x-%08x",p,ulTemp,(SystemKernelModuleBase + SystemKernelModuleSize + 0xfffffff)));
if (*(ULONG *)ulTemp == 0x00000000 ||
*(ULONG *)ulTemp == 0x00000005 ||
*(ULONG *)ulTemp == 0xc0000012)
{
goto Next;
}
Flagss = 0;
__asm{
mov esi,ulTemp
mov ax,word ptr [esi]
cmp ax,0x0000
jz Cont//是add byte ptr [eax],al
//结束
mov Flagss,1
Cont:
}
if (Flagss != 1)
goto Next;
ulTemp = ulTemp+0x5;
//简单处理一下二级跳
if (*ulTemp == 0xe9 ||
*ulTemp == 0xe8)
{
ulTemp = (PUCHAR)(*(PULONG)(ulTemp+1)+(ULONG)(ulTemp+5));
}
FillInlineHookInfo(ulTemp,InlineHookInfo,szFunctionName,(ULONG)p,0); //Inline Hook
Next:
_asm{nop}
}
}
}
}
//获取导出函数下一级0xe8 call函数的inlinehookcheck
ULONG GetNextFunctionAddress(ULONG ulNtDllModuleBase,ULONG ulOldAddress,char *functionName,PINLINEHOOKINFO InlineHookInfo)
{
ULONG ulCodeSize;
ULONG ulNextFunCodeSize;
ULONG ulNextFunReloadCodeSize;
PUCHAR i;
PUCHAR ulNextFunctionAddress = NULL;
PUCHAR ulReloadNextFunctionAddress = NULL;
BOOL bRetOK = FALSE;
PUCHAR ulTemp;
ULONG ulHookFunctionAddress;
PUCHAR p;
INSTRUCTION Inst;
INSTRUCTION Instb;
char lpszHookModuleImage[256];
ULONG ulHookModuleBase;
ULONG ulHookModuleSize;
int Flagss;
if (!MmIsAddressValid((PVOID)ulOldAddress))
{
return bRetOK;
}
__try
{
ulCodeSize = GetFunctionCodeSize((PVOID)ulOldAddress);
for (i=(PUCHAR)ulOldAddress;i < i+ulCodeSize;i++)
{
//扫描二次跳转
if (*i == 0xe8)
{
ulNextFunctionAddress = (PUCHAR)(*(PULONG)(i+1)+(ULONG)(i+5));
if (MmIsAddressValid((PVOID)ulNextFunctionAddress))
{
//判断一下是否是导出函数
if (IsFunctionInExportTable(ulNtDllModuleBase,(ULONG)ulNextFunctionAddress))
{
return 0;
}
//做hook 扫描
ulReloadNextFunctionAddress = ulNextFunctionAddress - SystemKernelModuleBase + ImageModuleBase;
if (MmIsAddressValid(ulReloadNextFunctionAddress) &&
MmIsAddressValid(ulNextFunctionAddress))
{
ulNextFunCodeSize = GetFunctionCodeSize(ulNextFunctionAddress);
ulNextFunReloadCodeSize = GetFunctionCodeSize(ulReloadNextFunctionAddress);
if (ulNextFunCodeSize == ulNextFunReloadCodeSize &&
memcmp(ulReloadNextFunctionAddress,ulNextFunctionAddress,ulNextFunCodeSize) != 0)
{
//被hook了
for (p = (PUCHAR)ulNextFunctionAddress ;(ULONG)p < (ULONG)ulNextFunctionAddress+ulNextFunCodeSize; p++)
{
//折半扫描,如果前面一半一样,则开始扫描下一半
if (memcmp(ulReloadNextFunctionAddress, ulNextFunctionAddress,ulNextFunCodeSize/2) == 0)
{
ulNextFunCodeSize = ulNextFunCodeSize + ulNextFunCodeSize/2;
continue;
}
//是否结束?
if (*p == 0xcc ||
*p == 0xc2)
{
break;
}
ulHookFunctionAddress = (*(PULONG)(p + 1) + (ULONG)p + 5); //得到地址
if (!RMmIsAddressValid((PVOID)ulHookFunctionAddress))
{
continue;
}
ulTemp = NULL;
get_instruction(&Inst,p,MODE_32);
switch (Inst.type)
{
case INSTRUCTION_TYPE_JMP:
if(Inst.opcode==0xFF&&Inst.modrm==0x25)
{
//DIRECT_JMP
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0xEB)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE9)
{
//RELATIVE_JMP;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_CALL:
if(Inst.opcode==0xFF&&Inst.modrm==0x15)
{
//DIRECT_CALL
ulTemp = (PUCHAR)Inst.op1.displacement;
}
else if (Inst.opcode==0x9A)
{
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
else if(Inst.opcode==0xE8)
{
//RELATIVE_CALL;
ulTemp = (PUCHAR)(p+Inst.op1.immediate);
}
break;
case INSTRUCTION_TYPE_PUSH:
if(!RMmIsAddressValid((PVOID)(p)))
{
break;
}
get_instruction(&Instb,(BYTE*)(p),MODE_32);
if(Instb.type == INSTRUCTION_TYPE_RET)
{
//StartAddress+len-inst.length-instb.length;
ulTemp = (PUCHAR)Instb.op1.displacement;
}
break;
}
if (ulTemp &&
MmIsAddressValid(ulTemp) &&
MmIsAddressValid(p)) //hook的地址也要有效才可以哦
{
if ((ULONG)ulTemp > SystemKernelModuleBase &&
(ULONG)ulTemp < SystemKernelModuleBase+SystemKernelModuleSize) //太近的跳也不是
{
goto Next;
}
//ulTemp也不能小于 SystemKernelModuleBase
if ((ULONG)ulTemp < SystemKernelModuleBase)
{
goto Next;
}
if (*(ULONG *)ulTemp == 0x00000000 ||
*(ULONG *)ulTemp == 0x00000005)
{
goto Next;
}
Flagss = 0;
__asm{
mov esi,ulTemp
mov ax,word ptr [esi]
cmp ax,0x0000
jz Cont//是add byte ptr [eax],al
mov Flagss,1
Cont:
}
if (Flagss != 1)
goto Next;
ulTemp = ulTemp+0x5;
//简单处理一下二级跳
if (*ulTemp == 0xe9 ||
*ulTemp == 0xe8)
{
ulTemp = (PUCHAR)(*(PULONG)(ulTemp+1)+(ULONG)(ulTemp+5));
}
FillInlineHookInfo(ulTemp+0x5,InlineHookInfo,functionName,(ULONG)p,2);
Next:
_asm{nop}
}
}
}
}
}
}
//结束鸟
if (*i == 0xcc ||
*i == 0xc2)
{
return 0;
}
}
}__except(EXCEPTION_EXECUTE_HANDLER){
}
return 0;
}
BOOLEAN IsFunctionInExportTable(ULONG ulModuleBase,ULONG ulFunctionAddress)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress,ulOldAddress;
IMAGE_EXPORT_DIRECTORY *pExportTable;
char *functionName;
__try
{
pDosHeader=(PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return FALSE;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return FALSE;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
{
//functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulModuleBase + arrayOfFunctionAddresses[functionOrdinal]);
//KdPrint(("%08x:%s\r\n",functionAddress,functionName));
//ulOldAddress = GetSystemRoutineAddress(0,functionName);
ulOldAddress = functionAddress - ulModuleBase + SystemKernelModuleBase;
if (ulFunctionAddress == ulOldAddress)
{
//是导出函数,退出
return TRUE;
}
}
}__except(EXCEPTION_EXECUTE_HANDLER){
}
return FALSE;
}
BOOLEAN ReSetEatHook(CHAR *lpszFunction,ULONG ulReloadKernelModule,ULONG ulKernelModule)
{
ULONG ulModuleBase;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base,x,functionAddress;
IMAGE_EXPORT_DIRECTORY *pExportTable;
char *functionName = NULL;
BOOL bIsEatHooked = FALSE;
int position;
ULONG ulFunctionOrdinal;
//恢复的时候 用reload的ImageModuleBase
ulModuleBase = ulReloadKernelModule;
pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
{
functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
ulFunctionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
ulFunctionOrdinal = arrayOfFunctionAddresses[ulFunctionOrdinal];
functionAddress = (DWORD)((BYTE*)ulModuleBase + ulFunctionOrdinal);
if (_stricmp(lpszFunction,functionName) == 0)
{
KdPrint(("reload ulFunctionOrdinal:%08x:%s",ulFunctionOrdinal,functionName));
//开始恢复
ulModuleBase = ulKernelModule;
pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
arrayOfFunctionAddresses[arrayOfFunctionOrdinals[x] + Base - 1] = ulFunctionOrdinal;
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
break;
}
}
return TRUE;
}
ULONG GetEatHook(ULONG ulOldAddress,int x,ULONG ulSystemKernelModuleBase,ULONG ulSystemKernelModuleSize)
{
ULONG ulModuleBase;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base,functionAddress;
IMAGE_EXPORT_DIRECTORY *pExportTable;
char *functionName = NULL;
BOOL bIsEatHooked = FALSE;
ULONG position = 0;
ULONG ulFunctionOrdinal;
ulModuleBase = ulSystemKernelModuleBase;
pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);
if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
{
KdPrint(("failed to find NtHeader\r\n"));
return 0;
}
opthdr = NtDllHeader->OptionalHeader;
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfFunctions); //地址表
arrayOfFunctionNames = (DWORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames); //函数名表
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
ulFunctionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulModuleBase + arrayOfFunctionAddresses[ulFunctionOrdinal]);
if (*functionName == 'Z' &&
*(functionName+1) == 'w')
{
position = *((WORD*)(functionAddress + 1)); //得到服务号
if (position > 0 &&
position <= OriginalServiceDescriptorTable->TableSize)
{
//得到原始地址
functionAddress = OriginalServiceDescriptorTable->ServiceTable[position] - (ULONG)ImageModuleBase + SystemKernelModuleBase;
}
}
if (ulOldAddress != functionAddress)
{
KdPrint(("EAT HOOK %08x:%s\r\n",functionAddress,functionName));
return functionAddress;
}
return 0;
}