看流星社区

 找回密码
 注册账号
查看: 2431|回复: 0

ShadowSSdt HOOK

[复制链接]

该用户从未签到

发表于 2017-6-1 13:33:10 | 显示全部楼层 |阅读模式
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;
//                 ULONG  ulSize;
//                 ULONG  ulByteReaded;

        __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 DWORD  rop4,
        IN DWORD  crBackColor,
        IN FLONG  fl
        ){
                DbgPrint("调用到了NtGdiBitBlt");
                return FALSE;
                return real_NtGdiBitBlt(
                        hdcDst,
                        x,
                        y,
                        cx,
                        cy,
                        hdcSrc,
                        xSrc,
                        ySrc,
                        rop4,
                        crBackColor,
                        fl
                        );

}
[/code]
#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
        );

typedef  BOOL (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 DWORD  rop4,
        IN DWORD  crBackColor,
        IN FLONG  fl
        );

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 DWORD  rop4,
        IN DWORD  crBackColor,
        IN FLONG  fl
        );
[/code]
防截屏实现:
#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[1];
}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 DWORD  rop4,
        IN DWORD  crBackColor,
        IN FLONG  fl
);

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 DWORD  rop4,
        IN DWORD  crBackColor,
        IN FLONG  fl
        )
{
        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[0x100];
       
    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[r].ObjectTypeNumber == 21) //Portobject
        {
            InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL,NULL);
                       
            cid.UniqueProcess= (HANDLE)Handles->Information[r].ProcessId;
                       
            cid.UniqueThread= 0;
                       
            if (NT_SUCCESS(NtOpenProcess(&amprocess,PROCESS_DUP_HANDLE, &obj, &cid)))
            {
                if (NT_SUCCESS(ZwDuplicateObject(Process,(HANDLE)Handles->Information[r].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[r].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[13], (ULONG)OldNtGdiBitBlt);
                        InterlockedExchange(&KeServiceDescriptorTableShadow->ServiceTableBase[292], (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[13], (ULONG)hook_NtGdiBitBlt);
                                OldNtGdiStretchBlt = (REAL_NtGdiStretchBlt)InterlockedExchange(&KeServiceDescriptorTableShadow->ServiceTableBase[292], (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;
}[/code]
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 15:00

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表