这个很久以前写的不过在VBGOOD上发布出去了代码写的很乱 这次删除了一些没用的代码 #include <stdio.h> #include <tchar.h> #include <windows.h> #include <shlwapi.h> #include <iostream> using namespace std; ULONG pBase = NULL; #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 struct _MEMORY_CHUNKS { ULONG Address; PVOID Data; ULONG Length; }MEMORY_CHUNKS, *PMEMORY_CHUNKS; typedef LONG NTSTATUS; typedef NTSTATUS (WINAPI *PFNNtQuerySystemInformation)( DWORD SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); 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; typedef struct { DWORD dwNumberOfModules; SYSTEM_MODULE_INFORMATION smi; } MODULES, *PMODULES; NTSTATUS ( __stdcall *NTSystemDebugControl ) ( IN int nCmd, IN PVOID pInBuf, IN ULONG nInLen, OUT PVOID pOutBuf, IN ULONG nOutLen, OUT PULONG nRetLen OPTIONAL); typedef struct _tagSSDT { PVOID pvSSDTBase; PVOID pvServiceCounterTable; ULONG ulNumberOfServices; PVOID pvParamTableBase; } SSDT, *PSSDT; VOID SetProc(IN ULONG ulIndex, IN PULONG buf ) { MEMORY_CHUNKS datas; ULONG dwRetLen; datas.Address =(ULONG)pBase + (ulIndex*4); datas.Data = buf; datas.Length = sizeof(LONG); NTSystemDebugControl(0x9,&datas,sizeof(MEMORY_CHUNKS),NULL,0,&dwRetLen); } 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; } 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 thru 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 KiServiceTable here // but forget it dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase; return dwKiServiceTable; } } } else if (pfe->type!=IMAGE_REL_BASED_ABSOLUTE) // should never get here // printf("/trelo type %d found at .%X/n",pfe->type,pbr->VirtualAddress+pfe->offset); } *(PDWORD)&pbr+=pbr->SizeOfBlock; } } if (!dwFixups) // should never happen - nt, 2k, xp kernels have relocation data // printf("No fixups!/n"); return 0; } void ReSSDT() { DWORD dwRetLen = 1024*800; HMODULE hKernel; PLONG KernelBase=NULL; MEMORY_CHUNKS datas; DWORD dwKSDT; // rva of KeServiceDescriptorTable DWORD dwKiServiceTable; // rva of KiServiceTable PMODULES pModules=(PMODULES)&pModules; DWORD dwNeededSize,rc; DWORD dwKernelBase,dwServices=0; PCHAR pKernelName; PDWORD pService; PIMAGE_FILE_HEADER pfh; PIMAGE_OPTIONAL_HEADER poh; PIMAGE_SECTION_HEADER psh; GetProcAddress(LoadLibrary("NTDLL.DLl"),"NtSystemDebugControl"); __asm { MOV NTSystemDebugControl,EAX } FARPROC NtQuerySystemInformationAddr=GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"); // get system modules - ntoskrnl is always first there rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,4,&dwNeededSize); if (rc==STATUS_INFO_LENGTH_MISMATCH) { pModules=(MODULES *)GlobalAlloc(GPTR,dwNeededSize); rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,dwNeededSize,NULL); } else { strange: // printf("不能使用 NtQuerySystemInformation()!/n"); return; } if (!NT_SUCCESS(rc)) goto strange; // imagebase dwKernelBase=(DWORD)pModules->smi.Base; // filename - it may be renamed in the boot.ini pKernelName=pModules->smi.ModuleNameOffset+pModules->smi.ImageName; // map ntoskrnl - hopefully it has relocs hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES); if (!hKernel) { // printf("加载内核文件失败! LastError=%i/n",GetLastError()); return; } GlobalFree(pModules); // our own export walker is useless here - we have GetProcAddress :) if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable"))) { // printf("不能得到KeServiceDescriptorTable/n"); return; } // get KeServiceDescriptorTable rva dwKSDT-=(DWORD)hKernel; // find KiServiceTable if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT))) { // printf("不能得到KiServiceTable.../n"); return; } // printf("&KiServiceTable==%08X/n/nDumping 'old' ServiceTable:/n/n",dwKiServiceTable+dwKernelBase); pBase=(ULONG)dwKiServiceTable+dwKernelBase; // let's dump KiServiceTable contents // MAY FAIL!!! // should get right ServiceLimit here, but this is trivial in the kernel mode GetHeaders((PCHAR)hKernel,&pfh,&poh,&psh); for (pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable); *pService-poh->ImageBase<poh->SizeOfImage; pService++,dwServices++) { ULONG ulAddr=*pService-poh->ImageBase+dwKernelBase; SetProc(dwServices,&ulAddr); // printf("INDEX:%3X 原地址:%8X /r/n",dwServices,ulAddr); } // printf("/n/SSDT总数==%08X/n",dwServices); FreeLibrary(hKernel); } int main( void ) { ReSSDT(); return EXIT_SUCCESS; }