SHADOW表地址的获取。
CSRSS进程。system进程并没有载入win32k.sys,所以,要访问shadowssdt表,必须KeStackAttackProces到一个有GUI线程的进程中,而csrss.exe就是这样的一个合适的进程(管理Windows图形相关任务)
Index?硬编码
挂钩NtGdiBitBlt、NtGdiStretchBlt用于截屏保护
挂钩NtUserSetWindowsHookEx 保护键盘钩子
http://blog.csdn.net/evi10r/article/details/6932607
http://blog.csdn.net/lionzl/article/details/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
-
);
-
}
-
#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
-
);
防截屏实现:
-
#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(&Process,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;
-
}