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…
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
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…
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 .
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.
…
}
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 >
> 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:
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:
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.
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);
}
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.