📄 entry.cpp
字号:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <shlwapi.h>
#define IOCTL_SETPROC (ULONG)CTL_CODE( FILE_DEVICE_UNKNOWN, 0x852, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA )
#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 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;
BOOL SetProc( IN HANDLE hDriver, IN ULONG ulIndex, IN PULONG buf )
{
if ( NULL == buf )
{
return FALSE;
}
DWORD dwReturned;
BOOL bRet = DeviceIoControl( hDriver, IOCTL_SETPROC, &ulIndex,sizeof( ULONG ), buf, sizeof( ULONG ), &dwReturned, NULL );
return bRet && ERROR_SUCCESS == GetLastError();
}
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( IN HANDLE hDriver)
{
HMODULE hKernel;
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;
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("strange 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("Failed to load! LastError=%i\n",GetLastError());
return;
}
GlobalFree(pModules);
// our own export walker is useless here - we have GetProcAddress :)
if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable"))) {
printf("Can't find KeServiceDescriptorTable\n");
return;
}
// get KeServiceDescriptorTable rva
dwKSDT-=(DWORD)hKernel;
// find KiServiceTable
if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT))) {
printf("Can't find KiServiceTable...\n");
return;
}
printf("&KiServiceTable==%08X\n\nDumping 'old' ServiceTable:\n\n",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( hDriver,dwServices, &ulAddr );
//printf("%08X\n",ulAddr);
}
printf("\n\nPossibly KiServiceLimit==%08X\n",dwServices);
FreeLibrary(hKernel);
}
BOOL GetDriverPath( OUT LPTSTR lpFileName, IN DWORD dwSize )
{
// 确定驱动位置
TCHAR szPath[MAX_PATH];
GetModuleFileName( NULL, szPath, MAX_PATH );
lstrcpy( _tcsrchr( szPath, _T('\\') ) + 1, _T("RESSDT.sys") );
lstrcpyn( lpFileName, szPath, dwSize );
return PathFileExists( lpFileName );
}
HANDLE LoadDriver( IN LPCTSTR lpFileName )
{
HANDLE hDriver = INVALID_HANDLE_VALUE;
SC_HANDLE hSCManager = OpenSCManager( NULL, NULL,
SC_MANAGER_CREATE_SERVICE );
if ( NULL != hSCManager )
{
SC_HANDLE hService = CreateService( hSCManager, _T("RESSDT"),
_T("RESSDT"), SERVICE_START,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, lpFileName, NULL, NULL, NULL, NULL, NULL );
if ( ERROR_SERVICE_EXISTS == GetLastError() )
{
hService = OpenService( hSCManager, _T("RESSDT"), SERVICE_START );
}
StartService(hService,0,NULL);
hDriver = CreateFileA( "\\\\.\\RESSDTDOS",
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
CloseServiceHandle( hService );
CloseServiceHandle( hSCManager );
}
return hDriver;
}
void UnloadDriver( IN HANDLE hDriver )
{
CloseHandle( hDriver );
SC_HANDLE hSCManager = OpenSCManager( NULL, NULL,SC_MANAGER_CREATE_SERVICE );
if ( NULL != hSCManager )
{
SC_HANDLE hService = OpenService( hSCManager, _T("RESSDT"), DELETE | SERVICE_STOP );
if ( NULL != hService )
{
SERVICE_STATUS ss;
ControlService( hService, SERVICE_CONTROL_STOP, &ss );
DeleteService( hService );
CloseServiceHandle( hService );
}
CloseServiceHandle( hSCManager );
}
}
int main( void )
{
TCHAR strDriver[MAX_PATH];
GetDriverPath(strDriver,MAX_PATH);
printf("%s \n",strDriver);
HANDLE hDriver = LoadDriver( strDriver );
if ( INVALID_HANDLE_VALUE == hDriver )
{
puts( "Load driver failed!" );
return -1;
}
ReSSDT(hDriver);
UnloadDriver( hDriver );
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -