蓝色的忧郁 发表于 2017-6-1 13:33:10

ShadowSSdt HOOK

SHADOW表地址的获取。
CSRSS进程。system进程并没有载入win32k.sys,所以,要访问shadowssdt表,必须KeStackAttackProces到一个有GUI线程的进程中,而csrss.exe就是这样的一个合适的进程(管理Windows图形相关任务)
Index?硬编码
挂钩NtGdiBitBlt、NtGdiStretchBlt用于截屏保护
挂钩NtUserSetWindowsHookEx 保护键盘钩子
6932607
7735483


代码:
#include "ShadowSsdt.h"

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
        unsigned int *ServiceTableBase;
        unsigned int *ServiceCounterTableBase; //Used only in checked build
        unsigned int NumberOfServices;
        unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport)ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

REAL_NtGdiStretchBlt real_NtGdiStretchBlt;

REAL_NtGdiBitBlt real_NtGdiBitBlt;

ULONG GetAddressOfShadowTable()
{
        ULONG i;
        UCHAR* p;
        ULONG dwordatbyte;

        UNICODE_STRING usKeAddSystemServiceTable;

        RtlInitUnicodeString(&usKeAddSystemServiceTable, L"KeAddSystemServiceTable");

        p = (UCHAR*)MmGetSystemRoutineAddress(&usKeAddSystemServiceTable);

        for (i = 0; i < 4096; i++,p++)
        {
                __try
                {
                        dwordatbyte = *(ULONG*)p;
                }__except(EXCEPTION_EXECUTE_HANDLER)
                {
                        return 0;
                }

                if(MmIsAddressValid((PVOID)dwordatbyte))
                {
                        if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0)    //比较的是地址指向的内容
                        {
                                if((PVOID)dwordatbyte == &KeServiceDescriptorTable)
                                {
                                        continue;
                                }
                                return dwordatbyte;
                        }
                }
        }
        return 0;
}


PDWORD NtGdiStretchBltAddr;
PDWORD NtGdiBitBltAddr;
BOOL flag = FALSE;
void StartHookShadow (void)
{
        DWORD SSDTShadowBaseAddr=GetAddressOfShadowTable()+0x10;//表基址所在地址
        DWORD TableCount=SSDTShadowBaseAddr+0x8;//函数数量所在地址
        DWORD dwCount=*((PDWORD)TableCount);
        PDWORD Fun_Addr=(PDWORD)(*((PDWORD)SSDTShadowBaseAddr));
       
        KdPrint(("ssdt shadow addr:0x%X= 0x%X= 0x%X",SSDTShadowBaseAddr,
                *(PDWORD)SSDTShadowBaseAddr,Fun_Addr));
        KdPrint(("数量是:%d",dwCount));
        if (!MmIsAddressValid(Fun_Addr))
        {
                KdPrint(("Fun_Addr地址不可访问%X!",Fun_Addr));
                return;
        }
        NtGdiStretchBltAddr=Fun_Addr+292;
        NtGdiBitBltAddr=Fun_Addr+13;
        KdPrint(("NtGdiStretchBltAddr:%X",NtGdiStretchBltAddr));
        KdPrint(("NtGdiBitBltAddr:%X",NtGdiBitBltAddr));
        //Fun_Addr是KeServiceDescriptorTable表的首地址,但是一用*Fun_Addr就出现0x50的蓝屏代码
        //0x50 PAGE_FAULT_IN_NONPAGED_AREA Parameters 分页内存读取错误,但是这里没分配分页内存呢。
        KdPrint(("*Fun_Addr:%X",*Fun_Addr));


        //保存原函数地址,SSDT HOOK是根据ZW函数地址硬编码得出的索引得到的函数地址
        real_NtGdiStretchBlt=(REAL_NtGdiStretchBlt)(*NtGdiStretchBltAddr);
        real_NtGdiBitBlt=(REAL_NtGdiBitBlt)(*NtGdiBitBltAddr);
       
       
        KdPrint(("NtGdiStretchBlt原函数地址:%08X\n",*NtGdiStretchBltAddr));
        KdPrint(("NtGdiStretchBlt新函数地址:%08X\n",HOOK_NtGdiStretchBlt));
        KdPrint(("NtGdiBitBlt原函数地址:%08X\n",*NtGdiBitBltAddr));
        KdPrint(("NtGdiBitBlt新函数地址:%08X\n",HOOK_NtGdiBitBlt));
//         获取未导出的服务函数索引号
//                 HANDLE    hFile;
//                 PCHAR    pDllFile;
//                 ULONGulSize;
//                 ULONGulByteReaded;

        __asm
        {
                push    eax
                        mov      eax, CR0
                        and      eax, 0FFFEFFFFh
                        mov      CR0, eax
                        pop      eax
        }

        InterlockedExchange((PLONG)NtGdiStretchBltAddr, (LONG)HOOK_NtGdiStretchBlt);
        InterlockedExchange((PLONG)NtGdiBitBltAddr, (LONG)HOOK_NtGdiBitBlt);

        //关闭
        __asm
        {
                push    eax
                        mov      eax, CR0
                        or      eax, NOT 0FFFEFFFFh
                        mov      CR0, eax
                        pop      eax
        }
        flag = TRUE;
        return ;
}

