A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #7659  by utsav.0202
 Tue Jul 26, 2011 11:59 am
Hi

I want to protect my process from getting terminated by any other process for Vista sp1 and later versions of WOS.
For the purpose I used ObRegisterCallbacks and registered a callback for process handle creation. In the PreOperation I am removing the PROCESS_TERMINATE and other necessary access rights(DesiredAccess). This works fine for OpenProcess function and the process handle is not given the PROCESS_TERMINATE access. (Checked from PostOperation, GrantedAccess)

But if in kernel mode I get the handle by using (I saw this Process Hacker)
i) PsLookupProcessByProcessId (get EPROCESS from PID)
ii) ObOpenObjectByPointer (get handle from EPROCESS)

it is given the PROCESS_TERMINATE access. Why? How to avoid this?

Thanks and Regards
Utsav
 #7665  by EP_X0FF
 Tue Jul 26, 2011 3:14 pm
Hello,

please post your callback code.

Regards.
 #7682  by utsav.0202
 Wed Jul 27, 2011 6:48 am
Thanks for replying.
Here is my callback
Code: Select all
void changeProcessAccess(ACCESS_MASK *pDesiredAccess)
{
	ACCESS_MASK DesiredAccess = *pDesiredAccess;

	DesiredAccess = DesiredAccess & ~PROCESS_CREATE_THREAD;
	DesiredAccess = DesiredAccess & ~PROCESS_CREATE_PROCESS;
	DesiredAccess = DesiredAccess & ~PROCESS_TERMINATE;
	DesiredAccess = DesiredAccess & ~PROCESS_VM_WRITE;
	DesiredAccess = DesiredAccess & ~PROCESS_VM_OPERATION;
	DesiredAccess = DesiredAccess & ~PROCESS_SUSPEND_RESUME;
	DesiredAccess = DesiredAccess & ~PROCESS_DUP_HANDLE;

	*pDesiredAccess = DesiredAccess;
}

OB_PREOP_CALLBACK_STATUS ObPreCallProcessObject(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
	char szProcName[20] = "";
	char *szNamePtr;
	PEPROCESS processObj	= NULL;
	ACCESS_MASK desired	= 0;
	
	processObj = OperationInformation->Object;
	
	szNamePtr = (char *)processObj + 0x238;         //for Vista
	if(szNamePtr)
	{
		RtlCopyMemory(szProcName, szNamePtr, 16);
		szProcName[16] = 0;
	}

	if ((szProcName[0] == 'a' || szProcName[0] == 'A') &&
		(szProcName[1] == 'b' || szProcName[1] == 'B') &&
		(szProcName[2] == 'c' || szProcName[2] == 'C'))                        //testing on abc.exe
	{
		if (OB_OPERATION_HANDLE_CREATE == OperationInformation->Operation)
		{
			desired = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
			changeProcessAccess(&desired);
			OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = desired;
		}
		else if (OB_OPERATION_HANDLE_DUPLICATE == OperationInformation->Operation)
		{

			desired = OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess;
			changeProcessAccess(&desired);
			OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = desired;
		}
	}

	UNREFERENCED_PARAMETER(RegistrationContext);

	return OB_PREOP_SUCCESS;
}
If ObRegisterCallbacks does not allow changing rights on handles opened in kernel mode then what do I do to protect my process in such situation?

Thanks ans Regards.
 #7683  by EP_X0FF
 Wed Jul 27, 2011 6:51 am
What is the sense in protecting from Kernel mode access? Absolutely no sense and wasting of time.
I can kill your process simple having only PEPROCESS.
 #7688  by EP_X0FF
 Wed Jul 27, 2011 7:25 am
Okay.

Second time.

What is the sense of this? Well you hook it, (btw it is Object Manager routine why it should be in SSDT?) then I call it through clean stub, or directly via Object Manager.
What next?

Complete wasting of time.

Splicing of kernel routines (except shadow table) is forbidden on x64.
 #7689  by utsav.0202
 Wed Jul 27, 2011 7:44 am
I understand that it can be called directly via Object Manager.

I just want to protect my process from tools like Process Hacker which are very easily available and any user can kill my process without taking any efforts.
 #7690  by EP_X0FF
 Wed Jul 27, 2011 7:48 am
User that has admin rights can use million + 1 ways to terminate your program. The only one way - is deny all drivers loading while your program is running. However this is extreme and total bugfest way, so no how.