现在的位置: 首页 > 综合 > 正文

SSDT UnHook For C

2013年05月18日 ⁄ 综合 ⁄ 共 5728字 ⁄ 字号 评论关闭
SSDT UnHook For C-翻译女王的代码,百分之80%的相似度,
Copy code

#include <ntddk.h>
#include "PE.h"

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

// 2个结构体
typedef struct _SYSTEM_MODULE
{
    ULONG    Reserved[2];
    ULONG    Base;
    ULONG    Size;
    ULONG    Flags;
    USHORT    Index;
    USHORT    Unknown;
    USHORT    LoadCount;
    USHORT    ModuleNameOffset;
    CHAR    ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG            uCount;
    SYSTEM_MODULE_INFORMATION    aSM[];
}MODULE_LIST,*PMODULE_LIST;

NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
    ULONG        SystemInformationClass,
    PVOID        SystemInformation,
    ULONG        SystemInformationLength,
    PULONG        ReturnLength
);

ULONG GetKernelBaseAddress(char* lpszModule)
{
    NTSTATUS nResult;
    ULONG ulNeededSize, uLoop, uKernelAddr;
    PMODULE_LIST pModuleList;
   
    uKernelAddr = 0;
    ZwQuerySystemInformation(11, &ulNeededSize, 0, &ulNeededSize);
    pModuleList = ExAllocatePool(NonPagedPool, ulNeededSize);
    nResult = ZwQuerySystemInformation(11, pModuleList, ulNeededSize, NULL);
   
    if (NT_SUCCESS(nResult))
    {
        //ntoskrnl is always first there
        uKernelAddr = pModuleList->aSM[0].Base;
        strcpy(lpszModule,"//SystemRoot//System32//");
        strcat(lpszModule,pModuleList->aSM[0].ModuleNameOffset+pModuleList->aSM[0].ImageName);
    }

    ExFreePool(pModuleList);

    return uKernelAddr;
}

ULONG RVAToRaw(PVOID lpBase,ULONG VirtualAddress)
{
    IMAGE_DOS_HEADER *pDosHeader;
    IMAGE_NT_HEADERS *pNtHeader;
    IMAGE_SECTION_HEADER *pSectionHeader;
    ULONG NumOfSections,uLoop;
    pDosHeader=(IMAGE_DOS_HEADER*)lpBase;
    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        return 0;
    pNtHeader=(IMAGE_NT_HEADERS*)((unsigned char*)lpBase+pDosHeader->e_lfanew);
    NumOfSections=pNtHeader->FileHeader.NumberOfSections;
    pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pNtHeader + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + pNtHeader->FileHeader.SizeOfOptionalHeader);
    VirtualAddress -= (ULONG)lpBase;
    for (uLoop=0;uLoop<NumOfSections;uLoop++)
    {
        pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pSectionHeader + sizeof(IMAGE_SECTION_HEADER) * uLoop);
        if(VirtualAddress>pSectionHeader->VirtualAddress&&VirtualAddress<pSectionHeader->VirtualAddress+pSectionHeader->SizeOfRawData)
        {
            ULONG Offset = VirtualAddress-pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;
            return Offset;
        }
    }
    return 0;
}

//服务停止时执行
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
    DbgPrint("DriverUnload!");
}

//StartService时调用
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
    NTSTATUS status=STATUS_SUCCESS;
    ULONG uKernelMoule,uImageBase,uSSDTCount,uSSDTBase,uSSDTRaw,uLoop,uOldAddress,uNewAddress;
    PULONG lpArraySSDT;
    char szKernelPath[256];
    ANSI_STRING aFileName;
    UNICODE_STRING uFileName;
    OBJECT_ATTRIBUTES ObjAttr;
    IO_STATUS_BLOCK ioStatus;
    FILE_POSITION_INFORMATION FilePos;
    HANDLE hFile;

    theDriverObject->DriverUnload=DriverUnload;
    // get system modules
    memset(szKernelPath,0,256);
    uKernelMoule = GetKernelBaseAddress(szKernelPath);
    uImageBase  = ((IMAGE_NT_HEADERS*)(uKernelMoule + ((IMAGE_DOS_HEADER*)uKernelMoule)->e_lfanew))->OptionalHeader.ImageBase;
    DbgPrint("Kernel ImageBase: 0x%.8X", uImageBase);
    DbgPrint("Kernel Base: 0x%.8X", uKernelMoule);
    DbgPrint("Kernel Module Path: %s", szKernelPath);
    //
    uSSDTCount = KeServiceDescriptorTable->ulNumberOfServices;
    uSSDTBase  = (ULONG)KeServiceDescriptorTable->pvSSDTBase;
    DbgPrint("SSDT BaseAddress: 0x%8X, SSDT Count: 0x%X", uSSDTBase, uSSDTCount);
    lpArraySSDT = ExAllocatePool(PagedPool, uSSDTCount * sizeof(ULONG));
    if (lpArraySSDT == NULL) return status;
    //计算SSDT数组的文件偏移
    uSSDTRaw = RVAToRaw(uKernelMoule, uSSDTBase);
    DbgPrint("SSDT RAW: 0x%.8X", uSSDTRaw);
    if (uSSDTRaw == 0)
    {
        DbgPrint("SSDT RAW Error");
        ExFreePool(lpArraySSDT);
        return status;
    }
    RtlInitAnsiString(&aFileName,szKernelPath);
    status = RtlAnsiStringToUnicodeString(&uFileName, &aFileName, TRUE);
    if(!NT_SUCCESS(status))
    {
        DbgPrint("RtlAnsiStringToUnicodeString Error");
        ExFreePool(lpArraySSDT);
        return status;
    }

    InitializeObjectAttributes(&ObjAttr, &uFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
    status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjAttr, &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT);
    if (NT_SUCCESS(status) && hFile)
    {
        FilePos.CurrentByteOffset.LowPart = uSSDTRaw;//1000;//uSSDTRaw;
        FilePos.CurrentByteOffset.HighPart = 0;
        status = ZwSetInformationFile(hFile, &ioStatus, &FilePos, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
        if (NT_SUCCESS(status))
        {
            status = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, lpArraySSDT, uSSDTCount * sizeof(ULONG), NULL, NULL);
            if (NT_SUCCESS(status))
            {
                for (uLoop=0; uLoop<uSSDTCount; uLoop++)
                {
                    uOldAddress = *(lpArraySSDT + uLoop) - uImageBase + uKernelMoule;
                    uNewAddress = *((PULONG)uSSDTBase + uLoop);
                    if (uOldAddress != uNewAddress)
                    {
                        DbgPrint("SSDT No.%X, Old: 0x%.8X, New: 0x%.8X", uLoop, uOldAddress, uNewAddress);
/*                        __asm
                        {//关中断
                            cli
                            mov eax,cr0
                            and eax,~0x10000
                            mov cr0,eax
                        }
                        *((PULONG)uSSDTBase + uLoop) = uOldAddress;
                        //fast_InterlockedExchange(*(uSSDTBase + uLoop), uOldAddress);
                        __asm
                        {//开中断
                            mov  eax,cr0
                            or  eax,0x10000
                            mov  cr0,eax
                            sti
                        }
*/
                    }
                }
                DbgPrint("SSDT TheEnd...");

            }
            else
                DbgPrint("Read File Error!");
        }
//        else
//            DbgPrint("Set File Pos Error!");
        if(hFile)
            ZwClose(hFile);
    }
    else
        DbgPrint("Open File Error!");
   
    RtlFreeUnicodeString(&uFileName);

    ExFreePool(lpArraySSDT);
    return status;
}

抱歉!评论已关闭.