Gettin HANDLE AND PASS IT TO USERMODE -- STATUS_OBJECT_TYPE_MISMATCH

PEPROCESS eProcess = NULL;
eProcess = PsLookupProcessByProcessId… (This Working)

status = ObOpenObjectByPointer(eProcess, 0, NULL, FILE_ALL_ACCESS, 0, UserMode,&(*data).ProcessHandle);

status is = Error Status : c0000024 STATUS_OBJECT_TYPE_MISMATCH

(*data).ProcessHandle = is a null handle that i am getting from user process.

Thing i am trying to do.
1Create null Handle in User process.
2Pass to driver that handle and assing that Handle to target process.
via ObOpenObjectByPointer

so basically
I need to Get A handle From Kernel space and use it in UserMode…

Thank you

For the UserMode access mode you should provide the object type for ObOpenObjectByPointer. Also get rid of FILE_ALL_ACCESS in favor of PROCESS_ALL_ACCESS.

#include <wdm.h> // for PsProcessType declaration
OR
extern POBJECT_TYPE* PsProcessType;

status = ObOpenObjectByPointer(eProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType,
UserMode,&(*data).ProcessHandle);



I hope data is allocated in the kernel space and not a user space pointer.</wdm.h>

From ObOpenObjectByPointer documentation:
NTSTATUS ObOpenObjectByPointer(
In PVOID Object,
In ULONG HandleAttributes,
In_opt PACCESS_STATE PassedAccessState,
In ACCESS_MASK DesiredAccess,
In_opt POBJECT_TYPE ObjectType,
In KPROCESSOR_MODE AccessMode,
Out PHANDLE Handle
);

If AccessMode is UserMode, ObjectType is not optional and can not be NULL.

Regards,
Alex Krol

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Thursday, January 12, 2017 11:31 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Gettin HANDLE AND PASS IT TO USERMODE – STATUS_OBJECT_TYPE_MISMATCH

PEPROCESS eProcess = NULL;
eProcess = PsLookupProcessByProcessId… (This Working)

status = ObOpenObjectByPointer(eProcess, 0, NULL, FILE_ALL_ACCESS, 0, UserMode,&(*data).ProcessHandle);

status is = Error Status : c0000024 STATUS_OBJECT_TYPE_MISMATCH

(*data).ProcessHandle = is a null handle that i am getting from user process.

Thing i am trying to do.
1Create null Handle in User process.
2Pass to driver that handle and assing that Handle to target process.
via ObOpenObjectByPointer

so basically
I need to Get A handle From Kernel space and use it in UserMode…

Thank you


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Thank You.
Now i can get the handle and use it in driver.Tested whit simple ObReferenceObjectByHandle.

But i still cant pass it to the ring3.

typedef struct _KERNEL_GET_HANDLE
{
ULONG ProcessId;
HANDLE ProcessHandle;
} KERNEL_GET_HANDLE, *PKERNEL_GET_HANDLE;

I think that exactly what i am doing.It’s a user space pointer.

KERNEL_GET_HANDLE test;
DeviceIoControl(…test…).

So how can i fix this?

Define the IOCTL as METHOD_BUFFERED. The system will allocate a kernel buffer and copies data to it from user space. Do not forget to set Irp->IoStatus.Information = sizeof( KERNEL_GET_HANDLE ) before calling IoCompleteRequest ( or whatever method you use in KMDF for IOCTL processing) so the system copies data from the kernel space buffer to the user space on IRP completion. Do not forget to provide an output buffer for DeviceIoControl , this can be the same as an input buffer.

With METHOD_BUFFERED the input buffer is Irp->AssociatedIrp.SystemBuffer . The output buffer is the same Irp->AssociatedIrp.SystemBuffer which is copied back to the user space on Irp completion, the copied data size is Irp->IoStatus.Information .

METHOD_BUFFERED (OK)
rp->AssociatedIrp.SystemBuffer (OK)

But still fails.

Few Sreenshots

//my Dispatch
https://i.gyazo.com/9a61c2d2dc5862e4d1f5bf4b608d1934.png

//Function
https://i.gyazo.com/097913464de543593f3ca61ed090fb39.png

//How ? call from Ring3
https://i.gyazo.com/8d3deb46b5d42e1fb13a734168dad2c3.png

DbgPrint dump
https://gyazo.com/ba7f90e5402402c01be95f3ce9dc3236

as we can see from DbgPrint handle does work in kernel space but i still fail to can it to ring 3

Why aren’t you using usermode function OpenProcess which does exactly what you are trying to do?

For science purposes only
I need to learn.

You are passing parameters by value to GetSysHandle, i.e. the system creates copies for ProcessId and Handle values on the stack or registers before passing them to GetSysHandle . I understand that people with Java or C# background might have some difficulties with this concept but these types are actually an alias for a basic type which is also passed by value in Java, so this code would not work even in Java-like languages. You need to pass parameters by reference.

Why do you need a struct ? An IOCTL provides both an input buffer and an output buffer. So the PID should be in the input buffer and the output buffer should just be a handle pointer.

Note that you could make the call with a handle allocated on the stack and make the copy to the user buffer at the very end if the call is successful.

HANDLE ProcessHandle;

Status = ObOpenObjectByPointer(…,&ProcessHandle);

