When you double-click an EXE, the OS loader allocates virtual memory, maps these sections to specific addresses, resolves the IAT by loading required DLLs into the process space, applies base relocations, and finally jumps to the Entry Point. The Nature of Shellcode
The resulting .bin file can now be loaded directly into memory and executed via any standard shellcode runner. Method 2: Writing Native Position-Independent Code in C
Once we have the shellcode, we can inject it into a vulnerable process to execute the malicious code.
A standard Windows EXE file relies on the Portable Executable (PE) format. This format includes headers, section tables, and import address tables (IAT) that tell the Windows Loader how to map the file into memory and resolve dependencies like kernel32.dll .
Several automated tools can wrap an existing EXE or DLL into a shellcode loader: convert exe to shellcode
This guide explores the methods, tools, and technical challenges of transforming a standalone executable into functional shellcode. Understanding the Difference: EXE vs. Shellcode
# Align to page boundary subprocess.run(["msvc", "-c", "example.bin.noheader", "-Fo", "example.bin.aligned"])
Available on GitHub - TheWover/donut and as a Kali Linux package .
: A tool by hasherezade that converts a PE file into a functional shellcode while keeping the output a valid PE. sRDI (Reflective DLL Injection) When you double-click an EXE, the OS loader
Then, compile it. The simplest method is to use the Visual Studio solution file: open donut.sln and build the solution in "Release" mode. This will generate donut.exe in the main directory.
# Remove headers and metadata subprocess.run(["dd", "if=example.bin", "of=example.bin.noheader", "bs=1", "skip=64"])
git clone https://github.com/TheWover/donut.git cd donut
Standard EXEs rely on the OS to set up memory sections and resolve imports (like DLLs). A standard Windows EXE file relies on the
The choice of tool depends on your specific goal. Here is a summary to help you decide:
Standard strings are placed in the .rdata section of a PE file, resulting in absolute addressing. In PIC, strings must be declared as stack-allocated byte arrays (e.g., char cmd[] = 'c','m','d','\0'; ).
In real-world red-team assessments, further obfuscation is often used to bypass advanced security products. Tools like are designed for this purpose, acting as a script that wraps numerous packers (like UPX, Hyperion) and obfuscators into a single pipeline. It can accept an EXE, apply a "daisy chain" of packers (e.g., Hyperion then UPX), and optionally convert the final result to shellcode with Donut, all in one automated process.
Use a simple C++ shellcode runner to load payload.bin into memory and execute it to verify functionality. If you'd like to dive deeper, let me know: Are you working with C++ or .NET ? Do you need to bypass antivirus (AV) or EDR?
If you are developing your own code specifically to be used as shellcode, you can extract it manually: hasherezade/pe_to_shellcode: Converts PE into a shellcode