SSDT_HOOK

分别从静态,动态两种方法来hook
静态是直接根据openProcess的调用号0xbe
动态是防止地址发生改变或者其他,来动态函数索引进而HOOK的

#include<ntifs.h>
#include<ntimage.h> //提供 PE结构

PULONG g_PageMapMemory = NULL;

typedef struct _SSDTItem {
	PULONG FunAddressTable;
	ULONG Pknum;
	ULONG uIndexCount;
	PCHAR pcParam;
}SSDTItem,*PSSDTItem;

//代表两张表的
typedef struct _RKSSDT {
	SSDTItem KernelItem;
	SSDTItem  GuiItem;
}RLSSDT,*PRSSDT;


//x86情况下,是根据名字来找到这张表的
EXTERN_C PRSSDT KeServiceDescriptorTable;

typedef NTSTATUS (NTAPI *rkOpenProcess)(//hook用来替换原来的函数,hook之后要还原,所以要保存一下类型
	 PHANDLE            ProcessHandle,
	 ACCESS_MASK        DesiredAccess,
	 POBJECT_ATTRIBUTES ObjectAttributes,
	 PCLIENT_ID         ClientId
);

rkOpenProcess NtOpenProcessOldFunAddr = NULL;

NTSTATUS NtOpenProcess(
	PHANDLE            ProcessHandle,
	ACCESS_MASK        DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes,
	PCLIENT_ID         ClientId
) {
	DbgPrint("你已被hook\n");
	return NtOpenProcessOldFunAddr(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}

//ntdll pe ssdt index
ULONG GetSSDTIndex(UNICODE_STRING usDllFileName,PCHAR pcFunctionName) {
	NTSTATUS ntStatus = STATUS_SUCCESS;
	HANDLE hFile = NULL;
	HANDLE hSection = NULL;//解析PE
	OBJECT_ATTRIBUTES objectAttr = { 0 };
	IO_STATUS_BLOCK ioStatus = { 0 };
	PVOID pBaseAddress = NULL;
	SIZE_T viewSize = 0;
	ULONG ulFunctionIndex = 0;
	//初始化对象
	InitializeObjectAttributes(&objectAttr, &usDllFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	//打开对象
	ntStatus = ZwOpenFile(&hFile, GENERIC_READ, &objectAttr, &ioStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
	if (!NT_SUCCESS(ntStatus))
	{
		DbgPrint("ZwOpenFile error\n");
		return 0;
	}
	ntStatus = ZwCreateSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, 0, PAGE_READWRITE, 0x1000000, hFile);
	if (!NT_SUCCESS(ntStatus))
	{
		DbgPrint("ZwCreateSection error\n");
		return 0;
	}
	//例程将部分视图映射到主题进程的虚拟地址空间。
	ntStatus = ZwMapViewOfSection(hSection, NtCurrentProcess(), pBaseAddress, 0, 1024, 0, &viewSize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE);
	if (!NT_SUCCESS(ntStatus))
	{
		DbgPrint("ZwMapViewOfSection error\n");
		return 0;
	} 
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
	PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);
	PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)pDosHeader + pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress);
	ULONG ulNameberForNames = pExportTable->NumberOfNames;
	PULONG lpNameAddressArray = (PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfNames);
	PCHAR lpFunName = NULL;
	for (size_t i = 0; i < ulNameberForNames; i++)
	{
		lpFunName = (PCHAR)((PUCHAR)pDosHeader + lpNameAddressArray[i]);
		if (_strnicmp(pcFunctionName, lpFunName, strlen(pcFunctionName)) == 0) {
			USHORT uHint =*(USHORT *)(pDosHeader + pExportTable->AddressOfNameOrdinals + 2 * i);
			ULONG ulFUNAddr = *(ULONG*)((PUCHAR)pDosHeader + pExportTable->AddressOfFunctions + 4*i);
			PVOID lpFuncAddr = (PVOID)((PUCHAR)pDosHeader + ulFUNAddr);
			ulFunctionIndex = *(ULONG*)((PUCHAR)lpFuncAddr + 1);
			break;
		}	
	}
	ZwClose(hSection);
	ZwClose(hFile);
	
	return ulFunctionIndex;
}

NTSTATUS SetHook(ULONG ulFuncAddr, PCHAR pcFunctionName) {
	LONG ulFunctionIndex = 0;
	NTSTATUS  status = STATUS_SUCCESS;
	UNICODE_STRING usDllFileName;
	RtlInitUnicodeString(&usDllFileName, L"\\??\\C:\\Windows\\System32\\ntdll.dll");
	ulFunctionIndex = GetSSDTIndex(usDllFileName, pcFunctionName);
	if (ulFunctionIndex == 0) {
		DbgPrint("GetSSDTIndex error!\n");
		return status;
	}
	DbgPrint("ulFunctionIndex is 0x%x\n", ulFunctionIndex);
	PHYSICAL_ADDRESS phyAddress = MmGetPhysicalAddress(KeServiceDescriptorTable->KernelItem.FunAddressTable);//获取物理地址
	g_PageMapMemory = MmMapIoSpace(phyAddress, PAGE_SIZE, MmCached);			//映射
	NtOpenProcessOldFunAddr = g_PageMapMemory[ulFunctionIndex];
	g_PageMapMemory[ulFunctionIndex] = NtOpenProcess;
	return status;
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {
	//关闭映射
	//g_PageMapMemory[0xbe] = NtOpenProcessOldFunAddr;//还原回去
	SetHook(NtOpenProcessOldFunAddr, "NtOpenProcess");//动态还原回去
	MmUnmapIoSpace(g_PageMapMemory, PAGE_SIZE);//解除hook
	DbgPrint("卸载成功!\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) {
	pDriverObject->DriverUnload = DriverUnload;
	//hook 调用号是0xbe
	//修改CR0寄存器
	//MDR
	//内存映射
	//获取物理地址
	//静态根据索引hook
	//PHYSICAL_ADDRESS phyAddress=  MmGetPhysicalAddress(KeServiceDescriptorTable->KernelItem.FunAddressTable);
	//映射
//	g_PageMapMemory = MmMapIoSpace(phyAddress, PAGE_SIZE, MmCached);
	//现在g_PageMapMemory和KeServiceDescriptorTable->KernelItem.FunAddressTable等值了
//	NtOpenProcessOldFunAddr = g_PageMapMemory[0xbe];
//	g_PageMapMemory[0xbe] = NtOpenProcess;
	//最后结束时候要结束映射,在驱动卸载函数里

	//动态获取索引号
	SetHook((ULONG)NtOpenProcess,"NtOpenProcess");

	DbgPrint("加载成功!\n");
	return STATUS_SUCCESS;
}

结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值