学习自建调试体系(四)
这部分ring3和ring0通信,感觉也是实用的套路,先总结大致思路:
- hook NtTerminateProcess函数
- 有TerminateProcess请求到来时,判断参数二是否为固定常数(密钥),不是的话走原函数调用
- 如果参数二是约定好的密钥,参数一作为约定好的结构指针
- 读取ring3传来的数据,读取数据,执行约定函数
SSDT hook
NTSTATUS DbgObjHookNtTerminateProcess()
{
	PULONG  Address;
	PVOID Temp;
	if ((ULONG)OldNtTerminateProcess)		//static变量初始化0 
	{
		return STATUS_UNSUCCESSFUL;
	}
	//
	// 在SSDT表中获取到NtTerminateProcess的地址
	//
	Address = (PULONG)((ULONG)KeServiceDescriptorTable->ntoskrnl.ServiceTable +
		257 * 4);
	//原函数 and 替换函数
	OldNtTerminateProcess = (PZWTERMINATEPROCESS)* Address;
	Temp = &NewNtTerminateProcess;
	//
	// 改写SSDT表中NtTerminateProcess的地址
	//
	//自己封装的MoveMemory函数
	SafeCopyMemory(Address, &Temp, sizeof(PVOID));
	KdPrint(("Ddvp-> 旧NtTerminateProcess地址: %p, 新的NtTerminateProcess地址: %p \n",
		OldNtTerminateProcess, &NewNtTerminateProcess));
	return STATUS_SUCCESS;
}
钩子函数
NTSTATUS
NewNtTerminateProcess(
HANDLE   hProcess,
NTSTATUS ExitStatus
)
{
	NTSTATUS Status;
	BUFFER_LOCK InBufferLock;
	BUFFER_LOCK OutBufferLock;
	SYSTEM_CALL  SysCall;
	//typedef struct tagSystemCall
	//{
	//	int Number;
	//	PVOID lpInBuffer;
	//	ULONG ulInBufferSize;
	//	PVOID lpOutBuffer;
	//	ULONG ulOutBufferSize;
	//}SYSTEM_CALL, *PSYSTEM_CALL;
	PEPROCESS Process = PsGetCurrentProcess();
	//
	// 如果调用过来的是用户态, 并且Key也相同
	//
	if ((ExGetPreviousMode() == UserMode) && (ExitStatus == 0x750C530D))
	{
		Status = STATUS_UNSUCCESSFUL;
		InBufferLock.lpData = NULL;
		OutBufferLock.lpData = NULL;
		do
		{
			__try
			{
				//
				// 检查用户模式缓冲区是否正确对齐.注意是用户模式缓冲区
				//
              
              /////hProcess作为pSysCall解释
				ProbeForRead(hProcess, sizeof(SYSTEM_CALL), 1);
				//
				// 复制 一个 syscall结构过来
				//
				fastcpy(&SysCall, hProcess, sizeof(SYSTEM_CALL));
			}
			__except (EXCEPTION_EXECUTE_HANDLER)
			{
				Status = GetExceptionCode();
				break;
			}
			//
			// 参数判断
			//
			if ((SysCall.Number > SC_MAX) ||
				(SysCall.ulInBufferSize  > SC_DAT_LIMIT) ||
				(SysCall.ulOutBufferSize > SC_DAT_LIMIT))
			{
				KdPrint(("Ddvp-> NewNtTerminateProcess Buffer 有问题 \n"));
				break;
			}
			//
			// 如果输入缓冲区不为NULL, 那么锁定输入缓冲区
			//
			if (SysCall.lpInBuffer != NULL)
			{
				if (DbgLockBuffer(&InBufferLock, SysCall.lpInBuffer, SysCall.ulInBufferSize) == 0)
				{
					KdPrint(("Ddvp-> NewNtTerminateProcess In Buffer Lock Error! \n"));
					break;
				}
				SysCall.lpInBuffer = InBufferLock.lpData;
			}
			//
			// 如果输出缓冲区不为NULL, 那么锁定输入缓冲区
			//
			if (SysCall.lpOutBuffer != NULL)
			{
				if (DbgLockBuffer(&OutBufferLock, SysCall.lpOutBuffer, SysCall.ulOutBufferSize) == 0)
				{
					KdPrint(("Ddvp-> NewNtTerminateProcess Out Buffer Lock Error! \n"));
					break;
				}
				SysCall.lpOutBuffer = OutBufferLock.lpData;
			}
			//
			// 执行约定的函数,哪个函数,什么通信数据都在SysCall结构中
			//
			if (NT_SUCCESS(SysCallTable[SysCall.Number](&SysCall)))
			{
				Status = STATUS_SUCCESS;
			}
		} while (0);
		if (InBufferLock.lpData != NULL)
		{
			DbgUnLockBuffer(&InBufferLock);
		}
		if (OutBufferLock.lpData != NULL)
		{
			DbgUnLockBuffer(&OutBufferLock);
		}
	}
	//---------------------------------------------------------------------------
	else
	{
			Status = OldNtTerminateProcess(hProcess, ExitStatus);
	}
	return Status;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号