ObReferenceObjectByHandle - STATUS_INVALID_HANDLE

Hi all,

I’m playing with writing a security software (for fun) and have hit a brick wall. I’ve read & read but am having difficulty on passing a UserMode Event HANDLE to Kernel Mode.

ObReferenceObjectByHandle keeps returning 0xc0000008 - STATUS_INVALID_HANDLE.

I know I must be very close and overlooking something simple…

UserMode creates the unnamed event HANDLE successfully:

procLaunched.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (procLaunched.hEvent == INVALID_HANDLE_VALUE) {
ShowLastError();
return FALSE;
}

Then passes it to Kernel Mode through IOCTL:

result = DeviceIoControl(
device,
IOCTL_EVENT_READY,
&procLaunched,
sizeof(REGISTER_EVENT),
NULL, 0, &ignore, NULL);
if(!result) {
ShowLastError();
return FALSE;
}

Which gets picked up in Kernel Mode:

PREGISTER_EVENT registerEvent;
PKEVENT pEvent;

registerEvent = (PREGISTER_EVENT)Irp->AssociatedIrp.SystemBuffer;

status = ObReferenceObjectByHandle(
registerEvent->hEvent,
EVENT_MODIFY_STATE,
*ExEventObjectType,
Irp->RequestorMode,
&pEvent,
NULL);

Which is where I hit the problem of STATUS_INVALID_HANDLE.

Please help me find out why the handle is invalid?

You shouldn’t specify Irp->RequestorMode, 'cause Irp->RequestorMode is actually UserMode.
Just change the access mode to KernelMode.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@optusnet.com.au
Sent: Tuesday, October 26, 2010 3:39 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] ObReferenceObjectByHandle - STATUS_INVALID_HANDLE

Hi all,

I’m playing with writing a security software (for fun) and have hit a brick wall. I’ve read & read but am having difficulty on passing a UserMode Event HANDLE to Kernel Mode.

ObReferenceObjectByHandle keeps returning 0xc0000008 - STATUS_INVALID_HANDLE.

I know I must be very close and overlooking something simple…

UserMode creates the unnamed event HANDLE successfully:

procLaunched.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (procLaunched.hEvent == INVALID_HANDLE_VALUE) {
ShowLastError();
return FALSE;
}

Then passes it to Kernel Mode through IOCTL:

result = DeviceIoControl(
device,
IOCTL_EVENT_READY,
&procLaunched,
sizeof(REGISTER_EVENT),
NULL, 0, &ignore, NULL);
if(!result) {
ShowLastError();
return FALSE;
}

Which gets picked up in Kernel Mode:

PREGISTER_EVENT registerEvent;
PKEVENT pEvent;

registerEvent = (PREGISTER_EVENT)Irp->AssociatedIrp.SystemBuffer;

status = ObReferenceObjectByHandle(
registerEvent->hEvent,
EVENT_MODIFY_STATE,
*ExEventObjectType,
Irp->RequestorMode,
&pEvent,
NULL);

Which is where I hit the problem of STATUS_INVALID_HANDLE.

Please help me find out why the handle is invalid?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks for the assist but same result. I’m running in VMWare Win7 x64 if the virtualisation makes any difference?

I just can’t put my finger on what’s wrong…

> Please help me find out why the handle is invalid?

IRP is processed synchronously? In same thread?
IOCTL_EVENT_READY defined as BUFFERED-request?
And check alignment of your structure REGISTER_EVENT: value of HANDLE are identical in user and kernel modes?.

Thanks for the tips Alexey, excuse me if I don’t understand some of the terminology full yet - I’m learning.

IRP is processed synchronously - YES.
In same thread - YES.

IOCTL_EVENT_READY defined as BUFFERED-request - YES:
#define IOCTL_EVENT_READY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)

And check alignment of your structure REGISTER_EVENT:
Good thinking, just checked:
User mode = 0x0000005c
Kernel mode = 0x8001 (I get the feeling my DbgPrint statement is wrong here:
DbgPrint(“Handle: 0x%x”, registerEvent->hEvent);

What “%?” value should I use for HANDLE?

> What “%?” value should I use for HANDLE?
For 32-bit systems such print format is correct. But it is better to use “%p” (HANDLE it is PVOID).

Try use directive alignment: http://msdn.microsoft.com/en-us/library/2e70t5y1(VS.80).aspx

Try to pack your structure on a one byte boundary, i.e.

#pragma pack (push, 1)

typedef struct TAG_FOO
{
HANDLE hEvent;
}FOO;

#pragma pack (pop)

OK, thanks for the hints with PRAGMA PACKin and alignment tests… It really highlighted the problem.

My structs were declared as:

//Event Types
typedef enum {
PROCESS_LAUNCHED,
DECISION_MADE
} EVENT_TYPE;

//Event holding structure
typedef struct _REGISTER_EVENT
{
EVENT_TYPE Type;
HANDLE hEvent;
} REGISTER_EVENT , *PREGISTER_EVENT;

In both USER and KERNEL MODE, and my suspicion is (caused by ignorance) that these are aligned/different lengths caused by the ENUM?

Anyway, after getting close but inconsistent results using #pragma pack, I removed the EVENT_TYPE enum and am doing better I think…

Will post back in a while.

Confirmed - I now have communication via events from User Mode -> Kernel Mode and back.

Thanks for all the help.

Since no one else asked I decided to give it a shot. I have used user event
handles for communications between drivers and applications, however you
failed to explain what communications are required. If the signaled event
is just used to have the app send a read or IoCtl to obtain more data, then
your design is faulty.

From what you have said about your code I did not see any posts about how
you are handling disappearing handles, processes, etc. Read this newsgroup
about this subject and review the event sample in the WDK. Ask more
questions if you don’t understand all the issues.

wrote in message news:xxxxx@ntdev…
> Confirmed - I now have communication via events from User Mode -> Kernel
> Mode and back.
>
> Thanks for all the help.
>
>

NOD - The design IS faulty as it stands. It can (and will) be cleaned up to use better methods like inverted call etc… However I’ve continued to learn throughout the process and find myself getting increasingly comfortable with the concepts - which is the main thing for me right now.

Disappearing handles/processes are somewhat handled right now, and I’ve reviewed fairly thoroughly the relevant samples and read books/forums etc…

I’ll be in touch when I need more clarification on something.