void RemoveHookShadow (void)
{
        if (!flag)
        {
                return;
        }
       
        __asm
        {
                push    eax
                        mov      eax, CR0
                        and      eax, 0FFFEFFFFh
                        mov      CR0, eax
                        pop      eax
        }
        InterlockedExchange( (PLONG) NtGdiStretchBltAddr,(LONG) real_NtGdiStretchBlt);
        InterlockedExchange( (PLONG) NtGdiBitBltAddr,(LONG) real_NtGdiBitBlt);
        __asm
        {
                push    eax
                        mov      eax, CR0
                        or      eax, NOT 0FFFEFFFFh
                        mov      CR0, eax
                        pop      eax
        }
}



BOOL NTAPI HOOK_NtGdiStretchBlt//293
        (
        IN HDC   hdcDst,
        IN int   xDst,
        IN int   yDst,
        IN int   cxDst,
        IN int   cyDst,
        IN HDC   hdcSrc,
        IN int   xSrc,
        IN int   ySrc,
        IN int   cxSrc,
        IN int   cySrc,
        IN DWORD dwRop,
        IN DWORD dwBackColor
        ){
                DbgPrint("调用到了NtGdiStretchBlt");
                return FALSE;
                return real_NtGdiStretchBlt(
                        hdcDst,
                        xDst,
                        yDst,
                        cxDst,
                        cyDst,
                        hdcSrc,
                        xSrc,
                        ySrc,
                        cxSrc,
                        cySrc,
                        dwRop,
                        dwBackColor
                        );
}

BOOL NTAPI HOOK_NtGdiBitBlt//14
        (
        IN HDC    hdcDst,
        IN int    x,
        IN int    y,
        IN int    cx,
        IN int    cy,
        IN HDC    hdcSrc,
        IN int    xSrc,
        IN int    ySrc,
        IN DWORDrop4,
        IN DWORDcrBackColor,
        IN FLONGfl
        ){
                DbgPrint("调用到了NtGdiBitBlt");
                return FALSE;
                return real_NtGdiBitBlt(
                        hdcDst,
                        x,
                        y,
                        cx,
                        cy,
                        hdcSrc,
                        xSrc,
                        ySrc,
                        rop4,
                        crBackColor,
                        fl
                        );

}

#include <ntddk.h>
#include <ntstrsafe.h>
#include <windef.h>

//#include <WTypes.h>
void StartHookShadow (void);
void RemoveHookShadow (void);


typedef BOOL (NTAPI *REAL_NtGdiStretchBlt)//293
        (
        IN HDC   hdcDst,
        IN int   xDst,
        IN int   yDst,
        IN int   cxDst,
        IN int   cyDst,
        IN HDC   hdcSrc,
        IN int   xSrc,
        IN int   ySrc,
        IN int   cxSrc,
        IN int   cySrc,
        IN DWORD dwRop,
        IN DWORD dwBackColor
        );

BOOL NTAPI HOOK_NtGdiStretchBlt//293
        (
        IN HDC   hdcDst,
        IN int   xDst,
        IN int   yDst,
        IN int   cxDst,
        IN int   cyDst,
        IN HDC   hdcSrc,
        IN int   xSrc,
        IN int   ySrc,
        IN int   cxSrc,
        IN int   cySrc,
        IN DWORD dwRop,
        IN DWORD dwBackColor
        );

typedefBOOL (NTAPI *REAL_NtGdiBitBlt)//14
        (
        IN HDC    hdcDst,
        IN int    x,
        IN int    y,
        IN int    cx,
        IN int    cy,
        IN HDC    hdcSrc,
        IN int    xSrc,
        IN int    ySrc,
        IN DWORDrop4,
        IN DWORDcrBackColor,
        IN FLONGfl
        );

BOOL NTAPI HOOK_NtGdiBitBlt//14
        (
        IN HDC    hdcDst,
        IN int    x,
        IN int    y,
        IN int    cx,
        IN int    cy,
        IN HDC    hdcSrc,
        IN int    xSrc,
        IN int    ySrc,
        IN DWORDrop4,
        IN DWORDcrBackColor,
        IN FLONGfl
        );

