- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
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(&rocess,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] |
|