HOOK地址还原

H头文件
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
typedef struct _ServiceDescriptorTable {
	PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
	PVOID ServiceCounterTable;
	//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
	unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
	PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable;  
extern PServiceDescriptorTable KeServiceDescriptorTable;

#pragma pack(1)
typedef struct _JMPCODE
{
	BYTE E9;
	ULONG JMPADDR;//88881234=B
}JMPCODE,*PJMPCODE;
#pragma pack()
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
ULONG GetNt_CurAddr() //获取当前SSDT_NtOpenProcess的当前地址
{

	LONG *SSDT_Adr,SSDT_NtOpenProcess_Cur_Addr,t_addr; 
	KdPrint(("驱动成功被加载中.............................
"));
	//读取SSDT表中索引值为0x7A的函数
	//poi(poi(KeServiceDescriptorTable)+0x7a*4)
	t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;
	KdPrint(("当前ServiceTableBase地址为%x 
",t_addr));
	SSDT_Adr=(PLONG)(t_addr+0x7A*4);
	KdPrint(("当前t_addr+0x7A*4=%x 
",SSDT_Adr)); 
	SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr;	
	KdPrint(("当前SSDT_NtOpenProcess_Cur_Addr地址为%x 
",SSDT_NtOpenProcess_Cur_Addr));
	return SSDT_NtOpenProcess_Cur_Addr;
}

ULONG GetNt_OldAddr()
{
	UNICODE_STRING Old_NtOpenProcess;
	ULONG Old_Addr;
	RtlInitUnicodeString(&Old_NtOpenProcess,L"NtOpenProcess");
	Old_Addr=(ULONG)MmGetSystemRoutineAddress(&Old_NtOpenProcess);//取得NtOpenProcess的地址
	KdPrint(("取得原函数NtOpenProcess的值为 %x",Old_Addr));
	return Old_Addr;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
CPP文件中:
全局变量:
JMPCODE oldCode;//用来保存前5字节  以便恢复
PJMPCODE pcur;
ULONG flag = 0;

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
DriverEntry函数:
ULONG cur,old;
	JMPCODE JmpCode;
	PJMPCODE pcur;


cur=GetNt_CurAddr();//A
	old=GetNt_OldAddr();//C
	if (cur!=old)
	{   
		flag = 1;
			//保存旧地址
			pcur = (PJMPCODE)(cur);
			oldCode.E9 = pcur->E9;				//1字节
			oldCode.JMPADDR = pcur->JMPADDR;	//4字节

			JmpCode.E9=0xE9; 
			JmpCode.JMPADDR=old-cur-5;
			KdPrint(("要写入的地址%X",JmpCode.JMPADDR));
		//写入JMP   C-A-5=B //实际要写入地址

		__asm //去掉页面保护
		{
			cli	//关掉中断 避免在执行时被打扰 sti 允许操作
				mov eax,cr0
				and eax,not 10000h //and eax,0FFFEFFFFh
				mov cr0,eax
		}
		
		pcur=(PJMPCODE)(cur);
		pcur->E9 = 0xE9;
		pcur->JMPADDR = JmpCode.JMPADDR;

		__asm //恢复页保护
		{
			mov eax,cr0
				or  eax,10000h //or eax,not 0FFFEFFFFh
				mov cr0,eax
				sti
		}

		KdPrint(("NtOpenProcess被HOOK了"));
	}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
DDK_Unload函数:
__asm //去掉页面保护
	{
		cli	//关掉中断 避免在执行时被打扰 sti 允许操作
			mov eax,cr0
			and eax,not 10000h //and eax,0FFFEFFFFh
			mov cr0,eax
	}
	if (flag)//全局 去看是否被HOOK 了  被HOOK才还原
	{
		pcur->E9 = oldCode.E9;				//1字节
		pcur->JMPADDR = oldCode.JMPADDR;	//4字节
	}
	
	__asm //恢复页保护
	{
		mov eax,cr0
			or  eax,10000h //or eax,not 0FFFEFFFFh
			mov cr0,eax
			sti
	}


原文地址:https://www.cnblogs.com/zcc1414/p/3982499.html