A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #15412  by imnewbie
 Wed Aug 29, 2012 11:52 pm
Hello,

I am trying to hook the Shadow SSDT on Windows 7.

I have obtained a source code from this forum and I am doing it like this:

- Get ShadowSSDTPtr by going through KeAddSystemServiceTable function

-Obtain all handles in the system with NtQuerySystemInformation
-Iterate over all handles to get PID of crss.exe

And here is the problem. I dont seem to find the PID of crss.exe



Here is the code I am using:
Code: Select all
HANDLE GetCRSSPID()
{
	HANDLE Process = (HANDLE)0;
	HANDLE hObject = (HANDLE)0;
	HANDLE CsrId = (HANDLE)0;
	OBJECT_ATTRIBUTES obj;
	CLIENT_ID cid;
	UCHAR Buff[0x100];
	POBJECT_NAME_INFORMATION ObjName = (POBJECT_NAME_INFORMATION)&Buff;
	PSYSTEM_HANDLE_INFORMATION_EX Handles;
	ULONG r;

	Handles = (PSYSTEM_HANDLE_INFORMATION_EX)GetInfoTable(SystemHandleInformation);

	if(!Handles) 
		return CsrId;

	for (r = 0; r < Handles->NumberOfHandles; r++)
	{
		if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
		{
			InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

			cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
			cid.UniqueThread = 0;
			obj.ObjectName = NULL;			
			
			if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
			{
				if (   NT_SUCCESS(   ZwDuplicateObject(Process, Handles->Information[r].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)    )   )
				{
					if ( NT_SUCCESS(   ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)  )   )
					{
						if ( ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20)  )
						{
						  CsrId = (HANDLE)Handles->Information[r].ProcessId;
						  break;
						} 
					}

					ZwClose(hObject);
				}

				ZwClose(Process);
			}
		}
	}

	ExFreePool(Handles);

	return CsrId;
}

Now, do you see anything wrong? I looked up every Api and the parameters are fine. What I dont really understand is:
Code: Select all
!wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20)
Why are we comparing to "\\Windows\\ApiPort" if I am actually looking for crss.exe?
 #15415  by EP_X0FF
 Thu Aug 30, 2012 1:54 am
Because it is exclusive port used by csrss for interprocess communications. In Vista and higher it is "ALPC Port" type not "Port" type. Learn what you copy-paste.
Code: Select all
lkd> !object \ObjectTypes\ALPC Port
Object: fffffa8006d22920  Type: (fffffa8006c8c340) Type
    ObjectHeader: fffffa8006d228f0 (new version)
    HandleCount: 0  PointerCount: 2
    Directory Object: fffff8a000006980  Name: ALPC Port
