hook方式进程创建监控,进程保护

85 篇文章 6 订阅
83 篇文章 9 订阅

关于进程创建,

xp系统:CreatProcessW->CreateProcessInternalW->NtCreateProcessEx->NtCreatSection

Vista以上:CCreatProcessW->CreateProcessInternalW->NtCreateUserProcess->NtCreateSection

所以我们要HookNtCreateSection

而系统调用NtCreateSecton时有多种情况,不只是创建进程时,我们要过滤排除掉其他情况。

发现只有

(Protect (PAGE_EXECUTE/*|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY*/)&&(Attributes == SEC_IMAGE) && FileHandle)

发现这些可以在创建进程时windbg在此下断,观察参数,或者去看wrk,reactos代码。

还要去得到子进程路径。

另外其实使用文件过滤监控IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION更好,这个函数会走这个IRP。因为通过过滤支持x64,ssdthook只支持x86.或者使用回调PsSetCreateProcessNotifyRoutineEx。注册回调,这样在进程创建时候回调用他。

监控代码片段

NTSTATUS NTAPI HOOK_NtCreateSection(PHANDLE SectionHandle,
				  ACCESS_MASK DesiredAccess,
				  POBJECT_ATTRIBUTES ObjectAttributes,
				  PLARGE_INTEGER SectionSize,
				  ULONG Protect,
				  ULONG Attributes,
				  HANDLE FileHandle)//代理函数 
{
	PFILE_OBJECT    			FileObject = NULL; 
	POBJECT_NAME_INFORMATION 	wcFilePath = NULL;
	ANSI_STRING 				dst = {0};
	UNICODE_STRING				ustrProcessPath = {0};
	WCHAR						wszProcessPath[MAX_PATH] = {0};
	NTSTATUS					ntStatus = 0;

	__try
	{
		if (Protect & (PAGE_EXECUTE/*|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY*/)&&
			(Attributes == SEC_IMAGE) && 
		    FileHandle)
		{
			if (NT_SUCCESS(ObReferenceObjectByHandle(FileHandle,0,NULL,KernelMode,&FileObject,NULL)))//获取文件对象,这里类型最好不要传NULL,不然会有问题
			{
				//获取FileObject对应的文件全路径
				if (IoQueryFileDosDeviceName(FileObject, &wcFilePath)==STATUS_SUCCESS)//获取文件对象所对应的文件Dos设备名称,即是全路径
				{
					if (RtlCompareMemory(wcFilePath->Name.Buffer+wcFilePath->Name.Length/2-wcslen(L"Winobj.exe"),L"Winobj.exe",wcslen(L"Winobj.exe")*sizeof(WCHAR))==wcslen(L"Winobj.exe")*sizeof(WCHAR)
						&& RtlCompareMemory(wcFilePath->Name.Buffer+wcFilePath->Name.Length/2-wcslen(L"PopupClient.exe"),
						L"PopupClient.exe",wcslen(L"PopupClient.exe")*sizeof(WCHAR))!=wcslen(L"PopupClient.exe")*sizeof(WCHAR))//这里是例子只监控Winobj.exe
					{
						DbgPrint("Target:%wZ\n",&wcFilePath->Name);//子进程
						//PPID = HandleToUlong(PsGetCurrentProcessId());
						ustrProcessPath.Buffer = wszProcessPath;
						ustrProcessPath.Length = 0;
						ustrProcessPath.MaximumLength = sizeof(wszProcessPath);
						ntStatus = ntGetProcessFullNameByPid(PsGetCurrentProcessId(), &ustrProcessPath);//父进程路径,就是当前路径
						DbgPrint("Parent:%wZ\n", &ustrProcessPath);
						if (NT_SUCCESS(ntStatus))
						{
							if (GetResultFromUser()==R3Result_Pass)
							{
								ntStatus = OldZwCreateSection(
												SectionHandle,
												DesiredAccess,
												ObjectAttributes,
												SectionSize,
												Protect,
												Attributes,
												FileHandle);
								ObDereferenceObject(FileObject);//放弃对FileObject的引用
								ExFreePool(wcFilePath);
								return ntStatus;	
							}
							ObDereferenceObject(FileObject);//放弃对FileObject的引用
							ExFreePool(wcFilePath);
							return STATUS_SUCCESS;
						}
					}
					ExFreePool(wcFilePath);//IoQueryFileDosDeviceName获取的OBJECT_NAME_INFORMATION 需要手动释放
				}
				ObDereferenceObject(FileObject);//放弃对FileObject的引用
			}        
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{

	}
	return OldZwCreateSection(SectionHandle,DesiredAccess,ObjectAttributes,SectionSize,Protect,Attributes,FileHandle);
}

 

注意点

if (NT_SUCCESS(ObReferenceObjectByHandle(FileHandle,0,NULL,KernelMode,&FileObject,NULL)))//获取文件对象,这里类型最好不要传NULL,不然会有问题

进程保护

在应用层杀死进程使用的是TerminateProcess,这个函数在0环使用的是ZwTerminateProcess,所以我们可以hookZwTerminateProcess

可以在用户层获得我们要保护的进程的PID,发到我们的内核里来,然后保存在一个数组里面,存着我们要保护进程的PID。然后每次hookZwTerminateProcess比对PID,但是ZwTerminateProcess只有handle,ObReferenceObjectByHandle拿到EPROCESS,调用PsGetProcessId拿到进程PID。然后去数组比对。

代码片段

NTSTATUS Hook_ZwTerminateProcess(
	__in_opt HANDLE ProcessHandle,
	__in NTSTATUS ExitStatus
	)
{
	ULONG 			uPID = 0;
	NTSTATUS 		ntStatus = 0;
	PEPROCESS 		pEProcess = NULL;

	ntStatus = ObReferenceObjectByHandle(ProcessHandle, FILE_READ_DATA, NULL, KernelMode, &pEProcess, NULL);
	if(!NT_SUCCESS(ntStatus))
	{
		return ntStatus;
	}


	uPID = (ULONG)PsGetProcessId(pEProcess);

	if(ValidateProcessNeedProtect(uPID) != -1)//不是当前进程PID,为了客户端自己关自己
	{
		if(uPID != (ULONG)PsGetProcessId(PsGetCurrentProcess()))
		{
			return STATUS_ACCESS_DENIED;
		}
	}
	ntStatus = OldZwTerminateProcess(ProcessHandle, ExitStatus);

	return ntStatus;
}

或者通过回调保护进程,通过obRegisterCallbacks注册回调,https://bbs.pediy.com/thread-168023.htm

结束任务的保护:

窗口标题不为空的程序,都会在任务列表中显示。

结束任务:使用SendMessageTimeoutW发送WM_CLOSE消息,并这顶超时时间500ms,超过走EndTask。

解决方法:我们就可以将标题SetWindowText(_T(""))为空,驱动里面hook NtOpenProcess,NtTerminateProcess

过滤WM_CLOSE消息,在虚函数Pre TranslateMessage里

BOOL CXXXDlg::PreTranslateMessage(MSG* pMSG)
{
    if(pMsg->message==WM_CLOSE)//过滤掉WM_CLOSE
    {
        return TRUE;
    }
    
}

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Hook进程创建函数是一种监控和拦截进程的技术。当一个进程创建时,操作系统会调用相应的进程创建函数来执行一系列的操作,例如分配内存、初始化资源等。通过hook进程创建函数,我们可以在进程创建的过程中插入自定义的代码,从而实现对进程监控和拦截。 通过hook进程创建函数,我们可以实现以下功能: 1. 监控进程创建:通过hook进程创建函数,我们可以记录下每个进程创建情况,包括进程的名称、进程ID等信息。这对于进程管理、调试和安全审计等方面都非常有用。 2. 拦截进程创建:当我们希望阻止某个进程创建时,可以通过hook进程创建函数实现进程的拦截。例如,某些恶意程序会通过创建进程方式进行传播,我们可以通过hook进程创建函数拦截这些进程创建,从而保护系统的安全。 3. 修改进程创建参数:通过hook进程创建函数,我们可以修改进程创建参数,例如修改程序的启动参数、运行环境等。这对于进程的定制化和优化非常有用。 4. 绕过进程创建限制:有些情况下,操作系统会对进程创建做一些限制,例如限制某个程序创建进程数量、限制进程的权限等。通过hook进程创建函数,我们可以绕过这些限制,实现一些我们需要的功能。 总之,hook进程创建函数是一种非常有用的技术,可以实现对进程监控和拦截。通过插入自定义代码来实现各种功能,从而对进程进行管理和控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值