diddom 发表于 2012-5-15 02:34:46

老掉牙的无驱动恢复SSDT

// RestoreSSDT.cpp : Defines the entry point for the console application.
////無驅動回復SSDT

//#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <shlwapi.h>
#include <iostream>
using namespace std;

typedef LONG NTSTATUS;

#define SystemModuleInfo        11
#define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset)))   
#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)   
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define ibaseDD *(PDWORD)&ibase

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 struct _SYSTEM_MODULE_INFORMATION {//Information Class 11   
    ULONG    Reserved;
    PVOID    Base;
    ULONG    Size;
    ULONG    Flags;
    USHORT    Index;
    USHORT    Unknown;
    USHORT    LoadCount;
    USHORT    ModuleNameOffset;
    CHAR    ImageName;
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;


typedef struct {
    DWORD    dwNumberOfModules;
    SYSTEM_MODULE_INFORMATION    smi;
} MODULES, *PMODULES;


typedef struct _tagSSDT {
    PVOID pvSSDTBase;
    PVOID pvServiceCounterTable;
    ULONG ulNumberOfServices;
    PVOID pvParamTableBase;
} SSDT, *PSSDT;


typedef
NTSTATUS
(WINAPI *PFNNtQuerySystemInformation)(      
    DWORD    SystemInformationClass,
    PVOID    SystemInformation,
    ULONG    SystemInformationLength,
    PULONG    ReturnLength
    );

//typedef
//NTSTATUS
//(WINAPI *NTSystemDebugControl)(
        //IN int nCmd,
        //IN PVOID pInBuf,
        //IN ULONG nInLen,   
        //OUT PVOID pOutBuf,
        //IN ULONG nOutLen,
        //OUT PULONG nRetLen OPTIONAL
        //);


//typedef
NTSTATUS
(__stdcall *NTSystemDebugControl)(
        IN int nCmd,
        IN PVOID pInBuf,
        IN ULONG nInLen,   
        OUT PVOID pOutBuf,
        IN ULONG nOutLen,
        OUT PULONG nRetLen OPTIONAL
        );

///////////////////////////////////////////////////////////

ULONG pBase = NULL;

///////////////////////////////////////////////////////////
//
//
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 != IMAGE_NT_SIGNATURE))
      return FALSE;
      
    *pfh = (PIMAGE_FILE_HEADER)&ibase;

    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.VirtualAddress) &&
      (!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED)))
        {
         
      pbr = (PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory.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 ,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);
                                        }
                                }

            } // end for

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

      }// end while

    } // end if
      
    if (!dwFixups)
        {
      // should never happen - nt, 2k, xp kernels have relocation data   
                // printf("No fixups!/n");
        }
    return 0;
}


///////////////////////////////////////////////////////////
//
//
void ReSSDT()
{
        //MEMORY_CHUNKS        datas;
        HMODULE                        hKernel;
        DWORD                        dwRetLen = 1024 * 800;
        PLONG                        KernelBase = NULL;      
        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)(SystemModuleInfo, pModules, 4, &dwNeededSize);

    if (rc == STATUS_INFO_LENGTH_MISMATCH)
        {
      pModules = (MODULES *) GlobalAlloc(GPTR, dwNeededSize);
      rc = ((PFNNtQuerySystemInformation) NtQuerySystemInformationAddr)(SystemModuleInfo, pModules, dwNeededSize, NULL);
        }
        else
        {
strange:
        //    printf("Can't Get 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("Load Driver Fail! 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 Get KeServiceDescriptorTable/n");   
      return;
    }

    // get KeServiceDescriptorTable rva   
    dwKSDT -= (DWORD)hKernel;

    // find KiServiceTable
    if (!(dwKiServiceTable = FindKiServiceTable(hKernel,dwKSDT)))
        {
    //    printf("Can't Get 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!!!
    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 OrgAddr:%8X /r/n",dwServices,ulAddr);   
    }

        //   printf("/n/SSDT Total==%08X/n",dwServices);
    FreeLibrary(hKernel);
}



///////////////////////////////////////////////////////////
//
//
int main(int argc, char* argv[])
{
        ReSSDT();
        //printf("Hello World!\n");
        return 0;
}

source

别人的作品, 忘记在哪看到的

po在此当备份

马大哈 发表于 2012-5-15 20:24:53

SystemDebugControl早已没用啦,可惜.

以前有些代码利用这个函数实现内核内存读写,隐藏进程等,后来微软把它给封了.

现在是只有用驱动了.{:soso_e101:}

diddom 发表于 2012-5-15 21:26:57

阿~~~~~~

lkd> uf 7c92de4e
7c92de4e b8ff000000      mov   eax,0FFh
7c92de53 ba0003fe7f      mov   edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92de58 ff12            call    dword ptr
7c92de5a c21800          ret   18h

watchsky 发表于 2012-5-16 18:43:39

貌似不好用了,不过还是感谢共享源码

liubin121051 发表于 2012-12-10 20:16:32

看看看看看看

DevilLiao 发表于 2013-1-11 16:31:08

win7应该没用了吧
页: [1]
查看完整版本: 老掉牙的无驱动恢复SSDT