lkd> dt nt!_OBJECT_TYPE fffffa8006d22920
   +0x000 TypeList         : _LIST_ENTRY [ 0xfffffa80`06d22920 - 0xfffffa80`06d22920 ]
   +0x010 Name             : _UNICODE_STRING "ALPC Port"
   +0x020 DefaultObject    : 0x00000000`000000c9 Void
   +0x028 Index            : 0x24
   +0x02c TotalNumberOfObjects : 0x377
   +0x030 TotalNumberOfHandles : 0x377
   +0x034 HighWaterNumberOfObjects : 0x3b3
   +0x038 HighWaterNumberOfHandles : 0x3b0
   +0x040 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0b0 TypeLock         : _EX_PUSH_LOCK
   +0x0b8 Key              : 0x43504c41
   +0x0c0 CallbackList     : _LIST_ENTRY [ 0xfffffa80`06d229e0 - 0xfffffa80`06d229e0 ]
Code: Select all
lkd> !object \ObjectTypes\Port
Object: 81feca08  Type: (81fed7a0) Type
    ObjectHeader: 81fec9f0 (old version)
    HandleCount: 0  PointerCount: 1
    Directory Object: e1004748  Name: Port
lkd> dt nt!_OBJECT_TYPE 81feca08
   +0x000 Mutex            : _ERESOURCE
   +0x038 TypeList         : _LIST_ENTRY [ 0x81feca40 - 0x81feca40 ]
   +0x040 Name             : _UNICODE_STRING "Port"
   +0x048 DefaultObject    : 0x80560960 Void
   +0x04c Index            : 0x15
   +0x050 TotalNumberOfObjects : 0xec
   +0x054 TotalNumberOfHandles : 0xea
   +0x058 HighWaterNumberOfObjects : 0x142
   +0x05c HighWaterNumberOfHandles : 0x140
   +0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0ac Key              : 0x74726f50
   +0x0b0 ObjectLocks      : [4] _ERESOURCE
 #15422  by imnewbie
 Thu Aug 30, 2012 11:30 am
Hey,

I changed the code a bit to test and see all the handles. Now Output is

"Name : (null)" all the time. Can you help me what I am doing wrong here?

Code: Select all
HANDLE GetCRSSPID()
{
	HANDLE Process, hObject;
	HANDLE CsrId = (HANDLE)0;
	OBJECT_ATTRIBUTES obj;
	CLIENT_ID cid;
	UCHAR Buff[0x100];
	POBJECT_NAME_INFORMATION ObjName = (POBJECT_NAME_INFORMATION)&Buff;
	PSYSTEM_HANDLE_INFORMATION_EX Handles;
	ULONG r;
	UNICODE_STRING test;

	Handles = (PSYSTEM_HANDLE_INFORMATION_EX)GetInfoTable(SystemHandleInformation);

	if(!Handles) 
		return CsrId;

	for (r = 0; r < Handles->NumberOfHandles; r++)
	{
		if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
		{
			InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

			cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
			cid.UniqueThread = 0;

			if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
			{
				if (NT_SUCCESS(ZwDuplicateObject(Process, (PHANDLE)&(Handles->Information[r].Handle),NtCurrentProcess(), (PHANDLE)&hObject, 0, 0, DUPLICATE_SAME_ACCESS))   )
				{
				if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
					{
						RtlInitUnicodeString(&test, ObjName->Name.Buffer);
						KdPrint(("Name: %wZ", test));
					}

					ZwClose(hObject);
				}

				ZwClose(Process);
			}
		}
	}

	ExFreePool(Handles);

	return CsrId;
}
 #15430  by xdeadcode
 Thu Aug 30, 2012 4:57 pm
Hi imnewbie,

As EP_X0FF stated before, it would be good for you to read something about LPC/ALPC and also investigate/debug how csrss is working under the hood to understand why it is done this way.
Here is good start point: http://recon.cx/2008/a/thomas_garnier/L ... -paper.pdf

According to your code, you have two thing written wrong:
1. You do not check ObjName->Name.Buffer - it can be null
2. DbgPrint("%wZ", &us) <--- it is taking pointer to unicode_string, not unicode_string itself.


Best regards,
 #15940  by SomeUnusedName
 Wed Oct 10, 2012 3:19 pm
To be honest I don't get the top post, and I don't get the reference to the topic's title.

Hooking the shadow SSDT on Windows 7 (x32) is pretty much the same as for Win XP, just some offsets have changed. So, can someone explain what the OP is doing/wants to do? Why would he care about csrss or something?
 #18933  by Vrtule
 Sun Apr 14, 2013 8:53 am
mepitiean wrote:I have done a shadow SSDT hooking for windows 7 32 bit by changing the callnumber of apis bt i got BSOD
I think you should describe your problem in more detail.

My implementation of SSDT Shadow hooking searches for GUI process in kernel by checking whether a process has valid W32PROCESS structure.
 #18934  by mepitiean
 Sun Apr 14, 2013 9:48 am
I want to hook NtUSerSendinput and NtuserPostmessage.But i just take ur code nd try that for windows 7 x32 SP1 whether it is work in windows 7 i have changed the call number of apis as http://j00ru.vexillium.org/win32k_syscalls/.I got an BSOD orelse i can able to register my driver and unable to start service because i got an error like parameter incorrect or system cannot find the file specified.But i successfully hooked SSDT.But i don't know how to hook Shadow SSDT