C,C++保护特定名字的进程(修复)

2021在线班
郁金香灬老师 QQ 150330575
交流群:158280115


学习目标: 
     C,C++只保护特定的名字的进程 
	 驱动中进程间的切换
	 
	 保护特定进程时 条件选择 名字 PID
	 
	
	 PsGetCurrentProcess()
     PsGetProcessImageFileName //11个有效的字符
     PsGetCurrentProcessId() //获取当前进程PID

 NTSTATUS 
 PsLookupProcessByProcessId( 
     __in HANDLE ProcessId,   //进程ID
     __deref_out PEPROCESS *Process //返回的EPROCESS
 )
 
 
const char* GetProcessName(ULONG dwPid)  
{  
    HANDLE ProcessHandle;  
    NTSTATUS status;  
    OBJECT_ATTRIBUTES  ObjectAttributes;  
    CLIENT_ID myCid;  
    PEPROCESS EProcess;  
  
    InitializeObjectAttributes(&ObjectAttributes,0,0,0,0);   
  
    myCid.UniqueProcess = (HANDLE)dwPid;  
    myCid.UniqueThread = 0;  
  
    //打开进程，获取句柄  
    status = ZwOpenProcess (&ProcessHandle,PROCESS_ALL_ACCESS,&ObjectAttributes,&myCid);  
    if (!NT_SUCCESS(status))  
    {  
        DbgPrint("打开进程出错\n");  
        return;  
    }  
      
    //得到EPROCESS，结构中取进程名  
    status = ObReferenceObjectByHandle(ProcessHandle,FILE_READ_DATA,0,KernelMode,&EProcess, 0);  
    if (status == STATUS_SUCCESS)  
    {  
        char *ProcessName = (char*)EProcess + 0x174;  
        char *PsName = PsGetProcessImageFileName(EProcess);  
  
        DbgPrint("ProcessName is %s\n",ProcessName);  
        DbgPrint("PsName is %s\n",PsName);  
  
        ZwClose(ProcessHandle);  
    }  
    else  
    {  
        DbgPrint("Get ProcessName error");  
    }  
	return PsName;
}  


//功能:进程ID,进程名称
const char* GetProcessName(HANDLE ProcessId)
{
	NTSTATUS st = STATUS_UNSUCCESSFUL;
	PEPROCESS ProcessObj = NULL;
	const char* string = NULL;
	st = PsLookupProcessByProcessId(ProcessId, &ProcessObj);
	if (NT_SUCCESS(st))
	{
		string = PsGetProcessImageFileName(ProcessObj);
		ObfDereferenceObject(ProcessObj);
	}
	return string;
}


//------------------



//功能:进程ID,进程名称
const char* GetProcessName(/*HANDLE ULONG*/ HANDLE ProcessId)
{
	NTSTATUS st = STATUS_UNSUCCESSFUL;
	PEPROCESS ProcessObj = NULL;
	const char* imagename = NULL;
	st = PsLookupProcessByProcessId(ProcessId, &ProcessObj);
	if (NT_SUCCESS(st))
	{
		imagename = PsGetProcessImageFileName(ProcessObj);
		ObfDereferenceObject(ProcessObj);
	}
	return imagename;
}




OB_PREOP_CALLBACK_STATUS
my_pre_callback(
	PVOID RegistrationContext,
	POB_PRE_OPERATION_INFORMATION OperationInformation
)
{
	RegistrationContext;

	
	if (OperationInformation->KernelHandle)
	{
		//内核创建 KernelMode
	}
	else
	{//UserMode
		/*
		OpenProcess(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL bInheritHandle,
    _In_ DWORD dwProcessId
    );

		*/
	//用户层 调用了 OpenProcess NtOpenProcess 进程名 OpenProcess(
	UINT32 curPID=PsGetCurrentProcessId(); //获取当前进程PID
	const char*进程名=	PsGetProcessImageFileName(PsGetCurrentProcess()); //11个有效的字符

	HANDLE dwProcessId = PsGetProcessId((PEPROCESS)OperationInformation->Object);; ///目标进程PID 想要保护的PID
	 const char*目标进程名 = GetProcessName(dwProcessId); //要保护是这个进程名
	if (判断受保护的PID((UINT32)dwProcessId) == 1)
	{
	 	KdPrint(("yjx:SYS curPID=%d 进程名=%s  目标进程PID =%d  目标进程名=%s \n", curPID, 进程名, dwProcessId, 目标进程名)); //11个节字长度是有效
		KdPrint(("yjx:sys pEPROCESS=%p dwProcessId=%d", OperationInformation->Object, dwProcessId));
		ACCESS_MASK old权限 = OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess;
		//ACCESS_MASK old1 = old权限;
		ACCESS_MASK new1 = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
		//排除 PROCESS_VM_READ 权限
		old权限 &= ~PROCESS_TERMINATE; //阻止结束进程  拦截结束进程
		old权限 &= ~PROCESS_VM_READ; //CE
		old权限 &= ~PROCESS_VM_WRITE;

		//排除掉 PROCESS_VM_WRITE
		/*old权限 &= ~PROCESS_VM_WRITE;*/
		//返回我们修改过的权限 OpenProcess
		OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 0;// old权限;
		KdPrint(("yjx:old权限=%x 新权限=%X 被保护的进程PID=%d", old权限, new1, dwProcessId));
	}


	}

	return OB_PREOP_SUCCESS;
};


