SSDT UnHook For C-翻译女王的代码,百分之80%的相似度,
Copy code
#include <ntddk.h>
#include "PE.h"
typedef struct _tagSSDT {
PVOID pvSSDTBase;
PVOID pvServiceCounterTable;
ULONG ulNumberOfServices;
PVOID pvParamTableBase;
} SSDT, *PSSDT;
extern PSSDT KeServiceDescriptorTable;
// 2个结构体
typedef struct _SYSTEM_MODULE
{
ULONG Reserved[2];
ULONG Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG uCount;
SYSTEM_MODULE_INFORMATION aSM[];
}MODULE_LIST,*PMODULE_LIST;
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
ULONG GetKernelBaseAddress(char* lpszModule)
{
NTSTATUS nResult;
ULONG ulNeededSize, uLoop, uKernelAddr;
PMODULE_LIST pModuleList;
uKernelAddr = 0;
ZwQuerySystemInformation(11, &ulNeededSize, 0, &ulNeededSize);
pModuleList = ExAllocatePool(NonPagedPool, ulNeededSize);
nResult = ZwQuerySystemInformation(11, pModuleList, ulNeededSize, NULL);
if (NT_SUCCESS(nResult))
{
//ntoskrnl is always first there
uKernelAddr = pModuleList->aSM[0].Base;
strcpy(lpszModule,"//SystemRoot//System32//");
strcat(lpszModule,pModuleList->aSM[0].ModuleNameOffset+pModuleList->aSM[0].ImageName);
}
ExFreePool(pModuleList);
return uKernelAddr;
}
ULONG RVAToRaw(PVOID lpBase,ULONG VirtualAddress)
{
IMAGE_DOS_HEADER *pDosHeader;
IMAGE_NT_HEADERS *pNtHeader;
IMAGE_SECTION_HEADER *pSectionHeader;
ULONG NumOfSections,uLoop;
pDosHeader=(IMAGE_DOS_HEADER*)lpBase;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return 0;
pNtHeader=(IMAGE_NT_HEADERS*)((unsigned char*)lpBase+pDosHeader->e_lfanew);
NumOfSections=pNtHeader->FileHeader.NumberOfSections;
pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pNtHeader + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + pNtHeader->FileHeader.SizeOfOptionalHeader);
VirtualAddress -= (ULONG)lpBase;
for (uLoop=0;uLoop<NumOfSections;uLoop++)
{
pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pSectionHeader + sizeof(IMAGE_SECTION_HEADER) * uLoop);
if(VirtualAddress>pSectionHeader->VirtualAddress&&VirtualAddress<pSectionHeader->VirtualAddress+pSectionHeader->SizeOfRawData)
{
ULONG Offset = VirtualAddress-pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;
return Offset;
}
}
return 0;
}
//服务停止时执行
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
DbgPrint("DriverUnload!");
}
//StartService时调用
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
NTSTATUS status=STATUS_SUCCESS;
ULONG uKernelMoule,uImageBase,uSSDTCount,uSSDTBase,uSSDTRaw,uLoop,uOldAddress,uNewAddress;
PULONG lpArraySSDT;
char szKernelPath[256];
ANSI_STRING aFileName;
UNICODE_STRING uFileName;
OBJECT_ATTRIBUTES ObjAttr;
IO_STATUS_BLOCK ioStatus;
FILE_POSITION_INFORMATION FilePos;
HANDLE hFile;
theDriverObject->DriverUnload=DriverUnload;
// get system modules
memset(szKernelPath,0,256);
uKernelMoule = GetKernelBaseAddress(szKernelPath);
uImageBase = ((IMAGE_NT_HEADERS*)(uKernelMoule + ((IMAGE_DOS_HEADER*)uKernelMoule)->e_lfanew))->OptionalHeader.ImageBase;
DbgPrint("Kernel ImageBase: 0x%.8X", uImageBase);
DbgPrint("Kernel Base: 0x%.8X", uKernelMoule);
DbgPrint("Kernel Module Path: %s", szKernelPath);
//
uSSDTCount = KeServiceDescriptorTable->ulNumberOfServices;
uSSDTBase = (ULONG)KeServiceDescriptorTable->pvSSDTBase;
DbgPrint("SSDT BaseAddress: 0x%8X, SSDT Count: 0x%X", uSSDTBase, uSSDTCount);
lpArraySSDT = ExAllocatePool(PagedPool, uSSDTCount * sizeof(ULONG));
if (lpArraySSDT == NULL) return status;
//计算SSDT数组的文件偏移
uSSDTRaw = RVAToRaw(uKernelMoule, uSSDTBase);
DbgPrint("SSDT RAW: 0x%.8X", uSSDTRaw);
if (uSSDTRaw == 0)
{
DbgPrint("SSDT RAW Error");
ExFreePool(lpArraySSDT);
return status;
}
RtlInitAnsiString(&aFileName,szKernelPath);
status = RtlAnsiStringToUnicodeString(&uFileName, &aFileName, TRUE);
if(!NT_SUCCESS(status))
{
DbgPrint("RtlAnsiStringToUnicodeString Error");
ExFreePool(lpArraySSDT);
return status;
}
InitializeObjectAttributes(&ObjAttr, &uFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjAttr, &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(status) && hFile)
{
FilePos.CurrentByteOffset.LowPart = uSSDTRaw;//1000;//uSSDTRaw;
FilePos.CurrentByteOffset.HighPart = 0;
status = ZwSetInformationFile(hFile, &ioStatus, &FilePos, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
if (NT_SUCCESS(status))
{
status = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, lpArraySSDT, uSSDTCount * sizeof(ULONG), NULL, NULL);
if (NT_SUCCESS(status))
{
for (uLoop=0; uLoop<uSSDTCount; uLoop++)
{
uOldAddress = *(lpArraySSDT + uLoop) - uImageBase + uKernelMoule;
uNewAddress = *((PULONG)uSSDTBase + uLoop);
if (uOldAddress != uNewAddress)
{
DbgPrint("SSDT No.%X, Old: 0x%.8X, New: 0x%.8X", uLoop, uOldAddress, uNewAddress);
/* __asm
{//关中断
cli
mov eax,cr0
and eax,~0x10000
mov cr0,eax
}
*((PULONG)uSSDTBase + uLoop) = uOldAddress;
//fast_InterlockedExchange(*(uSSDTBase + uLoop), uOldAddress);
__asm
{//开中断
mov eax,cr0
or eax,0x10000
mov cr0,eax
sti
}
*/
}
}
DbgPrint("SSDT TheEnd...");
}
else
DbgPrint("Read File Error!");
}
// else
// DbgPrint("Set File Pos Error!");
if(hFile)
ZwClose(hFile);
}
else
DbgPrint("Open File Error!");
RtlFreeUnicodeString(&uFileName);
ExFreePool(lpArraySSDT);
return status;
}