Windows Driver/Rootkit Development - function pointer - STATUS_INVALID_PARAMETER

This is quite a difficult problem to explain online, but I can’t figure out what’s going on and I really need help, so here goes!

Basically, I have written a security software (as a kernel driver) that will eventually hook every method in the SSDT (System Service Descriptor Table) for Windows XP - 32 bit. Everytime a system call is made, I log it in a file.

My issue arose when I hooked ZwOpenFile because that is a system call that MY code also makes to open the log file to write to it. So I got a Kernel stack overflow error because something would call ZwOpenFile, then I would try log it, and my logger (which is part of my driver) would then call ZwOpenFile which would then call ZwOpenFile (to log my logger) and so on and so forth until I had filled up the Stack enough to cause a blue screen of death.

In order to get around this, I decided, that everytime the logger function is called, it will also be supplied with a pointer to the old, unhooked, ZwOpenFile function so it could call that directly rather than go through my hooked function and create a recursive mess. However, when the logger calls the ZwOpenFile function pointer that it is supplied with as a parameter, it gets a STATUS_INVALID_PARAMETER error. If the ZwOpenFile is called directly (as opposed to through the pointer) it works perfectly! But when the pointer to what should be the same function with the SAME parameters is called, it throws the STATUS_INVALID_PARAMETER error code! However, the pointer must be pointing to the correct function as otherwise it wouldn’t throw this Windows error message. Here’s small and (hopefully) digestible snippets of my code to make more sense:

*mydriver.h*
#define UNICODE
#define _UNICODE
#include <ntddk.h>
#include <ntstrsafe.h>

#define OPEN_FILE_INDEX 0x74

NTSTATUS newZwOpenFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions);

typedef NTSTATUS (ZwOpenFilePtr)(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions);

mydriver.c
#include “mydriver.h”
#include “filehandling.c”

//global definition of pointer at top of mydriver.c file
ZwOpenFilePtr oldZwOpenFile;

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath){


//hooks the SSDT using the index of ZwOpenFile in the SSDT
oldZwOpenFile = (ZwOpenFilePtr)hookSSDTWithIndex(OPEN_FILE_INDEX, (BYTE
)newZwOpenFile, (DWORD*)systemCallTable);


}

//inside the method body of every hooked function, there is, at some point, the a call to the logger.
//This is shown in the context of newZwOpenFile
NTSTATUS newZwOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions){

driverWriteFile(&uFullString, &uProcess, *oldZwOpenFile);

}

filehandling.c
#include <ntstrsafe.h>

//the logger file
//the function doing the opening and writing
NTSTATUS driverWriteFile(PUNICODE_STRING stringToLog, PUNICODE_STRING filename, NTSTATUS (*fileOpenFunction)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG)) {

//the failing call that returns c000000d
ntstatus = fileOpenFunction(&handle, FILE_APPEND_DATA, &objAttr, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT);

}
What’s more is, that, all the hooked functions are spewing out the c000000d error (using DbgPrint), but once or twice, it does somehow succeed… Any help or suggestions would be HUGELY appreciated!</ntstrsafe.h></ntstrsafe.h></ntddk.h>

Of course you are in an area that is no longer supported nor was it
really supported back in the XP 32 days so don’t expect very much
positive response on this topic. But there is a myriad of things which
could be happening. What I suggest is to keep it simple, just patch the
SSDT entry points and call the real function directly from your patch
routine, nothing extra, just a pass through routine. Get this working
first and then move on to doing other work in your routine. As for your
logger, you can do several things to recognize your process is calling,
all pretty ugly in the end. For example, you could do some sort of name
mangling that your patched routine would recognize and redirect it to
the real routine with the correct name. Yes, not ideal but it does work.

Pete


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

------ Original Message ------
From: xxxxx@hotmail.com
To: “Windows System Software Devs Interest List”
Sent: 4/20/2017 6:25:35 AM
Subject: [ntdev] Windows Driver/Rootkit Development - function pointer -
STATUS_INVALID_PARAMETER

