#include <windows.h>
#include <stdio.h>
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define OBJ_KERNEL_HANDLE 0x00000200L
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef LONG NTSTATUS;
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; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef VOID (NTAPI *PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
typedef NTSTATUS (WINAPI *FnNtCreateFile)(
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 NTSTATUS (WINAPI *FnNtWriteFile)(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID Buffer,
ULONG Length,
PLARGE_INTEGER ByteOffset,
PULONG Key
);
typedef NTSTATUS (WINAPI *FnNtClose)(
HANDLE Handle
);
int main()
{
HMODULE hModule;
FnNtCreateFile pfnNtCreateFile;
FnNtWriteFile pfnNtWriteFile;
FnNtClose pfnNtClose;
hModule = LoadLibraryA("ntdll.dll"); /* always 0x7c900000 on XP */
if (hModule == NULL) {
return -1;
}
pfnNtCreateFile = (FnNtCreateFile)GetProcAddress(hModule, "NtCreateFile"); /* 0x7c90d090 */
pfnNtWriteFile = (FnNtWriteFile)GetProcAddress(hModule, "NtWriteFile"); /* 0x7c90df60 */
pfnNtClose = (FnNtClose)GetProcAddress(hModule, "NtClose"); /* 0x7c90cfd0 */
if (pfnNtCreateFile == NULL || pfnNtWriteFile == NULL || pfnNtClose == NULL) {
FreeLibrary(hModule);
return -1;
} else {
NTSTATUS ntStatus;
UNICODE_STRING us;
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK ioStatusBlock;
HANDLE hFile;
char szHello[] = "Hello World!";
us.Buffer = L"\\??\\C:\\test.txt";
us.Length = (USHORT)wcslen(us.Buffer) * sizeof(WCHAR);
us.MaximumLength = us.Length + sizeof(WCHAR);
oa.Length = sizeof(oa);
oa.RootDirectory = NULL;
oa.ObjectName = &us;
oa.Attributes = OBJ_KERNEL_HANDLE;
oa.SecurityDescriptor = NULL;
oa.SecurityQualityOfService = NULL;
ntStatus = pfnNtCreateFile(&hFile,
GENERIC_ALL | SYNCHRONIZE,
&oa,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (!NT_SUCCESS(ntStatus)) {
fprintf(stderr, "Failed to create file, error = 0x%x\n", ntStatus);
FreeLibrary(hModule);
return -1;
}
ntStatus = pfnNtWriteFile(hFile,
NULL,
NULL,
NULL,
&ioStatusBlock,
szHello,
(ULONG)strlen(szHello),
NULL,
NULL);
if (!NT_SUCCESS(ntStatus)) {
fprintf(stderr, "Failed to write file, error = 0x%x\n", ntStatus);
FreeLibrary(hModule);
return -1;
}
pfnNtClose(hFile);
}
FreeLibrary(hModule);
return 0;
}