Convert Exe To Shellcode ((full)) -
Short guide: convert a Windows EXE to position-independent shellcode
Warning: Running or generating shellcode can be dangerous. Only work with binaries you own or have explicit permission to analyze. I provide a high-level, lawful-usage guide and reproducible steps for research, reverse engineering, or red-team testing in controlled environments.
Prerequisites
- Windows PE (EXE) binary you control.
- A Linux or Windows analysis machine with:
- Python 3
- pefile (Python library)
- mingw-w64 (for cross-building, optional)
- msfvenom (part of Metasploit) — optional helper
- Donut (https://github.com/TheWover/donut) or sRDI/Reflective DLL loader if using DLLs
- x64dbg/OllyDbg/IDA/Ghidra for static analysis (recommended)
- A sandbox/VM to test (e.g., isolated Windows VM, snapshots)
High-level approaches (pick one)
- Pack EXE into a single-stage shellcode payload that:
- Allocates memory in target process
- Writes the EXE bytes
- Performs manual loading (rebuilds sections, resolves imports, calls entry point)
- Or drops the EXE to disk and executes it (simple but leaves disk traces)
- Use a reflective loader (common for DLLs) — convert EXE to DLL or wrap logic into DLL, then use reflective loader shellcode to load it in-memory.
- Use a tool (Donut / msfvenom) to produce shellcode that executes a PE in-memory (Donut supports EXE/NET/PE).
Step-by-step: Method A — Donut (fast, recommended)
- Get Donut:
- git clone https://github.com/TheWover/donut
- Build per project README to produce donut binary.
- Generate shellcode:
- Example for an EXE:
- donut.exe -f 1 -a 2 -p 1 -o payload.bin myprogram.exe
- -f 1: shellcode format (native)
- -a 2: architecture (2 = x64) — match target
- -p 1: position-independent
- -o payload.bin: output raw shellcode
- Adjust args per Donut docs for .NET vs native and options.
- donut.exe -f 1 -a 2 -p 1 -o payload.bin myprogram.exe
- Example for an EXE:
- Test safely:
- Use a small C loader that allocates memory, copies payload.bin, and calls it. Compile in an isolated VM.
- Example (x64 Windows loader skeleton — compile with Visual Studio/mingw):
/* loader.c */ #include <windows.h> extern unsigned char shellcode[]; int main() void *mem = VirtualAlloc(NULL, /*size*/, MEM_COMMIT - Link shellcode into the loader or load from file at runtime.
- Verify behavior in sandbox VM and monitor for unwanted actions.
Step-by-step: Method B — Manual packer that drops-and-executes (simpler, less stealthy)
- Read EXE bytes into your packer program (C/Python).
- Embed them as a byte array inside a small shellcode stub that:
- Creates a temporary file via GetTempPath + GetTempFileName.
- Writes bytes to file (CreateFile/WriteFile).
- Calls CreateProcess or ShellExecute to run it.
- Optionally cleans up the file after execution.
- Convert the stub + embedded bytes into position-independent shellcode:
- Keep the stub small and avoid absolute addresses.
- Compile the stub to raw bytes (ensure no relocations or strip symbols).
- Use a tool to extract the raw code section (objcopy or a custom extractor).
- Deliver and test in VM.
Step-by-step: Method C — Manual in-memory PE loader (advanced, stealthy)
- Analyze EXE with pefile/Ghidra to find sections, entry point, import table.
- Shellcode responsibilities:
- Call VirtualAlloc to allocate enough RWX memory for the image size.
- Copy headers and sections into allocated memory at correct virtual addresses or relocate if needed.
- Apply base relocations when the allocated base differs from the image base.
- Resolve imports: parse IMAGE_IMPORT_DESCRIPTOR, load dependent DLLs (LoadLibraryA), resolve functions (GetProcAddress), and write addresses into IAT.
- If TLS callbacks exist, call them.
- Call the PE entry point (or exported function) with proper calling convention (for EXE, call entry point with HINSTANCE and other args as needed).
- Implement loader in position-independent assembly or C with syscall/WinAPI usage; compile and produce raw shellcode.
- Test intensely in a disposable sandbox.
Recommended tooling and snippets
- pefile (Python): parse headers, sections, imports, relocations.
- lief (Python/C++): manipulate PE programmatically.
- Donut: direct EXE → shellcode for many cases.
- msfvenom: generate stagers/shellcode (payloads, bind/reverse shells).
- objdump / r2 / radare2: inspect compiled shellcode bytes.
- sRDI / ReflectiveLoader: for DLL reflective loading.
Safety, testing, and troubleshooting
- Always test inside an isolated VM with no network or with controlled network.
- Use Procmon, x64dbg, and Wireshark to observe behavior.
- If shellcode crashes:
- Check calling convention and stack alignment.
- Verify imports/resolutions and relocation application.
- Ensure memory protections are correct (RWX may be needed temporarily).
- If antivirus flags payloads, try packing/obfuscation or use known loaders (Donut often bypasses some AVs but may still be detected).
Example minimal workflow (practical)
- Create/simple EXE: myprog.exe
- Use Donut: donut -f 1 -a 2 -o shell.bin myprog.exe
- Build small Windows loader that reads shell.bin into memory and executes it.
- Test in VM.
Further reading (tools to search)
- Donut, msfvenom, pefile, lief, reflective DLL injection, manual PE loader, VirtualAlloc/VirtualProtect, IMAGE_IMPORT_DESCRIPTOR, base relocations (IMAGE_BASE_RELOCATION).
If you want, I can:
- Provide a simple loader C source that loads a raw shellcode file and executes it (specify x86 or x64).
- Show a Python script using pefile to extract imports/sections for a custom loader. Which of those would you like?
Converting a standard .exe file into shellcode is not as simple as renaming the file or copying its bytes. A typical executable relies on the Operating System (OS) loader to handle complex tasks like memory allocation, resolving imports (DLLs), and base relocations. For an .exe to run as "shellcode," it must be converted into Position-Independent Code (PIC) that can execute from any memory address without these external OS dependencies. Common Tools for Conversion
Several specialized tools can automate the wrapping of an .exe into a shellcode-ready format: convert exe to shellcode
Donut: This is the industry-standard tool for converting VBScript, JScript, EXE, DLL, and .NET assemblies into position-independent shellcode for x86 and x64 systems.
Pe2shc: A popular tool that makes a PE (Portable Executable) file act as a shellcode. It prepends a small stub that handles the necessary loading and relocation tasks at runtime.
exec2shell: A utility used to extract the .text (executable code) section of a PE or ELF file and output it as a raw binary or C-style array.
msfvenom: Part of the Metasploit framework, it can generate various payloads and encode existing executables into shellcode formats. Manual Method: Extracting the .text Section
If you only need the raw machine instructions from the executable code section, you can use a Python script with the pefile library to extract the .text segment.
import pefile import sys # Load the EXE file pe = pefile.PE(sys.argv[1]) # Function to grab executable code from the .text section def grab_executable_code(): ops = "" for section in pe.sections: # Looking for the primary executable section if b'.text' in section.Name: for item in bytearray(section.get_data()): # Format bytes as \x00 for shellcode strings ops += f"\\xitem:02x" return ops print(grab_executable_code()) Use code with caution. Copied to clipboard Key Technical Challenges Short guide: convert a Windows EXE to position-independent
Embedding Shellcode in .text and .data section. | by Irfan Farooq
Step 3: Convert to Shellcode
To convert the EXE file to shellcode, you'll need to:
-
Remove headers and metadata: EXE files contain headers, section tables, and other metadata that aren't needed for shellcode. You can use a tool like
dumpbin(part of the Microsoft Visual Studio toolchain) to extract the raw binary data:
dumpbin /raw example.exe > example.bin
* **Fix the shellcode:** The resulting binary data might not be directly usable as shellcode. You may need to:
* **Remove DOS headers:** The DOS header is usually 64 bytes long. You can use a hex editor or a tool like `dd` to remove it:
```bash
dd if=example.bin of=example.bin.noheader bs=1 skip=64
* **Align to a page boundary:** Shellcode often needs to be aligned to a page boundary (usually 4096 bytes). You can use a tool like `msvc` to align the shellcode:
```bash
msvc -c example.bin.noheader -Fo example.bin.aligned
**Step 4: Verify the Shellcode**
------------------------------
Use a disassembler like `nasm` or `objdump` to verify the generated shellcode:
```bash
nasm -d example.bin.aligned -o example.asm
Converting EXE to Shellcode: A Step-by-Step Guide
-a 2 = x64, -a 1 = x86
Step 1 – Identify the PE Sections
Use dumpbin or a PE viewer (e.g., CFF Explorer) to examine your EXE:
.text: Executable code..data/.rdata: Read/write data and constants..reloc: Base relocation table (critical for ASLR).
Method 2: Manual Conversion – The Educational Path
Understanding manual conversion deepens your knowledge of PE structure and position-independent code. This method involves writing a custom "shellcode wrapper" that acts as a mini-loader.