if(NT_SUCCESS(Status)){
// copy to the user buffer.
// A try/except scheme may be needed
// but not in the case of a buffered I/O as Slava pointed out.

}

D. T.

i did what u told me but still having problems.

HANDLE KernelProcessHandle;
status = ObOpenObjectByPointer(eProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode,&KernelProcessHandle);
ProcessHandle = KernelProcessHandle;

ProcessHandle = is a paramater that come from usermode.

like i said i tested the handle KernelProcessHandle whit ObReferenceObjectByHandle.It Works.
But cant copy the handle.
I realy want to fix this

.

What is the type ProcessHandle? Usually there would be a pointer deref. I would expect the type to be HANDLE*, also the code should read

*ProcessHandle = KernelProcessHandle;

Bent from my phone


From: xxxxx@hotmail.commailto:xxxxx
Sent: Saturday, January 14, 2017 2:20 AM
Subject: RE:[ntdev] Gettin HANDLE AND PASS IT TO USERMODE – STATUS_OBJECT_TYPE_MISMATCH
To: Windows System Software Devs Interest List >

D. T.

i did what u told me but still having problems.

HANDLE KernelProcessHandle;
status = ObOpenObjectByPointer(eProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode,&KernelProcessHandle);
ProcessHandle = KernelProcessHandle;

ProcessHandle = is a paramater that come from usermode.

like i said i tested the handle KernelProcessHandle whit ObReferenceObjectByHandle.It Works.
But cant copy the handle.
I realy want to fix this

.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx>

> ProcessHandle = is a paramater that come from usermode.

The user is passing an output buffer which is a region of memory where the driver writes. So if this buffer is just the address of a HANDLE, then the copy is performed like this:

*(PHANDLE)UserOutputBuffer = *pKernelProcessHandle;

Or, the general case:

RtlCopyMemory(UserOutputBuffer, pKernelProcessHandle , sizeof(HANDLE));

Remember that a PID is a DWORD (always 32 bits long like a ULONG) in user mode but a PID is a HANDLE in kernel mode (64 bits long in x64). Here the input buffer is a PULONG:

HANDLE Pid = (HANDLE)*(PULONG)UserInputBuffer;

Or you convert the DWORD to a HANDLE in user mode before the IOCTL code is issued, and then the input buffer is a PHANDLE:

HANDLE Pid = *(PHANDLE )UserInputBuffer;

You decide whether the conversion is made in user mode or in kernel mode.

Sorry there was errors in the previous post (I used pKernelProcessHandle instead of KernelProcessHandle). Forget it please:

ProcessHandle = is a paramater that come from usermode.

The user is passing an output buffer which is a region of memory where the driver writes. So if this buffer is just the address of a HANDLE, then the copy is performed like this:

*(PHANDLE)UserOutputBuffer = KernelProcessHandle;

Or, the general case:

RtlCopyMemory(UserOutputBuffer, &KernelProcessHandle , sizeof(HANDLE));

Remember that a PID is a DWORD (always 32 bits long like a ULONG) in user mode but a PID is a HANDLE in kernel mode (64 bits long in x64). Here the input buffer is a PULONG:

HANDLE Pid = (HANDLE)*(PULONG)UserInputBuffer;

Or you convert the DWORD to a HANDLE in user mode before the IOCTL code is issued, and then the input buffer is a PHANDLE:

HANDLE Pid = *(PHANDLE )UserInputBuffer;

You decide whether the conversion is made in user mode or in kernel mode.

Thank you people. Finaly fix it.
thank you a lot.

@Slava_Imameev said:

For the UserMode access mode you should provide the object type for ObOpenObjectByPointer. Also get rid of FILE_ALL_ACCESS in favor of PROCESS_ALL_ACCESS.

#include <wdm.h> // for PsProcessType declaration
OR
extern POBJECT_TYPE* PsProcessType;

status = ObOpenObjectByPointer(eProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType,
UserMode,&(*data).ProcessHandle);

I hope data is allocated in the kernel space and not a user space pointer.

How come that my code still causes BSOD even though I have the same way of getting a handle to a process.

My code:

				PEPROCESS processToHijack;
				HANDLE procHandle = NULL;
				status = PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(SysHandleTable->Handles[i].ProcessId), &processToHijack);
				if (NT_SUCCESS(status))
				{
					status = ObOpenObjectByPointer(processToHijack, NULL, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &procHandle);
					
					if (NT_SUCCESS(status))
					{
                                                 // do stuff
					}
					DbgPrintEx(0, 0, "Error: %x", status);
				}
				ZwClose(procHandle);
				ObDereferenceObject(processToHijack);
			}

Why does my code which is similar to your functioning code BSOD my computer?

My Code:
PEPROCESS processToHijack;
HANDLE procHandle = NULL;

				status = PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(SysHandleTable->Handles[i].ProcessId), &processToHijack);
				if (NT_SUCCESS(status))
				{
					status = ObOpenObjectByPointer(processToHijack, NULL, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &procHandle);
					
					if (NT_SUCCESS(status))
					{

					}
					DbgPrintEx(0, 0, "Error: %x", status);
				}
				ZwClose(procHandle);
				ObDereferenceObject(processToHijack);

You have resurrected a thread that is nearly 5 years old. Please post a new question, and include detailed information about the BSOD. There could be any number of strange problems here.