zoukankan      html  css  js  c++  java
  • 学习自建调试体系(四)

    这部分ring3和ring0通信,感觉也是实用的套路,先总结大致思路:

    1. hook NtTerminateProcess函数
    2. 有TerminateProcess请求到来时,判断参数二是否为固定常数(密钥),不是的话走原函数调用
    3. 如果参数二是约定好的密钥,参数一作为约定好的结构指针
    4. 读取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 
    ",
    		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 有问题 
    "));
    				break;
    			}
    
    			//
    			// 如果输入缓冲区不为NULL, 那么锁定输入缓冲区
    			//
    			if (SysCall.lpInBuffer != NULL)
    			{
    				if (DbgLockBuffer(&InBufferLock, SysCall.lpInBuffer, SysCall.ulInBufferSize) == 0)
    				{
    					KdPrint(("Ddvp-> NewNtTerminateProcess In Buffer Lock Error! 
    "));
    					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! 
    "));
    					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;
    }
    
    
  • 相关阅读:
    Java多线程系列 基础篇10 wait/notify/sleep/yield/join
    Java多线程系列 基础篇09 Object.wait/notifyJVM源码实现
    Java多线程系列 基础篇07 synchronized底层优化
    Java多线程系列 基础篇06 synchronized(同步锁)
    Java多线程系列 基础篇05 synchronized关键字
    Java多线程系列 基础篇04 线程中断
    Java多线程系列 基础篇03 线程的优先级和守护线程
    Java多线程系列 基础篇02 线程的创建和运行
    MySQL进阶14--标识列(自增序列/auto_increment)--设置/展示步长--设置/删除标示列
    MySQL进阶13--常见六大约束: 非空/默认/主键/唯一约束/检查约束/外键约束--表级约束 / 列级约束
  • 原文地址:https://www.cnblogs.com/Lnju/p/5414231.html
Copyright © 2011-2022 走看看