防截屏实现:
#include <ntifs.h>
#include <ntddk.h>
#include <WINDEF.H>

#define SystemHandleInformation 16
#define ObjectNameInformation 1

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG            ProcessId;
    UCHAR            ObjectTypeNumber;
    UCHAR            Flags;
    USHORT          Handle;
    PVOID            Object;
    ACCESS_MASK      GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
        ULONG NumberOfHandles;
        SYSTEM_HANDLE_INFORMATION Information;
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase; //Used only in checked build
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport)ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

PServiceDescriptorTableEntry_t KeServiceDescriptorTableShadow = NULL;

NTKERNELAPI NTSTATUS ZwQuerySystemInformation(
                                                                                          IN ULONG SystemInformationClass,
                                                                                          OUT PVOID            SystemInformation,
                                                                                          IN ULONG                SystemInformationLength,
OUT PULONG            ReturnLength OPTIONAL );

typedef BOOL (NTAPI *REAL_NtGdiStretchBlt)
(
        IN HDC   hdcDst,
        IN int   xDst,
        IN int   yDst,
        IN int   cxDst,
        IN int   cyDst,
        IN HDC   hdcSrc,
        IN int   xSrc,
        IN int   ySrc,
        IN int   cxSrc,
        IN int   cySrc,
        IN DWORD dwRop,
        IN DWORD dwBackColor
);

typedef BOOL (NTAPI *REAL_NtGdiBitBlt)
(
        IN HDC    hdcDst,
        IN int    x,
        IN int    y,
        IN int    cx,
        IN int    cy,
        IN HDC    hdcSrc,
        IN int    xSrc,
        IN int    ySrc,
        IN DWORDrop4,
        IN DWORDcrBackColor,
        IN FLONGfl
);

REAL_NtGdiStretchBlt OldNtGdiStretchBlt;
REAL_NtGdiBitBlt OldNtGdiBitBlt = NULL;

BOOL NTAPI hook_NtGdiStretchBlt(
        IN HDC   hdcDst,
        IN int   xDst,
        IN int   yDst,
        IN int   cxDst,
        IN int   cyDst,
        IN HDC   hdcSrc,
        IN int   xSrc,
        IN int   ySrc,
        IN int   cxSrc,
        IN int   cySrc,
        IN DWORD dwRop,
        IN DWORD dwBackColor
        )
{
        return TRUE;
        //DbgPrint("hook_NtGdiStretchBlt:%d", hdcDst);

        return OldNtGdiStretchBlt(
                hdcDst,
                xDst,
                yDst,
                cxDst,
                cyDst,
                hdcSrc,
                xSrc,
                ySrc,
                cxSrc,
                cySrc,
                dwRop,
                dwBackColor
        );
}

BOOL NTAPI hook_NtGdiBitBlt(
        IN HDC    hdcDst,
        IN int    x,
        IN int    y,
        IN int    cx,
        IN int    cy,
        IN HDC    hdcSrc,
        IN int    xSrc,
        IN int    ySrc,
        IN DWORDrop4,
        IN DWORDcrBackColor,
        IN FLONGfl
        )
{
        PEPROCESS pe = NULL;
        PCHAR pProcessName = NULL;
        PCHAR pIgnorePocess = "explorer.exe";

        pe = PsGetCurrentProcess();

        pProcessName = (PCHAR)((ULONG)pe + 0x174);

        if (RtlCompareMemory(pProcessName, pIgnorePocess, strlen(pIgnorePocess)) == strlen(pIgnorePocess))
        {
                return OldNtGdiBitBlt(
                        hdcDst,
                        x,
                        y,
                        cx,
                        cy,
                        hdcSrc,
                        xSrc,
                        ySrc,
                        rop4,
                        crBackColor,
                        fl
                );
        }

        return TRUE;
}

PVOID GetInfoTable(ULONG ATableType)
{
        ULONG mSize = 0x4000;
    PVOID mPtr = NULL;
    NTSTATUS St;
       
    do
    {
      mPtr = ExAllocatePoolWithTag(PagedPool, mSize, 'GIT');
      memset(mPtr, 0,mSize);
               
      if (mPtr)
      {
            St = ZwQuerySystemInformation(ATableType, mPtr,mSize, NULL);
      } else return NULL;
               
      if (St == STATUS_INFO_LENGTH_MISMATCH)
      {
            ExFreePool(mPtr);
                       
            mSize = mSize *2;
      }
               
    } while (St == STATUS_INFO_LENGTH_MISMATCH);
       
    if (St == STATUS_SUCCESS) return mPtr;
       
    ExFreePoolWithTag(mPtr, 'GIT');
       
    return NULL;
}

