SSDT new way

 

//http://www.rootkit.com/newsread.php?newsid=176

#include <windows.h>

struct IMAGE_FIXUP_ENTRY

{

WORD offset:12,type:4;

};

long _stdcall NtQuerySystemInformation();

HMODULE hKernel;

DWORD dwKSDT,dwKernelBase,*j,dwKiServiceTable,*pService,i,dwPointerRva;

PIMAGE_OPTIONAL_HEADER poh;

PIMAGE_DOS_HEADER mzhead;

PIMAGE_BASE_RELOCATION pbr;

struct IMAGE_FIXUP_ENTRY *pfe;   

void main()

{   

j=GlobalAlloc(0,20000);

NtQuerySystemInformation(11,j,20000,0);

dwKernelBase=*(j+3);

hKernel=LoadLibraryEx("ntoskrnl.exe",0,0);

We then want the address of KeServiceDescriptorTable an exported variable in ntoskrnl.exe. We use the function GetProcAddress

 

dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable") - (DWORD)hKernel;

mzhead=(PIMAGE_DOS_HEADER)hKernel;

poh=(PIMAGE_OPTIONAL_HEADER)((int)hKernel+mzhead->e_lfanew+sizeof(IMAGE_NT_SIGNATURE)+sizeof(IMAGE_FILE_HEADER));

pbr=(PIMAGE_BASE_RELOCATION)(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress+(int)hKernel);

while (dwKiServiceTable == 0)

{

pfe=(struct IMAGE_FIXUP_ENTRY *)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));

for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++)

{

dwPointerRva=pbr->VirtualAddress+pfe->offset;

if (*(PDWORD)((DWORD)hKernel+dwPointerRva)-(DWORD)poh->ImageBase == dwKSDT)

{

//check for mov [mem32],imm32. we are trying to find mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable from the KiInitSystem.

if (*(PWORD)((DWORD)hKernel+dwPointerRva-2)==0x05c7)

dwKiServiceTable = *(PDWORD)((DWORD)hKernel+dwPointerRva+4)-poh->ImageBase;

}

}

*(PDWORD)&pbr+=pbr->SizeOfBlock;

}

if ( dwKiServiceTable+dwKernelBase == 0x804E26A8)

printf("KiServiceTable OK\n");

pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable);

if ( *pService-poh->ImageBase+dwKernelBase == 0x805862DE)

printf("1st entry ok\n");

pService++;

if ( *pService-poh->ImageBase+dwKernelBase == 0x8056FDED)

printf("2nt entry ok\n");

}

 

Lets look at a new way of finding the address of the ssdt table but without getting into ring 0. As always we first need to find the address of where ntoskrnl starts in memory. We take lots of shortcuts here as we have done this a trillion times before. We first  allocate 20000 bytes of memory using GlobalAlloc even though malloc would have done the job. Like always the perso0n who wrote the original program used GlobalAlloc and so do we. We then call the method NtQuerySystemInformation passing it a value 11 to gives a list of modules in j. We simply specify that this method os stdcall and link it with nt.dll.lib copied from the winddk. You can use LoadLibrary for all that we care. The parameters do not have to specified in the prototype of the method NtQuerySystemInformation. The first four bytes are the number of structures followed by 2 more int’s. Thus 12 bytes from the start is the address of where ntoskrnl.exe starts in memory and also it is the first structure. On Windows XP the value of the base of ntoskrnl.exe is 804d7000 which is in kernel memory and not user memory. We then use the LoadLibraryEx function and not LoadLibrary to load ntoskrnl.exe in memory. On our machine it loads at 410000, very low in memory.