S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

SSDT原始地址,现在地址

Posted on 2009-10-26 13:45 S.l.e!ep.¢% 阅读(992) 评论(0)  编辑 收藏 引用 所属分类: RootKit

#include <windows.h>

#include <winnt.h>

#include <WindowsX.h>

#include <commctrl.h>

#include <stdio.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;

}

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

// 搜索函数名称

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

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 (int i=0;i<(int)(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 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;

                        }

                    }

                   

                }

     // should never get here

            }

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

        }

    }   

   

    return 0;

}

DWORD    dwKSDT;                // rva of KeServiceDescriptorTable

DWORD    dwKiServiceTable;    // rva of KiServiceTable

DWORD    dwKernelBase,dwServices=0;

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

void GetSSDT()

{    

    HMODULE    hKernel;

    PCHAR    pKernelName;

    PDWORD    pService;

    PIMAGE_FILE_HEADER    pfh;

    PIMAGE_OPTIONAL_HEADER    poh;

    PIMAGE_SECTION_HEADER    psh;

ULONG n;

    // get system modules - ntoskrnl is always first there

    ZwQuerySystemInformation(SystemModuleInformation,&n,0,&n);

PULONG p=new ULONG[n];

    ZwQuerySystemInformation(SystemModuleInformation,p,n*sizeof(*p),0);

PSYSTEM_MODULE_INFORMATION module=PSYSTEM_MODULE_INFORMATION(p+1);

    // imagebase

    dwKernelBase=(DWORD)module->Base;

    // filename - it may be renamed in the boot.ini

    pKernelName=module->ModuleNameOffset+module->ImageName;

   

    // map ntoskrnl - hopefully it has relocs

    hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES);

    if (!hKernel) {

        return;

    }

    // our own export walker is useless here - we have GetProcAddress :)

    if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable"))) {

        return;

    }

    // get KeServiceDescriptorTable rva

    dwKSDT-=(DWORD)hKernel;

    // find KiServiceTable

    if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT))) {

        return;

    }

    // 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);

    dwServices=0;

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

*pService-poh->ImageBase<poh->SizeOfImage;

pService++,dwServices++)

{

   ssdt_list[dwServices].address1=*pService-poh->ImageBase+dwKernelBase;

}

FreeLibrary(hKernel);

//读取现在的

MEMORY_CHUNKS QueryBuff;

DWORD *address2=new DWORD[dwServices];

QueryBuff.Address = dwKernelBase+dwKiServiceTable;

QueryBuff.Data = address2;

QueryBuff.Length = sizeof(DWORD)*dwServices;

DWORD ReturnLength;

ZwSystemDebugControl

   (

   SysDbgReadVirtualMemory,

   &QueryBuff,

   sizeof(MEMORY_CHUNKS),

   NULL,

   0,

   &ReturnLength

   );

LV_ITEM lvi;

lvi.mask = LVIF_TEXT;

char tmp[10];

ListView_DeleteAllItems(hList);

for (int j=0;j<(int)dwServices;j++)

{

   lvi.iItem=j;

   lvi.iSubItem=0;

   lvi.pszText=tmp;

   wsprintf(tmp,"0x%02X",j);

   ListView_InsertItem(hList,&lvi);

   ListView_SetItemText(hList,j,1,ssdt_list[j].fname);

   wsprintf(tmp,"0x%08X",ssdt_list[j].address1);

   ListView_SetItemText(hList,j,2,tmp);

   wsprintf(tmp,"0x%08X",address2[j]);

   ssdt_list[j].address2=address2[j];

   ListView_SetItemText(hList,j,3,tmp);

  

   //搜索模块

   for (int i=0;i<(int)*p;i++)

   {

    if (ssdt_list[j].address2 > ( DWORD)module[i].Base&&ssdt_list[j].address2 < (DWORD)module[i].Base + module[i].Size )

    {

     ListView_SetItemText(hList,j,4,module[i].ImageName);

     break;

    }

   }

}

   

delete [] p;

delete [] address2;

}

int main()

{

ssdt_list=new SSDT_LIST_ENTRY[500];

LocateNtdllEntry();

FindExport();

DebugPrivilege (SE_DEBUG_NAME,TRUE);

GetSSDT();

//恢复SSDT

DWORD *address1=new DWORD[dwServices];

for (int i=0;i<(int)dwServices;i++)

{

   //address1[i]=ssdt_list[i].address1;

   printf("原始地址:0x%08X,现在地址:0x%08X,SSDTName=%s\n",ssdt_list[i].address1,ssdt_list[i].address2,ssdt_list[i].fname);

}

MEMORY_CHUNKS QueryBuff;

QueryBuff.Address=dwKiServiceTable+dwKernelBase;

QueryBuff.Data=address1;

QueryBuff.Length=dwServices*sizeof(DWORD);

DWORD ReturnLength;

ZwSystemDebugControl

   (

   SysDbgWriteVirtualMemory,

   &QueryBuff,

   sizeof(MEMORY_CHUNKS),

   NULL,

   0,

   &ReturnLength

   );

printf("恢复SSDT成功!\n");

// system("pause");

return 0;

}


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理