Skip to content

Instantly share code, notes, and snippets.

@ASkyeye
Forked from whokilleddb/LowNtReadFile.c
Created August 13, 2025 00:34
Show Gist options
  • Save ASkyeye/8f04aed64efc6eadbf1473c001b51be5 to your computer and use it in GitHub Desktop.
Save ASkyeye/8f04aed64efc6eadbf1473c001b51be5 to your computer and use it in GitHub Desktop.

Revisions

  1. @whokilleddb whokilleddb created this gist Aug 12, 2025.
    109 changes: 109 additions & 0 deletions LowNtReadFile.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,109 @@
    #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;
    }