mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 23:39:23 +00:00
900263ea6f
n/a
695 lines
27 KiB
C
695 lines
27 KiB
C
#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;
|
|
}
|
|
|