views:

304

answers:

4

I read a very fascinating article that was about programming drivers using the wdk, and one of the functions it used is called ObReferenceObjectByName. This function has given me lots of headaches. The first bad thing is that it's not documented by microsoft. The second thing, is that the language used in the article was C++, and I want to keep my code in plain ol' C. I know that most of the time this shouldn't be a problem, but I haven't - for the life of me - been able to figure out how to include this function.

The code in the article goes something like:

extern "C"{

 #include <ntifs.h>


 NTSYSAPI NTSTATUS NTAPI ObReferenceObjectByName(PUNICODE_STRING ObjectName,

         ULONG Attributes,

         PACCESS_STATE AccessState,

         ACCESS_MASK DesiredAccess,

         POBJECT_TYPE ObjectType,

         KPROCESSOR_MODE AccessMode,

         PVOID ParseContext OPTIONAL,

         PVOID* Object);
}

I've been trying to replicate this for hours. I tried declaring it without the 'extern' keyword, I tried changing the calling convention, I tried changing the includes... I always end up with the error "unresolved external symbol...".

I'm absolutely stumped, so if anyone could offer some advice, I'd be grateful. Thanks.

A: 

I don't know this API, but I can give you a trick that might help you diagnose the problem.

at a command prompt that has MSVC tools in the path

link /dump /exports ???.dll

where ???.dll is the dll were you expect this function to be. This will give you a complete list of exported symbol names and will tell you two things. 1) is the symbol there? and 2) is it being decorated the same as your attempted prototype.

For 32 bit kernel, you should expect this to be called _ObReferenceObjectByName@64,

John Knoeller
+1  A: 

You wouldn't be reading http://www.codeproject.com/KB/recipes/keystroke-hook.aspx and trying to create your own Keyboard Logger would you?

Anyways, instead of using this, call ZwCreateFile then ObReferenceObjectByHandle instead.

Paul Betts
That is the article I read, but my end goal isn't a keyboard logger. I just found it interesting how you could change a MajorFunction in a driver. Thanks for the suggestion.
I suspect that this won't work in Vista/Win7 and it's certainly not safe to do since you can't properly guarantee that IOs won't be sent during your change, but for information purposes it's neato I guess.
Paul Betts
It is safe provided you are using atomic functions (InterlockedExchangePointer).
Sergius
The replace itself is safe, but things get really complex if you do anything nontrivial inside your hook, since you can't guarantee that a hooked IRP_MJ_READ's Irp was processed by your IRP_MJ_CREATE for example because there'll be a small window where you won't finish overwriting the dispatch table.
Paul Betts
A: 

Here is a test C code compiled and built with no problems:

#include <ntddk.h>

NTSYSAPI NTSTATUS NTAPI ObReferenceObjectByName(
    PUNICODE_STRING ObjectName,
    ULONG Attributes,
    PACCESS_STATE AccessState,
    ACCESS_MASK DesiredAccess,
    POBJECT_TYPE ObjectType,
    KPROCESSOR_MODE AccessMode,
    PVOID ParseContext OPTIONAL,
    PVOID* Object
    );

NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    ObReferenceObjectByName(0, 0, 0, 0, 0, 0, 0, 0);

    return STATUS_SUCCESS;
}
Sergius
A: 

would you please tell me how to get driver object by name without ObReferenceObjectByName? My code is below but it always failed after calling ZwOpenFile... [cpp] RtlInitUnicodeString(&uFileName,sDriverName);

InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL);

status = ZwOpenFile(&handle,GENERIC_READ,&obj_attrib,&file_status,
                        FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,FILE_OPEN,FILE_NON_DIRECTORY_FILE);
if ( !NT_SUCCESS ( status ) ){
    DbgPrint("Failed to create file handle for %ws\n",sDriverName);
    return status;
}
status = ObReferenceObjectByHandle(handle,FILE_ALL_ACCESS,NULL,KernelMode,(PVOID*)&pDriverObj,NULL);
if ( !NT_SUCCESS ( status ) ){
    DbgPrint(" Failed to get object reference by handle\n");
    return status ;
}

[/cpp]

Arsalan