Created
August 12, 2025 21:19
-
-
Save whokilleddb/a6de6e54e78cc0b667784c60396a1023 to your computer and use it in GitHub Desktop.
Read contents of a file using LowNtReadFile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <winternl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#pragma comment(lib, "ntdll.lib") | |
#define FILE_TO_READ L"\\??\\C:\\Users\\DB\\Desktop\\test.txt" | |
EXTERN_C NTSTATUS NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions); | |
EXTERN_C VOID RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString); | |
EXTERN_C NTSTATUS NtClose(HANDLE Handle); | |
EXTERN_C NTSTATUS NtReadFile(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(NTAPI* PLowNtReadFile)(HANDLE FileHandle, LARGE_INTEGER byteoffset, PVOID Buffer, ULONG Length, LPDWORD unimp); | |
void UseNt(HANDLE hFile) { | |
LARGE_INTEGER byteOffset = { 0 }; | |
char buffer[4096] = { 0 }; | |
OBJECT_ATTRIBUTES objAttributes = { 0 } ; | |
IO_STATUS_BLOCK ioStatusBlock = { 0 }; | |
InitializeObjectAttributes(&objAttributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL); | |
NTSTATUS status = NtReadFile(hFile, | |
NULL, | |
NULL, | |
NULL, | |
&ioStatusBlock, | |
buffer, | |
sizeof(buffer) - 1, | |
&byteOffset, | |
NULL); | |
if (NT_SUCCESS(status)) { | |
printf("[+] File contents:\t%s\n", buffer); | |
} | |
else { | |
printf("[-] NtReadFile() failed: 0x%08X\n", status); | |
} | |
} | |
void UseLowNt(HANDLE hFile) { | |
LARGE_INTEGER byteOffset = { 0 }; | |
HMODULE hDmutil = LoadLibraryW(L"dmutil.dll"); | |
if (hDmutil == NULL) { | |
printf("[+] Failed to load dmutil.dll: 0x%lx\n", GetLastError()); | |
return; | |
} | |
printf("[+] Loaded dmutil.dll into current process\n"); | |
PLowNtReadFile LowNtReadFile = (PLowNtReadFile)GetProcAddress(hDmutil, "LowNtReadFile"); | |
if (LowNtReadFile == NULL) { | |
printf("[-] GetProcAddress() failed: 0x%lx\n", GetLastError()); | |
if (hDmutil) FreeLibrary(hDmutil); | |
return; | |
} | |
printf("[+] LowNtReadFile(): 0x%p\n", LowNtReadFile); | |
char buffer[4096] = { 0 }; | |
DWORD temp = 0; | |
NTSTATUS status = LowNtReadFile(hFile, byteOffset, buffer, sizeof(buffer) - 1, &temp); | |
if (NT_SUCCESS(status)) { | |
printf("[+] File contents:\t%s\n", buffer); | |
} | |
else { | |
printf("[-] LowNtReadFile() failed: 0x%08X\n", status); | |
} | |
if (hDmutil) FreeLibrary(hDmutil); | |
} | |
int main() {; | |
NTSTATUS status; | |
HANDLE hFile = NULL; | |
UNICODE_STRING fileName; | |
IO_STATUS_BLOCK ioStatusBlock; | |
OBJECT_ATTRIBUTES objAttributes; | |
RtlInitUnicodeString(&fileName, FILE_TO_READ); | |
InitializeObjectAttributes(&objAttributes, &fileName, OBJ_CASE_INSENSITIVE, NULL, NULL); | |
// Open the file | |
status = NtOpenFile(&hFile, | |
GENERIC_READ | SYNCHRONIZE | GENERIC_ALL, | |
&objAttributes, | |
&ioStatusBlock, | |
FILE_SHARE_READ, | |
FILE_SYNCHRONOUS_IO_NONALERT); | |
if (!NT_SUCCESS(status)) { | |
printf("[-] NtOpenFile() failed: 0x%08X\n", status); | |
return -1; | |
} | |
printf("[+] Sccessfully opened:\t%S\n\n", FILE_TO_READ); | |
printf("[+] Reading File Contents using NtReadFile()\n"); | |
UseNt(hFile); | |
printf("\n[+] Reading File Contents using LowNtReadFile()\n"); | |
UseLowNt(hFile); | |
if (hFile) NtClose(hFile); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment