PHP NtCreateFile Example

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Code:
#include "stdafx.h"

#include <iostream>
#include <Windows.h>

typedef long NTSTATUS;

typedef struct _IO_STATUS_BLOCK {
   union {
      NTSTATUS Status;
      PVOID Pointer;
   } DUMMYUNIONNAME;

   ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _UNICODE_STRING {
   USHORT Length;
   USHORT MaximumLength;
   PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {
   ULONG           Length;
   HANDLE          RootDirectory;
   PUNICODE_STRING ObjectName;
   ULONG           Attributes;
   PVOID           SecurityDescriptor;
   PVOID           SecurityQualityOfService;
}  OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef NTSTATUS(__stdcall *_NtCreateFile)(
   PHANDLE FileHandle,
   ACCESS_MASK DesiredAccess,
   POBJECT_ATTRIBUTES ObjectAttributes,
   PIO_STATUS_BLOCK IoStatusBlock,
   PLARGE_INTEGER AllocationSize,
   ULONG FileAttributes,
   ULONG ShareAccess,
   ULONG CreateDisposition,
   ULONG CreateOptions,
   PVOID EaBuffer,
   ULONG EaLength
);

typedef VOID(__stdcall *_RtlInitUnicodeString)(
   PUNICODE_STRING DestinationString,
   PCWSTR SourceString
);

#define FILE_CREATE 0x00000002
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define OBJ_CASE_INSENSITIVE 0x00000040L

#define InitializeObjectAttributes( i, o, a, r, s ) {    \
      (i)->Length = sizeof( OBJECT_ATTRIBUTES );         \
      (i)->RootDirectory = r;                            \
      (i)->Attributes = a;                               \
      (i)->ObjectName = o;                               \
      (i)->SecurityDescriptor = s;                       \
      (i)->SecurityQualityOfService = NULL;              \
   }

int main()
{
   _NtCreateFile NtCreateFile = (_NtCreateFile) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateFile");
   _RtlInitUnicodeString RtlInitUnicodeString = (_RtlInitUnicodeString) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlInitUnicodeString");

   HANDLE hFile;
   OBJECT_ATTRIBUTES objAttribs = { 0 };

   std::cout << "Initializing unicode string..." << std::endl;
   PCWSTR filePath = L"\\??\\Z:\\NtCreateFileHook.output";
   UNICODE_STRING unicodeString;
   RtlInitUnicodeString(&unicodeString, filePath);

   std::cout << "Call to InitializeObjectAttributes for OBJECT_ATTRIBUTES data structure..." << std::endl;
   InitializeObjectAttributes(&objAttribs, &unicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL);

   std::cout << "Initializing LARGE_INTEGER for allocation size..." << std::endl;
   const int allocSize = 2048;
   LARGE_INTEGER largeInteger;
   largeInteger.QuadPart = allocSize;

   std::cout << "Calling NtCreateFile..." << std::endl;

   IO_STATUS_BLOCK ioStatusBlock = { 0 };
   NtCreateFile(&hFile, STANDARD_RIGHTS_ALL, &objAttribs, &ioStatusBlock, &largeInteger,
                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_CREATE, FILE_NON_DIRECTORY_FILE, NULL, NULL);
   if (hFile != NULL) CloseHandle(hFile);

   std::cout << "Done!" << std::endl;
   std::cin.get();
}

Here is an example I wrote on using the NtCreateFile method from ntdll.dll. Note, the output file size is 0bytes because this is only file creation, however lengthy the process just for file creation, looks.
 
Last edited:
Nice example Ace!

To expand slightly on where you might use this in practice (in standard usermode code), there exist a couple of file access functions which exist only in the Nt/Zw... form, and take a handle only from Nt/ZwCreateFile respectively.

The only place I've ever used this in practice (although I have used it in this scenario several times) is with the NtQueryInformationFile function, which exposes some information available in no other (simple) way in user mode code.

Richard
 
Another practical use would involve a hook to this function allowing you to load this with another existing process to see if it writes anything to disk for malware analysis as an example; specific, but still possibly useful. You could compile the code which defines the hook as a DLL and attach it to process X.
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top