MalwareSourceCode/Win32/Proof of Concepts/CheckKernelEATHook/CheckKernelHookDrv/CheckKernelHook/Reload.c

356 lines
14 KiB
C
Raw Normal View History

2022-04-12 01:00:13 +00:00
#include "Reload.h"
#include "KernelReload.h"
WCHAR* SystemKernelFilePath = NULL;
ULONG_PTR SystemKernelModuleBase = 0;
ULONG_PTR SystemKernelModuleSize = 0;
ULONG_PTR ImageModuleBase;
PVOID OriginalKiServiceTable;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE OriginalServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE Safe_ServiceDescriptorTable;
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>FuncName <EFBFBD><EFBFBD> ԭ<EFBFBD><EFBFBD>Ntos<EFBFBD><EFBFBD>ַ <EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ntos<EFBFBD><EFBFBD>ַ
//<2F><>һ<EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ͨ<EFBFBD><CDA8> ϵͳ<CFB5><CDB3>ԭ<EFBFBD><D4AD>ƫ<EFBFBD><C6AB> + NewBase <20><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ַ
//Ȼ<><C8BB>ͨ<EFBFBD><CDA8><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>RMmGetSystemRoutineAddress<73><73><EFBFBD><EFBFBD> ƫ<><C6AB>+NewBase <20><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ַ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
ULONG ReLoadNtosCALL(WCHAR *lpwzFuncTion,ULONG ulOldNtosBase,ULONG ulReloadNtosBase)
{
UNICODE_STRING UnicodeFunctionName;
ULONG ulOldFunctionAddress;
PUCHAR ulReloadFunctionAddress = NULL;
int index=0;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS NtDllHeader;
IMAGE_OPTIONAL_HEADER opthdr;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress,position;
char* functionName;
IMAGE_EXPORT_DIRECTORY *pExportTable;
ULONG ulNtDllModuleBase;
UNICODE_STRING UnicodeFunction;
UNICODE_STRING UnicodeExportTableFunction;
ANSI_STRING ExportTableFunction;
//<2F><>һ<EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ͨ<EFBFBD><CDA8> ϵͳ<CFB5><CDB3>ԭ<EFBFBD><D4AD>ƫ<EFBFBD><C6AB> + NewBase <20><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ַ
//Ȼ<><C8BB>ͨ<EFBFBD><CDA8><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>RMmGetSystemRoutineAddress<73><73><EFBFBD><EFBFBD> ƫ<><C6AB>+NewBase <20><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ַ
__try
{
if (RRtlInitUnicodeString &&
RRtlCompareUnicodeString &&
RMmGetSystemRoutineAddress &&
RMmIsAddressValid)
{
RRtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);
ulOldFunctionAddress = (DWORD)RMmGetSystemRoutineAddress(&UnicodeFunctionName);
ulReloadFunctionAddress = (PUCHAR)(ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>FuncAddr
if (RMmIsAddressValid(ulReloadFunctionAddress)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȡ<EFBFBD><C8A1> Ӧ<>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>Ч
{
return (ULONG)ulReloadFunctionAddress;
}
//<2F>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ
ulNtDllModuleBase = ulReloadNtosBase;
pDosHeader = (PIMAGE_DOS_HEADER)ulReloadNtosBase;
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*)ulNtDllModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulNtDllModuleBase + pExportTable->AddressOfFunctions); //<2F><>ַ<EFBFBD><D6B7>
arrayOfFunctionNames = (DWORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNames); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
arrayOfFunctionOrdinals = (WORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
for(x = 0; x < pExportTable->NumberOfFunctions; x++) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>
{
functionName = (char*)( (BYTE*)ulNtDllModuleBase + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)((BYTE*)ulNtDllModuleBase + arrayOfFunctionAddresses[functionOrdinal]);
RtlInitAnsiString(&ExportTableFunction,functionName);
RtlAnsiStringToUnicodeString(&UnicodeExportTableFunction,&ExportTableFunction,TRUE);
RRtlInitUnicodeString(&UnicodeFunction,lpwzFuncTion);
if (RRtlCompareUnicodeString(&UnicodeExportTableFunction,&UnicodeFunction,TRUE) == 0)
{
RtlFreeUnicodeString(&UnicodeExportTableFunction);
return functionAddress;
}
RtlFreeUnicodeString(&UnicodeExportTableFunction);
}
return 0;
}
RtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);
ulOldFunctionAddress = (DWORD)MmGetSystemRoutineAddress(&UnicodeFunctionName);
ulReloadFunctionAddress = (PUCHAR)(ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase);
//KdPrint(("%ws:%08x:%08x",lpwzFuncTion,ulOldFunctionAddress,ulReloadFunctionAddress));
if (MmIsAddressValid(ulReloadFunctionAddress))
{
return (ULONG)ulReloadFunctionAddress;
}
//
}__except(EXCEPTION_EXECUTE_HANDLER){
KdPrint(("EXCEPTION_EXECUTE_HANDLER"));
}
return 0;
}
/*<2A><><EFBFBD><EFBFBD>Ntos*/
NTSTATUS ReLoadNtos(PDRIVER_OBJECT DriverObject,DWORD RetAddress)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG ulKeAddSystemServiceTable;
PULONG p;
if (!GetSystemKernelModuleInfo(
&SystemKernelFilePath,
&SystemKernelModuleBase,
&SystemKernelModuleSize
))
{
KdPrint(("Get System Kernel Module failed"));
return status;
}
if (InitSafeOperationModule(
DriverObject,
SystemKernelFilePath,
SystemKernelModuleBase
))
{
KdPrint(("Init Ntos module success\r\n"));
RRtlInitUnicodeString = NULL;
RMmGetSystemRoutineAddress = NULL;
RMmIsAddressValid = NULL;
RRtlCompareUnicodeString = NULL;
RPsGetCurrentProcess = NULL;
status = STATUS_UNSUCCESSFUL;
//<2F><>һ<EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ͨ<EFBFBD><CDA8> ϵͳ<CFB5><CDB3>ԭ<EFBFBD><D4AD>ƫ<EFBFBD><C6AB> + NewBase <20><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ַ
//Ȼ<><C8BB>ͨ<EFBFBD><CDA8><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>RMmGetSystemRoutineAddress<73><73><EFBFBD><EFBFBD> ƫ<><C6AB>+NewBase <20><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ַ
RRtlInitUnicodeString = (ReloadRtlInitUnicodeString)ReLoadNtosCALL(L"RtlInitUnicodeString",SystemKernelModuleBase,ImageModuleBase);
RRtlCompareUnicodeString = (ReloadRtlCompareUnicodeString)ReLoadNtosCALL(L"RtlCompareUnicodeString",SystemKernelModuleBase,ImageModuleBase);
RMmGetSystemRoutineAddress = (ReloadMmGetSystemRoutineAddress)ReLoadNtosCALL(L"MmGetSystemRoutineAddress",SystemKernelModuleBase,ImageModuleBase);
RMmIsAddressValid = (ReloadMmIsAddressValid)ReLoadNtosCALL(L"MmIsAddressValid",SystemKernelModuleBase,ImageModuleBase);
RPsGetCurrentProcess = (ReloadPsGetCurrentProcess)ReLoadNtosCALL(L"PsGetCurrentProcess",SystemKernelModuleBase,ImageModuleBase);
if (!RRtlInitUnicodeString ||
!RRtlCompareUnicodeString ||
!RMmGetSystemRoutineAddress ||
!RMmIsAddressValid ||
!RPsGetCurrentProcess)
{
KdPrint(("Init NtosCALL failed"));
return status;
}
}
return status;
}
BOOLEAN InitSafeOperationModule(PDRIVER_OBJECT pDriverObject,WCHAR *SystemModulePath,ULONG KernelModuleBase)
{
UNICODE_STRING FileName;
HANDLE hSection;
PDWORD FixdOriginalKiServiceTable;
PDWORD CsRootkitOriginalKiServiceTable;
ULONG i = 0;
//<2F>Լ<EFBFBD>peload һ<><D2BB>ntos*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD><EFBFBD>˸<EFBFBD><CBB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ͻ<EFBFBD><CDBB>~
if (!PeLoad(SystemModulePath,(BYTE**)&ImageModuleBase,pDriverObject,KernelModuleBase))
{
return FALSE;
}
OriginalKiServiceTable = ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
if (!OriginalKiServiceTable)
{
return FALSE;
}
//<2F><><EFBFBD><EFBFBD>SSDT<44><54>ַ<EFBFBD><D6B7>ͨ<EFBFBD><CDA8><EFBFBD>ض<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>Ƚϵõ<CFB5>
if(!GetOriginalKiServiceTable((BYTE*)ImageModuleBase,KernelModuleBase,(DWORD*)&OriginalKiServiceTable))
{
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
//<2F>޸<EFBFBD>SSDT<44><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ <20><><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>Reload<61>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>ַ <20>ɾ<EFBFBD><C9BE><EFBFBD>
FixOriginalKiServiceTable((PDWORD)OriginalKiServiceTable,(DWORD)ImageModuleBase,KernelModuleBase);
OriginalServiceDescriptorTable = (PSERVICE_DESCRIPTOR_TABLE)ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
if (OriginalServiceDescriptorTable == NULL)
{
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
RtlZeroMemory(OriginalServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
//<2F>޸<EFBFBD>SERVICE_DESCRIPTOR_TABLE <20>
OriginalServiceDescriptorTable->ServiceTable = (PDWORD)OriginalKiServiceTable;
OriginalServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;
OriginalServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize;
OriginalServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
CsRootkitOriginalKiServiceTable = (PDWORD)ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
if (CsRootkitOriginalKiServiceTable==NULL)
{
ExFreePool(OriginalServiceDescriptorTable);
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
RtlZeroMemory(CsRootkitOriginalKiServiceTable,KeServiceDescriptorTable->TableSize*sizeof(DWORD));
Safe_ServiceDescriptorTable = (PSERVICE_DESCRIPTOR_TABLE)ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
if (Safe_ServiceDescriptorTable == NULL)
{
ExFreePool(OriginalServiceDescriptorTable);
ExFreePool(CsRootkitOriginalKiServiceTable);
ExFreePool(OriginalKiServiceTable);
return FALSE;
}
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>SSDT<44><54><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>
RtlZeroMemory(Safe_ServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);
//<2F><><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
for (i = 0; i < KeServiceDescriptorTable->TableSize; i++)
{
CsRootkitOriginalKiServiceTable[i] = OriginalServiceDescriptorTable->ServiceTable[i];
}
Safe_ServiceDescriptorTable->ServiceTable = (PDWORD)CsRootkitOriginalKiServiceTable;
Safe_ServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;
Safe_ServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize;
Safe_ServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
//<2F>ͷžͻ<C5BE>bsod
//ExFreePool(OriginalKiServiceTable);
return TRUE;
}
VOID FixOriginalKiServiceTable(PDWORD OriginalKiServiceTable,DWORD ModuleBase,DWORD ExistImageBase)
{
DWORD FuctionCount;
DWORD Index;
FuctionCount=KeServiceDescriptorTable->TableSize; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
KdPrint(("ssdt funcion count:%X---KiServiceTable:%X\n",FuctionCount,KeServiceDescriptorTable->ServiceTable));
for (Index=0;Index<FuctionCount;Index++)
{
OriginalKiServiceTable[Index]=OriginalKiServiceTable[Index]-ExistImageBase+ModuleBase; //<2F>޸<EFBFBD>SSDT<44><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
}
}
//ͨ<><CDA8>KeServiceDescriptorTable<6C><65>RVA<56><41><EFBFBD>ض<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַRVA<56>Ƚϣ<C8BD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>SSDT<44><54><EFBFBD><EFBFBD>ַ
BOOLEAN GetOriginalKiServiceTable(BYTE *NewImageBase,DWORD ExistImageBase,DWORD *NewKiServiceTable)
{
PIMAGE_DOS_HEADER ImageDosHeader;
PIMAGE_NT_HEADERS ImageNtHeaders;
DWORD KeServiceDescriptorTableRva;
PIMAGE_BASE_RELOCATION ImageBaseReloc=NULL;
DWORD RelocSize;
int ItemCount,Index;
int Type;
PDWORD RelocAddress;
DWORD RvaData;
DWORD count=0;
WORD *TypeOffset;
ImageDosHeader=(PIMAGE_DOS_HEADER)NewImageBase;
if (ImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
ImageNtHeaders=(PIMAGE_NT_HEADERS)(NewImageBase+ImageDosHeader->e_lfanew);
if (ImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE)
{
return FALSE;
}
KeServiceDescriptorTableRva=(DWORD)MiFindExportedRoutine(NewImageBase,TRUE,"KeServiceDescriptorTable",0);
if (KeServiceDescriptorTableRva==0)
{
return FALSE;
}
KeServiceDescriptorTableRva=KeServiceDescriptorTableRva-(DWORD)NewImageBase;
ImageBaseReloc=RtlImageDirectoryEntryToData(NewImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_BASERELOC,&RelocSize);
if (ImageBaseReloc==NULL)
{
return FALSE;
}
while (ImageBaseReloc->SizeOfBlock)
{
count++;
ItemCount=(ImageBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/2;
TypeOffset=(WORD*)((DWORD)ImageBaseReloc+sizeof(IMAGE_BASE_RELOCATION));
for (Index=0;Index<ItemCount;Index++)
{
Type=TypeOffset[Index]>>12; //<2F><><34><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>12λλҳ<CEBB><D2B3>ƫ<EFBFBD><C6AB> 4k
if (Type==3)
{
//Base + Virtual <20><>λ<EFBFBD><CEBB>ҳ + <20><>12λ = RelocAddress <20><>Ҫ<EFBFBD>޸<EFBFBD><DEB8>ĵ<EFBFBD>ַ
RelocAddress=(PDWORD)((DWORD)(TypeOffset[Index]&0x0fff)+ImageBaseReloc->VirtualAddress+(DWORD)NewImageBase);
RvaData=*RelocAddress-ExistImageBase;
if (RvaData==KeServiceDescriptorTableRva) //<2F>ض<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>е<EFBFBD>rva <20><> KeServiceDescriptorTable <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if(*(USHORT*)((DWORD)RelocAddress-2)==0x05c7)
{
/*
1: kd> dd 0x89651c12 RelocAddress - 2
89651c12 79c005c7 bd9c83f8
1: kd> dd KeServiceDescriptorTable
83f879c0 83e9bd9c 00000000 00000191 83e9c3e4
83f879d0 00000000 00000000 00000000 00000000
1: kd> dd 0x89651c14 RelocAddress
89651c14 83f879c0 83e9bd9c 79c41589 c8a383f8
89651c24 c783f879 f879cc05 e9c3e483 d8158983
*/
//RelocAddress <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> KeServiceDesriptorTable<6C><65>ַ
//RelocAddress + 4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> KeServiceDesriptorTable<6C><65>һ<EFBFBD><D2BB>ԱҲ<D4B1><D2B2><EFBFBD><EFBFBD>SSDT<44><54>ַ
*NewKiServiceTable=*(DWORD*)((DWORD)RelocAddress+4)-ExistImageBase+(DWORD)NewImageBase;
return TRUE;
}
}
}
}
ImageBaseReloc=(PIMAGE_BASE_RELOCATION)((DWORD)ImageBaseReloc+ImageBaseReloc->SizeOfBlock);
}
return FALSE;
}