ShadowSSdt HOOK

本文详细介绍了ShadowSSDT技术,这是一种内核级别的防截屏方法,通过修改系统服务调度表(SSDT)创建阴影表来隐藏关键函数,增加了恶意软件检测的难度。内容包括ShadowSSDT的工作原理、实现过程及其在保护系统安全方面的应用。
摘要由CSDN通过智能技术生成
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&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值