// ***************************************************************
// main version: 1.0 ? date: 09/16/2008
// -------------------------------------------------------------
// SSDT
// ***************************************************************
//
// ***************************************************************
#include <windows.h>
#include <winnt.h>
#include <WindowsX.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#define ibaseDD *(PDWORD)&ibase
HINSTANCE g_hInst;
HWND hWinMain,hList;
#define ID_LISTVIEW 104
#pragma comment(lib,"comctl32")
typedef ULONG NTSTATUS;
#define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset)))
#define ibaseDD *(PDWORD)&ibase
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef struct {
WORD offset:12;
WORD type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
typedef ULONG (WINAPI *ZWQUERYSYSTEMINFORMATION)(
DWORD SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength);
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;
typedef enum _SYSDBG_COMMAND {
// 以下是NT 5.1 新增的
//从内核空间拷贝到用户空间,或者从用户空间拷贝到用户空间
//但是不能从用户空间拷贝到内核空间
SysDbgReadVirtualMemory = 8,
//从用户空间拷贝到内核空间,或者从用户空间拷贝到用户空间
//但是不能从内核空间拷贝到用户空间
SysDbgWriteVirtualMemory = 9,
} SYSDBG_COMMAND, *PSYSDBG_COMMAND;
typedef struct _MEMORY_CHUNKS {
ULONG Address;
PVOID Data;
ULONG Length;
}MEMORY_CHUNKS, *PMEMORY_CHUNKS;
typedef NTSTATUS (NTAPI * ZWSYSTEMDEBUGCONTROL) (
SYSDBG_COMMAND ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
);
ZWSYSTEMDEBUGCONTROL ZwSystemDebugControl = NULL;
typedef struct _SYSTEM_MODULE_INFORMATION { //Information Class 11
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;
#define SystemModuleInformation 11
typedef struct
{
CHAR fname[100];
ULONG address1;
ULONG address2;
} SSDT_LIST_ENTRY;
SSDT_LIST_ENTRY *ssdt_list;
/////////////////////////////////////////////////////////////////////////
BOOL LocateNtdllEntry()
{
HMODULE ntdll_dll = NULL;
if (!(ntdll_dll = GetModuleHandle("ntdll.dll"))) return FALSE;
if ( !( ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(ntdll_dll, "ZwQuerySystemInformation" )))
return FALSE;
if ( !( ZwSystemDebugControl = (ZWSYSTEMDEBUGCONTROL)GetProcAddress(ntdll_dll, "ZwSystemDebugControl" )))
return FALSE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
BOOL DebugPrivilege(TCHAR *PName,BOOL bEnable)
{
BOOL fOk = FALSE;
HANDLE hToken;
TOKEN_PRIVILEGES tp;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken))
{
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
LookupPrivilegeValue(NULL,PName,&tp.Privileges[0].Luid);
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
fOk=(GetLastError() == ERROR_SUCCESS);
CloseHandle(hToken);
}
return fOk;
}
//////////////////////////////////////////////////////////////////////////
DWORD GetHeaders(PCHAR ibase,
PIMAGE_FILE_HEADER *pfh,
PIMAGE_OPTIONAL_HEADER *poh,
PIMAGE_SECTION_HEADER *psh)
{
PIMAGE_DOS_HEADER mzhead=(PIMAGE_DOS_HEADER)ibase;
if ((mzhead->e_magic!=IMAGE_DOS_SIGNATURE) ||
(ibaseDD[mzhead->e_lfanew]!=IMAGE_NT_SIGNATURE))
return FALSE;
*pfh=(PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew];
if (((PIMAGE_NT_HEADERS)*pfh)->Signature!=IMAGE_NT_SIGNATURE)
return FALSE;
*pfh=(PIMAGE_FILE_HEADER)((PBYTE)*pfh+sizeof(IMAGE_NT_SIGNATURE));
*poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh+sizeof(IMAGE_FILE_HEADER));
if ((*poh)->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return FALSE;
*psh=(PIMAGE_SECTION_HEADER)((PBYTE)*poh+sizeof(IMAGE_OPTIONAL_HEADER));
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// Search the Export function name.
//////////////////////////////////////////////////////////////////////////
void FindExport()
{
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
PIMAGE_EXPORT_DIRECTORY ped;
DWORD *arrayOfFunctionNames;
DWORD* arrayOfFunctionAddresses;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal,functionAddress;
HMODULE hNtdll=GetModuleHandle(TEXT("ntdll.dll"));
GetHeaders((PCHAR)hNtdll,&pfh,&poh,&psh);
if (poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
{
ped=(PIMAGE_EXPORT_DIRECTORY)(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+(BYTE*)hNtdll);
arrayOfFunctionNames=(DWORD*)(ped->AddressOfNames+(BYTE*)hNtdll);
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hNtdll + ped->AddressOfFunctions);
arrayOfFunctionNames = (DWORD*)( (BYTE*)hNtdll + ped->AddressOfNames);
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hNtdll + ped->AddressOfNameOrdinals);
for (unsigned int i=0;i<ped->NumberOfNames;i++)
{
char* fun_name= (char*)((BYTE*)hNtdll + arrayOfFunctionNames[i]);
functionOrdinal = arrayOfFunctionOrdinals[i] + ped->Base - 1;
functionAddress = (DWORD)( (BYTE*)hNtdll + arrayOfFunctionAddresses[functionOrdinal]);
if (fun_name[0]=='N'&&fun_name[1]=='t')
{
WORD number=*((WORD*)(functionAddress+1));
if (number>ped->NumberOfNames) continue;
lstrcpy(ssdt_list[number].fname,fun_name);
}
}
}
}
DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT)
{
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
PIMAGE_BASE_RELOCATION pbr;
PIMAGE_FIXUP_ENTRY pfe;
DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;
BOOL bFirstChunk;
GetHeaders((PCHAR)hModule,&pfh,&poh,&psh);
// loop through relocs to speed up the search
if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &&
(!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) {
pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);
bFirstChunk=TRUE;
// 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0
while (bFirstChunk || pbr->VirtualAddress) {
bFirstChunk=FALSE;
pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));
for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) {
if (pfe->type==IMAGE_REL_BASED_HIGHLOW) {
dwFixups++;
dwPointerRva=pbr->VirtualAddress+pfe->offset;
// DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed
dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;
// does this reloc point to KeServiceDescriptorTable.Base?
if (dwPointsToRva==dwKSDT) {
// check for mov [mem32],imm32. we are trying to find
// "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable"
// from the KiInitSystem.
if (*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7) {
// should check for a reloc presence on KiServiceTabl