HANDLE GetCsrPid()
{
    HANDLE Process,hObject;
       
    HANDLE CsrId =(HANDLE)0;
       
    OBJECT_ATTRIBUTES obj;
       
    CLIENT_ID cid;
       
    UCHAR Buff;
       
    POBJECT_NAME_INFORMATION ObjName= (PVOID)&Buff;
       
    PSYSTEM_HANDLE_INFORMATION_EX Handles;
       
    ULONG r;
       
    Handles = GetInfoTable(SystemHandleInformation);
       
    if (!Handles) return CsrId;
       
    for (r = 0; r < Handles->NumberOfHandles; r++)
    {
      if (Handles->Information.ObjectTypeNumber == 21) //Portobject
      {
            InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL,NULL);
                       
            cid.UniqueProcess= (HANDLE)Handles->Information.ProcessId;
                       
            cid.UniqueThread= 0;
                       
            if (NT_SUCCESS(NtOpenProcess(&Process,PROCESS_DUP_HANDLE, &obj, &cid)))
            {
                if (NT_SUCCESS(ZwDuplicateObject(Process,(HANDLE)Handles->Information.Handle,NtCurrentProcess(),&hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
                {
                                        if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation,ObjName, 0x100, NULL)))
                  {
                        if (ObjName->Name.Buffer&& !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
                        {
                            CsrId = (HANDLE)Handles->Information.ProcessId;
                        }
                  }
                  ZwClose(hObject);
                }
                ZwClose(Process);
            }
      }
    }
       
    ExFreePool(Handles);
       
    return CsrId;
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
        NTSTATUS ntStatus = STATUS_SUCCESS;
        PEPROCESS crsProcess = NULL;
       
        if (OldNtGdiBitBlt && OldNtGdiStretchBlt && KeServiceDescriptorTableShadow)
        {
                ntStatus = PsLookupProcessByProcessId(GetCsrPid(),&crsProcess);
               
                if (NT_SUCCESS(ntStatus))
                {
                        KeAttachProcess(crsProcess);
                       
                        __asm
                        {
                                push    eax
                                        mov      eax, CR0
                                        and      eax, 0FFFEFFFFh
                                        mov      CR0, eax
                                        pop      eax
                        }
                       
                        InterlockedExchange(&KeServiceDescriptorTableShadow->ServiceTableBase, (ULONG)OldNtGdiBitBlt);
                        InterlockedExchange(&KeServiceDescriptorTableShadow->ServiceTableBase, (ULONG)OldNtGdiStretchBlt);
                       
                        __asm
                        {
                                push    eax
                                        mov      eax, CR0
                                        or      eax, NOT 0FFFEFFFFh
                                        mov      CR0, eax
                                        pop      eax
                        }
                }
        }
}

NTSTATUS HookssdtShadow()
{
        NTSTATUS ntStatus = STATUS_SUCCESS;
        ULONG BuildNumber= 0;
    ULONG MinorVersion = 0;
    ULONG MajorVersion = 0;
        PEPROCESS crsProcess = NULL;
       
    PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);

        DbgPrint("%d", BuildNumber);       

        if (BuildNumber == 2600) //XP
        {
                KeServiceDescriptorTableShadow = (PServiceDescriptorTableEntry_t)((ULONG)&KeServiceDescriptorTable - 0x40 + 0x10);

                DbgPrint("%d", KeServiceDescriptorTableShadow);       
               
                if (KeServiceDescriptorTableShadow)
                {
                        ntStatus = PsLookupProcessByProcessId(GetCsrPid(),&crsProcess);

                        if (NT_SUCCESS(ntStatus))
                        {
                                KeAttachProcess(crsProcess);
                               
                                __asm
                                {
                                        push    eax
                                                mov      eax, CR0
                                                and      eax, 0FFFEFFFFh
                                                mov      CR0, eax
                                                pop      eax
                                }
                               
                                OldNtGdiBitBlt = (REAL_NtGdiBitBlt)InterlockedExchange(&KeServiceDescriptorTableShadow->ServiceTableBase, (ULONG)hook_NtGdiBitBlt);
                                OldNtGdiStretchBlt = (REAL_NtGdiStretchBlt)InterlockedExchange(&KeServiceDescriptorTableShadow->ServiceTableBase, (ULONG)hook_NtGdiStretchBlt);
                               
                                __asm
                                {
                                        push    eax
                                                mov      eax, CR0
                                                or      eax, NOT 0FFFEFFFFh
                                                mov      CR0, eax
                                                pop      eax
                                }
                        }
                }
        }

        return ntStatus;
}


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
        pDriverObject->DriverUnload = DriverUnload;

        HookssdtShadow();
       
        return STATUS_SUCCESS;
}
页: [1]
查看完整版本: ShadowSSdt HOOK