>This is quite a difficult problem to explain online, but I can’t figure
>out what’s going on and I really need help, so here goes!
>
>Basically, I have written a security software (as a kernel driver) that
>will eventually hook every method in the SSDT (System Service
>Descriptor Table) for Windows XP - 32 bit. Everytime a system call is
>made, I log it in a file.
>
>My issue arose when I hooked ZwOpenFile because that is a system call
>that MY code also makes to open the log file to write to it. So I got a
>Kernel stack overflow error because something would call ZwOpenFile,
>then I would try log it, and my logger (which is part of my driver)
>would then call ZwOpenFile which would then call ZwOpenFile (to log my
>logger) and so on and so forth until I had filled up the Stack enough
>to cause a blue screen of death.
>
>In order to get around this, I decided, that everytime the logger
>function is called, it will also be supplied with a pointer to the old,
>unhooked, ZwOpenFile function so it could call that directly rather
>than go through my hooked function and create a recursive mess.
>However, when the logger calls the ZwOpenFile function pointer that it
>is supplied with as a parameter, it gets a STATUS_INVALID_PARAMETER
>error. If the ZwOpenFile is called directly (as opposed to through the
>pointer) it works perfectly! But when the pointer to what should be the
>same function with the SAME parameters is called, it throws the
>STATUS_INVALID_PARAMETER error code! However, the pointer must be
>pointing to the correct function as otherwise it wouldn’t throw this
>Windows error message. Here’s small and (hopefully) digestible snippets
>of my code to make more sense:
>
>mydriver.h
> #define UNICODE
> #define _UNICODE
> #include <ntddk.h>
> #include <ntstrsafe.h>
>
> #define OPEN_FILE_INDEX 0x74
>
> NTSTATUS newZwOpenFile(
> PHANDLE FileHandle,
> ACCESS_MASK DesiredAccess,
> POBJECT_ATTRIBUTES ObjectAttributes,
> PIO_STATUS_BLOCK IoStatusBlock,
> ULONG ShareAccess,
> ULONG OpenOptions);
>
> typedef NTSTATUS (ZwOpenFilePtr)(
> PHANDLE FileHandle,
> ACCESS_MASK DesiredAccess,
> POBJECT_ATTRIBUTES ObjectAttributes,
> PIO_STATUS_BLOCK IoStatusBlock,
> ULONG ShareAccess,
> ULONG OpenOptions);
>
>mydriver.c
> #include “mydriver.h”
> #include “filehandling.c”
>
> //global definition of pointer at top of mydriver.c file
> ZwOpenFilePtr oldZwOpenFile;
>
> NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING
>pRegistryPath){
> …
> …
> //hooks the SSDT using the index of ZwOpenFile in the SSDT
> oldZwOpenFile =
>(ZwOpenFilePtr)hookSSDTWithIndex(OPEN_FILE_INDEX, (BYTE
)newZwOpenFile,
>(DWORD*)systemCallTable);
> …
> …
> }
>
> //inside the method body of every hooked function, there is, at
>some point, the a call to the logger.
> //This is shown in the context of newZwOpenFile
> NTSTATUS newZwOpenFile(PHANDLE FileHandle, ACCESS_MASK
>DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK
>IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions){
> …
> driverWriteFile(&uFullString, &uProcess, *oldZwOpenFile);
> …
> }
>
>filehandling.c
> #include <ntstrsafe.h>
>
> //the logger file
> //the function doing the opening and writing
> NTSTATUS driverWriteFile(PUNICODE_STRING stringToLog,
>PUNICODE_STRING filename, NTSTATUS
>(*fileOpenFunction)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG))
>{
> …
> //the failing call that returns c000000d
> ntstatus = fileOpenFunction(&handle, FILE_APPEND_DATA, &objAttr,
>&ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE,
>FILE_SYNCHRONOUS_IO_NONALERT);
> …
> }
>What’s more is, that, all the hooked functions are spewing out the
>c000000d error (using DbgPrint), but once or twice, it does somehow
>succeed… Any help or suggestions would be HUGELY appreciated!
>
>—
>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:></ntstrsafe.h></ntstrsafe.h></ntddk.h>

What I’m currently doing in each hooked function is very simple. I just log that the function was called and which process it was called by and then call the original function. I don’t understand what you mean by “name mangling”, could you provide a more concrete example? How do I recognise that my code is calling the logger (or vice versa) as my code (inc logger) is running as a driver, so the process making the call will appear as svchost.exe surely.