//CodeBy XiCao
#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;
}
/////////////////////////////////////////////////////////////////
//PE.H
#ifndef _PE_H_
#define _PE_H_
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef unsigned char BYTE, *PBYTE;
typedef unsigned int UINT, *PUINT;
// headers PE
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
ULONG PhysicalAddress;
ULONG VirtualSize;
} Misc;
ULONG VirtualAddress;
ULONG SizeOfRawData;
ULONG PointerToRawData;
ULONG PointerToRelocations;
ULONG PointerToLinenumbers;
USHORT NumberOfRelocations;
USHORT NumberOfLinenumbers;
ULONG Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) /
((ULONG)ntheader + /
FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + /
((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader /
))
typedef struct _IMAGE_DOS_HEADER {
USHORT e_magic;
USHORT e_cblp;
USHORT e_cp;
USHORT e_crlc;
USHORT e_cparhdr;
USHORT e_minalloc;
USHORT e_maxalloc;
USHORT e_ss;
USHORT e_sp;
USHORT e_csum;
USHORT e_ip;
USHORT e_cs;
USHORT e_lfarlc;
USHORT e_ovno;
USHORT e_res[4];
USHORT e_oemid;
USHORT e_oeminfo;
USHORT e_res2[10];
LONG e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _IMAGE_FILE_HEADER {
USHORT Machine;
USHORT NumberOfSections;
ULONG TimeDateStamp;
ULONG PointerToSymbolTable;
ULONG NumberOfSymbols;
USHORT SizeOfOptionalHeader;
USHORT Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
ULONG VirtualAddress;
ULONG Size;
} IMAGE_DATA_DIRECTORY,
*PIMAGE_DATA_DIRECTORY;
typedef struct _IMAGE_OPTIONAL_HEADER {
USHORT Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
ULONG SizeOfCode;
ULONG SizeOfInitializedData;
ULONG SizeOfUninitializedData;
ULONG AddressOfEntryPoint;
ULONG BaseOfCode;
ULONG BaseOfData;
ULONG ImageBase;
ULONG SectionAlignment;
ULONG FileAlignment;
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
USHORT MajorImageVersion;
USHORT MinorImageVersion;
USHORT MajorSubsystemVersion;
USHORT MinorSubsystemVersion;
ULONG Win32VersionValue;
ULONG SizeOfImage;
ULONG SizeOfHeaders;
ULONG CheckSum;
USHORT Subsystem;
USHORT DllCharacteristics;
ULONG SizeOfStackReserve;
ULONG SizeOfStackCommit;
ULONG SizeOfHeapReserve;
ULONG SizeOfHeapCommit;
ULONG LoaderFlags;
ULONG NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
typedef struct _IMAGE_NT_HEADERS {
ULONG Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
// PEB
#pragma pack(4)
typedef struct _PEB_LDR_DATA
{
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
#pragma pack()
typedef struct _PEB_ORIG {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[229];
PVOID Reserved3[59];
ULONG SessionId;
} PEB_ORIG, *PPEB_ORIG;
typedef void (*PPEBLOCKROUTINE)(PVOID PebLock);
struct _PEB_FREE_BLOCK {
struct _PEB_FREE_BLOCK *Next;
ULONG Size;
};
typedef struct _PEB_FREE_BLOCK PEB_FREE_BLOCK;
typedef struct _PEB_FREE_BLOCK *PPEB_FREE_BLOCK;
typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StdInputHandle;
HANDLE StdOutputHandle;
HANDLE StdErrorHandle;
UNICODE_STRING CurrentDirectoryPath;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingPositionLeft;
ULONG StartingPositionTop;
ULONG Width;
ULONG Height;
ULONG CharWidth;
ULONG CharHeight;
ULONG ConsoleTextAttributes;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopName;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PPEBLOCKROUTINE FastPebLockRoutine;
PPEBLOCKROUTINE FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID *KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID *ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID **ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, *PPEB;