IOCTL sent to a driver without an endpoint

Hello,

This question is out of curiosity, and may not have any practical use (but who knows ?).

Imagine I create a windows kernel driver with no endpoint (i.e : no call to IoCreateSymbolicLink, nor IoCreateDevice), but still I fill pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] to register a handler for IOCTLs. Question is : can I send IOCTL to it from userland (or kernelland) ? If yes, how ? Subquestion : is it necessary to fill this array if I don’t register an endpoint ?

Thank you for your answer.

can i send IOCTL to it from userland…

No. How could you? How would you get a file handle to send the ioctl?

(or kernelland)?

No. How could you? If there’s no DEVICE_OBJECT, what would you pass to IoCallDriver?

1 Like

Mr. @a78 … WHY is this question in the Announcements and Administration forum? I mean, seriously…

Peter

No Device Object means you don’t have a driver. How would you do this, even?

Did you try it, before posting such a question here???

Peter

@“Peter_Viscarola_(OSR)” said:
Mr. @a78 … WHY is this question in the Announcements and Administration forum? I mean, seriously…

Peter

Wrong move obviously, sorry about that.

@“Peter_Viscarola_(OSR)” said:
No Device Object means you don’t have a driver. How would you do this, even?

Did you try it, before posting such a question here???

Peter

I don’t understand how I could “try” anything that I don’t know how to do, but in fact I have tried some things yes : I have found an existing device driver with this particular case : a IOCTL handler setup, but no endpoint registered, and I was just curious about it.

Mr. @a78 … I’m Moving this to NTDEV where it belongs.

Peter

I don’t understand how I could “try” anything that I don’t know how to do

You know, replies like that annoy me.

You wrote “Imagine I create a windows kernel driver with no endpoint (i.e : no call to IoCreateSymbolicLink, nor IoCreateDevice), but still I fill pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] to register a handler for IOCTLs.”

It would take you less time to try that, than to post your question here.

But I digress…

I have found an existing device driver with this particular case : a IOCTL handler setup, but no endpoint registered, and I was just curious about it.

Hmmmm… I don’t know what you mean by “endpoint”… so you’re gonna have to explain what you mean. That’s not a “standard” or typical Windows kernel-mode term.

I don’t know how you can have a driver that’s loaded but not have a Device Object associated with that driver. I just don’t.

Now, you could CERTAINLY have a driver loaded that has a Device Object is unnamed and that doesn’t export a Device Interface GUID and doesn’t create a Symbolic Link name for its Device object. That would effectively prevent the Device from being accessible from user mode. This is pretty commonly done in Filter Drivers.

Peter

Thank you for your answer.

You know, replies like that annoy me.

You wrote “Imagine I create a windows kernel driver with no endpoint (i.e : no call to IoCreateSymbolicLink, nor IoCreateDevice), but still I fill pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] to register a handler for IOCTLs.”

It would take you less time to try that, than to post your question here.

I am sorry but I don’t understand that intro. I did try that, and I checked that I wasn’t able to access it by the ways I am aware of. What could I have tried ?

I have found an existing device driver with this particular case : a IOCTL handler setup, but no endpoint registered, and I was just curious about it.

Hmmmm… I don’t know what you mean by “endpoint”… so you’re gonna have to explain what you mean. That’s not a “standard” or typical Windows kernel-mode term.

I agree. In first post I tried to clarify the terme “no endpoint” with : no call to IoCreateSymbolicLink, nor IoCreateDevice, so I have a driver, but no device created and no symbolic link.

I don’t know how you can have a driver that’s loaded but not have a Device Object associated with that driver. I just don’t.

Now, you could CERTAINLY have a driver loaded that has a Device Object is unnamed and that doesn’t export a Device Interface GUID and doesn’t create a Symbolic Link name for its Device object. That would effectively prevent the Device from being accessible from user mode. This is pretty commonly done in Filter Drivers.

Exactly, that’s what happens. I was thinking that maybe there was a way by which windows automatically generates a name by default, or something that I would not be aware of. Now I understand that the answer is no : there is no way to communicate with that driver, thank you for that.

Here’s the short answer. In Windows, you don’t send requests to a driver. You send requests to a device. If there’s no DEVICE_OBJECT, then there is no device, and that driver’s IRP dispatch routines will never be called. It’s just that simple.

maybe there was a way by which windows automatically generates a name by default

In fact, Windows will do this by default for PDOs (children of bus drivers — which is why you see useless names like PCI000021 and such on Device Objects), but not FDOs.

To answer this question with a bit more depth, if only for the archives: There are actually multiple “levels” of naming to consider. Native Device Object names (for PDOs and FDOs… they’re different), external symbolic links making the device easily accessible to user mode, and device interface GUIDs (which work out to be just another flavor of symbolic link — to the PDO — at the end of the day).

It is in fact needlessly complicated, and you can read a bit about it here (one of my favorite articles of all time).

An FDO that is both unnamed and has not created a symbolic link to its underlying PDO either directly or is creating a device interface can’t be directly targeted (even from kernel mode, without playing games like shipping the device object address around)…. but can still receive requests if something else in its Device Stack is targeted (and the request is not completed or sent to another Device Stack before it gets to the FDO in question). Again, this is how filter drivers usually work.

But…. you can’t have a driver instance without at least one Device Object instance. That is part of what you asked about, and was what I was suggesting you try, and you would see that the driver unloads immediately.

Peter

1 Like

Thank you for your answers.

you can’t have a driver instance without at least one Device Object instance. That is part of what you asked about, and was what I was suggesting you try, and you would see that the driver unloads immediately.

@“Peter_Viscarola_(OSR)” Can you explain this sentence? This is an empty driver without any device and it stays in memory until it’s manually unloaded:

#include <ntifs.h>

VOID
DriverUnload(
    __in PDRIVER_OBJECT Driver
    )
{
    UNREFERENCED_PARAMETER(Driver);
}

NTSTATUS
DriverEntry(
    __in PDRIVER_OBJECT Driver,
    __in PUNICODE_STRING Registry
    )
{
    UNREFERENCED_PARAMETER(Registry);

    Driver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

EDIT: I didn’t know that PnP drivers are unloaded automatically when their last device object is removed, thanks.