NtReadFile not properly reading the file

551 Views Asked by At

I am attempting to read ntdl.dll from disk using the NtReadFile native call. A handle has already been acquired through the NtCreateFile native call. However, when I attempt to read it using NtReadFIle, it neither fails nor succeeds. I try to print out the NtStatus, but there's nothing, as it looks like the call never actually completes. It does seem to work with the ReadFile Win API call, so not quite sure why the native call isn't working.

In the debugger, it seems like an unhandled exception is raised when transitioning back to userland after making the syscall, so not sure what is going on. Below is a snippet of the code.

#define OBJ_CASE_INSENSITIVE 0x00000040
#define FILE_OPEN 0x00000001 
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_RANDOM_ACCESS   0x00000800
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_SYNCHRONOUS_IO_NONALERT   0x00000020

SIZE_T bytesWritten = 0;
DWORD oldProtection = 0;
//HANDLE file = NULL;
HANDLE file = NULL;
ULONG fileSize = NULL;
LPDWORD bytesRead = NULL;
PVOID fileData = NULL;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING f;
IO_STATUS_BLOCK IoStatusBlock;

WCHAR ntdl[100] = L"\\?\\c:\\windows\\system32\\ntdll.dll";
WCHAR filepath[100] = L"\\??\\c:\\windows\\system32";
RtlInitUnicodeString(&f, ntdl);
InitializeObjectAttributes(&oa, &f, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS stat = NtCreateFile(&file, FILE_GENERIC_READ, &oa, &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 0, 0);

fileSize = GetFileSize(file, NULL);
fileData = HeapAlloc(GetProcessHeap(), 0, fileSize);
NTSTATUS stat1 = NtReadFile(file, NULL, NULL, NULL, &IoStatusBlock, fileData, sizeof(fileData), 0, NULL);

if (stat1 != 0)
    {
        printf("failed: %X\n", stat1);
    }
2

There are 2 best solutions below

0
LethalSnake1337 On

Instead of sizeof(fileData) pass the fileSize and initialize + pass the ByteOffset value of 0.

LARGE_INTEGER liBytes = { 0 };
status = SysNtReadFile(file, NULL, NULL, NULL, &statusBlock, fileData, fileSize, &liBytes, NULL);
0
YangHaoi On

And, In code line

fileData = HeapAlloc(GetProcessHeap(), 0, fileSize);

the third parameter should be set HEAP_ZERO_MEMORY, not 0. See nf-heapapi-heapalloc