简体   繁体   中英

Windows C++ API: How do I read an entire binary file into a buffer?

  • OS: Windows 10
  • Target Platform: x86

I'm trying to load the entire contents of an arbitrary-length binary file into a character array. The contents of this array will later be copied into a memory location reserved with VirtualAlloc . Here is my code so far:

#include <windows.h>
#include <fileapi.h>
#include <tchar.h>

int __cdecl _tmain(int argc, TCHAR* argv[])
{
    HANDLE payload;
    if (argc != 2) {
        _tprintf(TEXT("Usage: runp.exe [payload_file]\nExecutes the specified binary payload.\n"));
        return 0;
    }
    _tprintf(TEXT("[*] Loading binary payload: %s\n"), argv[1]);
    payload = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
    if (payload == INVALID_HANDLE_VALUE) {
        _tprintf(TEXT("[!] Could not open payload: %s\n"), argv[1]);
    }
    else {
        DWORD size = GetFileSize(payload, NULL);
        _tprintf(TEXT("[*] Payload found: %d bytes.\n"), size);

        // TROUBLE STARTS HERE
        LPDWORD bytes_read = 0;
        char* buffer = new char[size + 1];
        if (FALSE == ReadFile(payload, buffer, size, bytes_read, NULL)) {
            _tprintf(TEXT("[!] Could not read payload!\n"));
        }
        else {
            _tprintf(TEXT("[*] Payload read!\n"));
        }
        delete[] buffer;
        // TROUBLE ENDS HERE

    }
    CloseHandle(payload);
    return 0;
}

Here's an example of how it fails:

PS C:\path\to\binary> echo "Demonstration file." > demo.file
PS C:\path\to\binary> .\runp.exe .\demo.file
[*] Loading binary payload: .\demo.file
[*] Payload found: 44 bytes.
[!] Could not read payload!

The program correctly detects and identifies the size of the binary file, yet I am unable to read the contents of the file into my custom-sized buffer.

C++ on Windows is not my native language. Python is more my speed, but I don't have a choice here. Any help would be much appreciated.

With everyone's help, I was able to overcome the issues I was having with my code. I wasn't able to entirely remove all the TCHAR stuff per selbie 's suggestion, as the CreateFile function wouldn't accept a character array for the filename, nor compile without using a _tmain format for the main function. (Again, C++ on Windows isn't my native language, so doubtless there's a better way to achieve this.) But I did add the \0 (null byte) to terminate the buffer contents. I also incorporated changes suggested by Retired Ninja and Mark Ransom . Here's the code after these changes were applied:

#include <windows.h>
#include <fileapi.h>
#include <stdio.h>
#include <tchar.h>

int __cdecl _tmain(int argc, TCHAR* argv[])
{
    HANDLE payload;
    if (argc != 2) {
        printf("Usage: runp.exe [payload_file]\nExecutes the specified binary payload.\n");
        return 0;
    }
    printf("[*] Loading binary payload: %ws\n", argv[1]);
    payload = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (payload == INVALID_HANDLE_VALUE) {
        printf("[!] Could not open payload: %ws\n", argv[1]);
    }
    else {
        DWORD size = GetFileSize(payload, NULL);
        DWORD bytes_read = 0;
        char* buffer = new char[size + 1];
        if (FALSE == ReadFile(payload, buffer, size, &bytes_read, NULL)) {
            printf("[!] Could not read payload!\n");
        }
        else {
            buffer[bytes_read] = '\0';
            printf("[*] %d bytes read.\n[*] File contents:\n\n%s\n", bytes_read, buffer);
        }
        delete[] buffer;
    }
    CloseHandle(payload);
    return 0;
}

Here is a demonstration of the program in action:

C:\path\to\binary>echo Demonstration! > test.txt

C:\path\to\binary>type test.txt
Demonstration!

C:\path\to\binary>runp.exe test.txt
[*] Loading binary payload: test.txt
[*] 17 bytes read.
[*] File contents:

Demonstration!

Thanks again to everyone for your helpful suggestions!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM