遍历 shadowssdt表 函数名地址

#include <ntifs.h>
#include <ntimage.h>
//#include "ntddk.h"    
//SSDT结构体  
typedef struct _SERVICE_DESCRIPTOR_TABLE {
	PULONG   ServiceTable;
	PULONG  CounterTable;
	ULONG   TableSize;
	PUCHAR  ArgumentTable;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorShadowTable;
typedef enum WIN_VER_DETAIL {
	WINDOWS_VERSION_NONE,       //  0
	WINDOWS_VERSION_2K,
	WINDOWS_VERSION_XP,
	WINDOWS_VERSION_2K3,
	WINDOWS_VERSION_2K3_SP1_SP2,
	WINDOWS_VERSION_VISTA_2008,
	WINDOWS_VERSION_7_7600_UP,
	WINDOWS_VERSION_7_7000
} WIN_VER_DETAIL;
WIN_VER_DETAIL WinVersion;
WIN_VER_DETAIL GetWindowsVersion();
__declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);
UCHAR *PsGetProcessImageFileName(__in PEPROCESS eprocess);
VOID MyUnload(PDRIVER_OBJECT    pDriverObject)
{
	KdPrint(("驱动卸载成功\n"));
}

PVOID GetShadowTableAddress()
{
	ULONG dwordatbyte, i;
	PUCHAR p = (PUCHAR)KeAddSystemServiceTable;
	for (i = 0; i < 0x1024; i++, p++)// 往下找一页 指针递增1 
	{
		__try
		{
			dwordatbyte = *(PULONG)p;
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
			return FALSE;
		}
		if (MmIsAddressValid((PVOID)dwordatbyte))
		{
			if (memcmp((PVOID)dwordatbyte, KeServiceDescriptorTable, 16) == 0)//对比前16字节 相同则找到
			{
				if ((PVOID)dwordatbyte == KeServiceDescriptorTable)//排除自己
				{
					continue;
				}
				return (PVOID)dwordatbyte;
			}
		}
	}
	return FALSE;
}
WIN_VER_DETAIL GetWindowsVersion()
{
	RTL_OSVERSIONINFOEXW	osverinfo;
	if (WinVersion)
		return WinVersion;
	memset(&osverinfo, 0, sizeof(RTL_OSVERSIONINFOEXW));
	osverinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
	if (RtlGetVersion((RTL_OSVERSIONINFOW*)&osverinfo) != STATUS_SUCCESS){
		return WINDOWS_VERSION_NONE;
	}
	// 	KdPrint(("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n", 
	// 		osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber, 
	// 		osverinfo.wServicePackMajor, osverinfo.wServicePackMinor));

	if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0){
		WinVersion = WINDOWS_VERSION_2K;
	}
	else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1){
		WinVersion = WINDOWS_VERSION_XP;
	}
	else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2){
		if (osverinfo.wServicePackMajor == 0){
			WinVersion = WINDOWS_VERSION_2K3;
		}
		else{
			WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
		}
	}
	else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0){
		WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
	}
	else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber == 7000){
		WinVersion = WINDOWS_VERSION_7_7000;
	}
	else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber >= 7600){
		WinVersion = WINDOWS_VERSION_7_7600_UP;
	}
	return WinVersion;
}
NTSTATUS LookupProcessByName(IN PCHAR pcProcessName,OUT PEPROCESS *pEprocess)
{
	NTSTATUS	status;
	ULONG		uCount = 0;
	ULONG		uLength = 0;
	PLIST_ENTRY	pListActiveProcess;
	PEPROCESS	pCurrentEprocess = NULL;
	ULONG ulNextProcess = 0;
	ULONG g_Offset_Eprocess_Flink;
	WIN_VER_DETAIL WinVer;
	char lpszProName[100];
	char *lpszAttackProName = NULL;
	if (!ARGUMENT_PRESENT(pcProcessName) || !ARGUMENT_PRESENT(pEprocess))
	{
		return STATUS_INVALID_PARAMETER;
	}
	if (KeGetCurrentIrql() > PASSIVE_LEVEL)
	{
		return STATUS_UNSUCCESSFUL;
	}
	uLength = strlen(pcProcessName);

	WinVer = GetWindowsVersion();
	switch (WinVer)
	{
	case WINDOWS_VERSION_XP:
		g_Offset_Eprocess_Flink = 0x88;
		break;
	case WINDOWS_VERSION_7_7600_UP:
	case WINDOWS_VERSION_7_7000:
		g_Offset_Eprocess_Flink = 0xb8;
		break;
	case WINDOWS_VERSION_VISTA_2008:
		g_Offset_Eprocess_Flink = 0x0a0;
		break;
	case WINDOWS_VERSION_2K3_SP1_SP2:
		g_Offset_Eprocess_Flink = 0x98;
		break;
	case WINDOWS_VERSION_2K3:
		g_Offset_Eprocess_Flink = 0x088;
		break;
	}
	if (!g_Offset_Eprocess_Flink){
		return STATUS_UNSUCCESSFUL;
	}
	pCurrentEprocess = PsGetCurrentProcess();
	ulNextProcess = (ULONG)pCurrentEprocess;
	__try
	{
		memset(lpszProName, 0, sizeof(lpszProName));
		if (uLength > 15)
		{
			strncat(lpszProName, pcProcessName, 15);
		}
		while (1)
		{
			lpszAttackProName = NULL;
			lpszAttackProName = (char *)PsGetProcessImageFileName(pCurrentEprocess);

			if (uLength > 15)
			{
				if (lpszAttackProName &&
					strlen(lpszAttackProName) == uLength)
				{
					if (_strnicmp(lpszProName, lpszAttackProName, uLength) == 0)
					{
						*pEprocess = pCurrentEprocess;
						status = STATUS_SUCCESS;
						break;
					}
				}
			}
			else
			{
				if (lpszAttackProName &&
					strlen(lpszAttackProName) == uLength)
				{
					if (_strnicmp(pcProcessName, lpszAttackProName, uLength) == 0)
					{
						*pEprocess = pCurrentEprocess;
						status = STATUS_SUCCESS;
						break;
					}
				}
			}
			if ((uCount >= 1) && (ulNextProcess == (ULONG)pCurrentEprocess))
			{
				*pEprocess = 0x00000000;
				status = STATUS_NOT_FOUND;
				break;
			}
			pListActiveProcess = (LIST_ENTRY *)((ULONG)pCurrentEprocess + g_Offset_Eprocess_Flink);
			(ULONG)pCurrentEprocess = (ULONG)pListActiveProcess->Flink;
			(ULONG)pCurrentEprocess = (ULONG)pCurrentEprocess - g_Offset_Eprocess_Flink;
			uCount++;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		KdPrint(("LookupProcessByName:%08x\r\n", GetExceptionCode()));
		status = STATUS_NOT_FOUND;
	}
	return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING Reg_Path)
{
	int i = 0;
	PEPROCESS eprocess_explorer;
	pDriverObject->DriverUnload = MyUnload;
	KeServiceDescriptorShadowTable = GetShadowTableAddress();
	if (KeServiceDescriptorShadowTable)
	{
		//我们得到一个gui进程的对象,因为我们切换进程的时候需要用到
		if (LookupProcessByName("explorer.exe", &eprocess_explorer) == STATUS_SUCCESS)
		{
			KeAttachProcess(eprocess_explorer);//附加到目标进程
			//这里为什么要KeServiceDescriptorShadowTable[1],正如我们所说的,第二个表才是ShadowSSDT
			int j = KeServiceDescriptorShadowTable[1].TableSize;
			for (i = 0; i < j; i++)
			{
				DbgPrint("Number:%d  Address:0x%08X\r\n", i, KeServiceDescriptorShadowTable[1].ServiceTable[i]);
			}

			KeDetachProcess();//解除附加		
		}
	}
	return STATUS_SUCCESS;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本实例由VS2008开发,在提供了一套驱动开发框架的同时,又演示了如何获取Shadow SSDT函数原始地址的办法。 主要函数:ULONG GetShadowSSDT_Function_OriAddr(ULONG index); 原理说明: 根据特征码搜索导出函数KeAddSystemServiceTable来获取Shadow SSDT基址,以及通过ZwQuerySystemInformation()函数获取win32k.sys基址,然后解析PE定位到Shadow SSDT在win32k.sys的偏移地址,并通过进一步计算来得到Shadow SSDT函数的原始地址。 这里只测试了三个函数:(460)NtUserMessageCall、(475)NtUserPostMessage和(502)NtUserSendInput,具体使用时可以举一反三,网上完整的源代码实例并不太多,希望可以帮到真正有需要的朋友。 系统环境: 在WinXP SP3系统 + 瑞星杀毒软件 打印输出: [ LemonInfo : Loading Shadow SSDT Original Address Driver... ] [ LemonInfo : 创建“设备”值为:0 ] [ LemonInfo : 创建“设备”成功... ] [ LemonInfo : 创建“符号链接”状态值为:0 ] [ LemonInfo : 创建“符号链接”成功... ] [ LemonInfo : 驱动加载成功... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 开始... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP Enter IRP_MJ_DEVICE_CONTROL... ] [ LemonInfo : 获取ShadowSSDT (460)NtUserMessageCall 函数的“当前地址”为:0xB83ECFC4,“起源地址”为:0xBF80EE6B ] [ LemonInfo : 获取ShadowSSDT (475)NtUserPostMessage 函数的“当前地址”为:0xB83ECFA3,“起源地址”为:0xBF8089B4 ] [ LemonInfo : 获取ShadowSSDT (502)NtUserSendInput 函数的“当前地址”为:0xBF8C31E7,“起源地址”为:0xBF8C31E7 ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP_MJ_DEVICE_CONTROL 成功执行... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 结束... ] [ LemonInfo : UnLoading Shadow SSDT Original Address Driver... ] [ LemonInfo : 删除“符号链接”成功... ] [ LemonInfo : 删除“设备”成功... ] [ LemonInfo : 驱动卸载成功... ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值