Position-Independent Shellcode Generator - Donut Compatible
FOR EDUCATIONAL AND AUTHORIZED SECURITY RESEARCH ONLY
This tool is designed for security professionals, penetration testers, and researchers conducting authorized security assessments. Unauthorized access to computer systems is illegal.
The author is not responsible for any misuse or damage caused by this tool.
- What is Midres?
- How It Works
- Features
- Building
- Usage
- Output Formats
- Examples
- Technical Deep Dive
- Troubleshooting
- License
Midres is a shellcode generator written in Rust that converts Windows executables (PE files) into position-independent shellcode. It's compatible with the Donut loader format.
- Takes a Windows executable (.exe or .dll)
- Converts it into raw shellcode
- The shellcode can be injected into any process and will run the original program
- Red Team Operations: Execute payloads in memory without touching disk
- Security Research: Study in-memory execution techniques
- Malware Analysis: Understand shellcode generation and injection
- Penetration Testing: Test endpoint detection capabilities
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MIDRES FLOW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββ ββββββββββββββββ ββββββββββββββββββββ β
β β Input β β Process β β Output β β
β β .exe β ββββΊ β & Encrypt β ββββΊ β Shellcode β β
β β .dll β β & Compress β β β β
β ββββββββββββ ββββββββββββββββ ββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SHELLCODE STRUCTURE
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Call Stub β DONUT_INSTANCE β Encrypted Payload β Loader β
β 5 bytes β 4752 bytes β Variable β ~13 KB β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Position-Independent Code (PIC) is code that can execute at any memory address without modification. Midres achieves this by:
- No Absolute Addresses: All jumps and calls use relative offsets
- Dynamic API Resolution: Windows APIs are found at runtime using PEB walking
- Self-Contained: Everything needed is embedded in the shellcode
| Feature | Description |
|---|---|
| π Encryption | Chaskey block cipher in CTR mode |
| π¦ Compression | LZ4 (fast) or Zstd (better ratio) |
| π‘οΈ AMSI Bypass | Bypasses Antimalware Scan Interface |
| π― Multi-Arch | x86, x64, or both combined |
| π Multiple Formats | Binary, C, Rust, Python, PowerShell, etc. |
| β‘ .NET Support | Full support for .NET Framework assemblies |
| Type | Architecture | Status |
|---|---|---|
| Native EXE | x86/x64 | β |
| Native DLL | x86/x64 | β |
| .NET EXE | Any | β |
| .NET DLL | Any | β |
| VBScript | Any | β |
| JScript | Any | β |
- Rust 1.70+ - Install from rustup.rs
- Windows 10/11 - Required for building
- Visual Studio Build Tools - For MSVC linker
# Clone the repository
git clone https://github.com/MidasRX/NovaLite.git
cd midres
# Build release binaries (optimized)
cargo build --release
# Binaries will be in:
# ./target/release/midres.exe (shellcode generator)
# ./target/release/injector.exe (process injector)# Debug build (faster compile, slower execution)
cargo build
# Release build with full optimization
cargo build --release
# Clean and rebuild
cargo clean; cargo build --release# Generate shellcode from an executable
midres.exe -i payload.exe -o shellcode.bin
# With verbose output
midres.exe -i payload.exe -o shellcode.bin -v# Inject into a process by name
injector.exe --shellcode shellcode.bin -n notepad.exe
# Inject into a process by PID
injector.exe --shellcode shellcode.bin -p 1234midres.exe [OPTIONS] --input <INPUT> --output <OUTPUT>
OPTIONS:
-i, --input <INPUT> Input PE/DLL/EXE file
-o, --output <OUTPUT> Output file path
-a, --arch <ARCH> Architecture [default: x64]
Values: x86, x64, x84 (both)
-f, --format <FORMAT> Output format [default: binary]
Values: binary, base64, c, rust, python,
powershell, csharp, hex, uuid
-e, --encrypt Enable encryption
-c, --compress <TYPE> Compression [default: lz4]
Values: none, lz4, zstd
-x, --exit <EXIT> Exit behavior [default: thread]
Values: thread, process, block
-b, --bypass <BYPASS> AMSI/ETW bypass [default: continue]
Values: none, abort, continue
--class <CLASS> .NET class name
--method <METHOD> .NET method or DLL export
--args <ARGS> Arguments for payload
--domain <DOMAIN> .NET AppDomain name
--runtime <RUNTIME> .NET runtime (v2.0.50727, v4.0.30319)
--thread Run EXE entrypoint as thread
--entropy <ENTROPY> Entropy level [default: 3]
1=none, 2=random, 3=full
-v, --verbose Verbose output
-h, --help Print help
Midres can output shellcode in multiple formats for easy integration:
Raw bytes, ready for injection.
unsigned char midres_shellcode[1234] = {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
// ...
};
unsigned int midres_shellcode_len = 1234;const MIDRES_SHELLCODE: [u8; 1234] = [
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
// ...
];midres_shellcode = b""
midres_shellcode += b"\x4d\x5a\x90\x00\x03\x00\x00\x00"
# ...
midres_shellcode_len = 1234[Byte[]] $MidresShellcode = @(
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00
# ...
)byte[] midresShellcode = new byte[1234] {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
// ...
};# Create shellcode from a .NET console application
midres.exe -i MyApp.exe -o payload.bin -v
# Output:
# [*] Initializing configuration...
# [+] Loaded input file: 12345 bytes
# [+] Module type: .NET EXE, Architecture: x64
# [+] Compressed: 12345 -> 8765 bytes (71.0%)
# [+] Generated shellcode: 25678 bytes
# [+] Written to: payload.bin# Specify class and method for a .NET DLL
midres.exe -i MyLibrary.dll -o payload.bin \
--class "MyNamespace.MyClass" \
--method "Execute" \
--args "arg1 arg2"# Generate shellcode from native DLL
midres.exe -i native.dll -o payload.bin --method "DllMain"# Output as PowerShell script
midres.exe -i payload.exe -o loader.ps1 -f powershell# Disable encryption for debugging
midres.exe -i payload.exe -o debug.bin --entropy 1 -c none -v+------------------+------------------------------------------+
| COMPONENT | DESCRIPTION |
+------------------+------------------------------------------+
| Call Stub | 5-byte relative call to loader |
| | E8 XX XX XX XX |
+------------------+------------------------------------------+
| DONUT_INSTANCE | 4752 bytes - Configuration & metadata |
| - Encryption | Chaskey keys, IV, counter |
| - API Hashes | MARU hashes for dynamic resolution |
| - Config | Compression, bypass, exit options |
| - Module | Embedded DONUT_MODULE (1328 bytes) |
+------------------+------------------------------------------+
| Payload Data | Compressed + Encrypted PE/DLL |
+------------------+------------------------------------------+
| Loader Code | ~13KB position-independent loader |
+------------------+------------------------------------------+
Midres uses MARU hash for API resolution - a modified DJB2 with 64-bit output:
fn maru_hash(input: &[u8], iv: u64) -> u64 {
let mut h: u64 = iv;
for &byte in input {
h = h ^ (byte as u64);
h = h.wrapping_mul(0x5bd1e995);
h = h ^ (h >> 15);
}
h
}- Algorithm: Chaskey lightweight block cipher
- Mode: CTR (Counter)
- Key Size: 128 bits (16 bytes)
- Block Size: 128 bits (16 bytes)
| Mode | Description |
|---|---|
thread |
Exit current thread only (stealthy) |
process |
Terminate entire process |
block |
Block forever (for persistent payloads) |
- Cause: Payload executed but returned immediately
- Fix: Ensure payload has staying power (loop, wait, or service)
- Cause: Missing dependencies or wrong runtime
- Fix:
- Use
--runtime v4.0.30319explicitly - Merge dependencies with ILMerge or Costura.Fody
- Use
- Cause: Insufficient privileges or protected process
- Fix: Run as Administrator or target different process
Generate unencrypted shellcode for analysis:
midres.exe -i payload.exe -o debug.bin --entropy 1 -c none -vmidres/
βββ Cargo.toml # Workspace configuration
βββ midres-gen/ # Main shellcode generator
β βββ src/
β βββ main.rs # CLI entry point
β βββ donut_instance.rs # Core structures
β βββ pe.rs # PE file parsing
β βββ crypto.rs # Chaskey encryption
β βββ compress.rs # LZ4/Zstd compression
β βββ output.rs # Format generation
β βββ bundle.rs # .NET bundle extraction
βββ midres-common/ # Shared types & constants
β βββ src/lib.rs
βββ map-injector/ # Process injection tool
βββ src/main.rs
- Donut - Original project by TheWover & odzhan
- CLR Injection - .NET in-memory techniques
- PEB Walking - Dynamic API resolution
MIT License - See LICENSE for details.
MIT License
Copyright (c) 2024-2026 MidasRX
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software...
β Star this repo if you find it useful! β
Made with π¦ by MidasRX