3 releases
Uses new Rust 2024
| 0.1.2 | Sep 12, 2025 |
|---|---|
| 0.1.1 | Sep 12, 2025 |
| 0.1.0 | Sep 12, 2025 |
#56 in Windows APIs
25 downloads per month
70KB
1.5K
SLoC
🍁 maple-rs
A Rust library for loading Windows PE executables and DLLs directly from memory, without needing to write them to disk first. This is a modern, memory-safe Rust replacement for the C memorymodule library.
Security Notice
This library enables loading and executing code from memory buffers. While this has legitimate uses such as:
- Dynamic code loading in game engines
- Plugin systems
- Testing and debugging tools
- Memory-efficient application packaging
Users are responsible for ensuring they only load trusted code and comply with all applicable laws and security policies.
Features
- 🔹 In-Memory Loading: Load PE executables (.exe) and libraries (.dll) directly from memory
- 🔹 Application DLL Support: Execute applications compiled as DLLs with proper threading
- 🔹 Full PE Support: Complete PE parsing, import resolution, and relocation processing
- 🔹 Native Execution: Code runs exactly as if loaded from disk
- 🔹 Memory Safety: Proper memory management with automatic cleanup
- 🔹 Cross-Platform Ready: Windows implementation complete, Linux planned
- 🔹 Zero-Copy: Efficient memory usage with minimal overhead
Quick Start
Add this to your Cargo.toml:
[dependencies]
maple-rs = "0.1.0"
Basic Usage
use maple_rs::{Maple, Result};
use std::fs;
fn main() -> Result<()> {
// Load an executable from memory
let data = fs::read("program.exe")?;
let module = Maple::load_executable_from_memory(&data)?;
// Execute the program's entry point
module.execute_entry_point()?;
Ok(())
}
Loading Regular DLLs
use maple_rs::{MemoryModuleBuilder, Result};
use std::fs;
fn main() -> Result<()> {
let data = fs::read("library.dll")?;
let module = MemoryModuleBuilder::new()
.resolve_imports(true)
.process_relocations(true)
.call_dll_main(true)
.load_from_memory(&data)?;
// Get a function from the loaded library
let function = module.get_proc_address("MyFunction")?;
Ok(())
}
Loading Application DLLs
Application DLLs are applications that have been compiled as DLL files instead of executables. They typically start a thread in DllMain to run the application logic.
use maple_rs::{Maple, Result};
use std::fs;
fn main() -> Result<()> {
// Load an application DLL (like focus.dll)
let data = fs::read("app.dll")?;
let module = Maple::load_application_dll_from_memory(&data)?;
// Execute the application
module.execute_dll_application()?;
// Application runs in background thread...
std::thread::sleep(std::time::Duration::from_secs(5));
Ok(())
}
Manual Control with Builder Pattern
For advanced control over application DLL loading:
use maple_rs::{MemoryModuleBuilder, Result};
use std::fs;
fn main() -> Result<()> {
let data = fs::read("app.dll")?;
let module = MemoryModuleBuilder::new()
.resolve_imports(true)
.process_relocations(true)
.call_dll_main(false) // Don't auto-call DllMain
.is_application_dll(true) // Mark as application DLL
.load_from_memory(&data)?;
// Manually execute when ready
module.execute_dll_application()?;
Ok(())
}
API Reference
Main Entry Points
Maple::load_executable_from_memory(data)- Load a standard executableMaple::load_library_from_memory(data)- Load a standard DLL/libraryMaple::load_application_dll_from_memory(data)- Load an application DLL
MemoryModule Trait Methods
execute_entry_point()- Execute an executable's entry pointexecute_dll_application()- Execute an application DLL (starts thread in DllMain)call_dll_entry_point(reason)- Manually call DllMain with specific reasonget_proc_address(name)- Get function address by nameget_proc_address_ordinal(ordinal)- Get function address by ordinal
Builder Options
resolve_imports(bool)- Enable/disable import resolutionprocess_relocations(bool)- Enable/disable relocation processingcall_dll_main(bool)- Auto-call DllMain on loadis_application_dll(bool)- Mark as application DLLignore_missing_imports(bool)- Continue loading with missing imports
Documentation
Comprehensive API documentation is available on docs.rs.
Platform Support
| Platform | Status | Features |
|---|---|---|
| Windows | ✅ Complete | Full PE parsing, import resolution, memory protection, application DLLs |
| Linux | 🔄 Planned | ELF support planned for future release |
| macOS | 🔄 Planned | Mach-O support planned for future release |
Error Handling
All operations return a Result<T, MapleError> with detailed error information:
use maple_rs::{Maple, MapleError};
match Maple::load_executable_from_memory(&data) {
Ok(module) => {
// Successfully loaded
},
Err(MapleError::InvalidPEFormat(msg)) => {
eprintln!("Invalid PE file: {}", msg);
},
Err(MapleError::MemoryAllocation(msg)) => {
eprintln!("Memory allocation failed: {}", msg);
},
Err(MapleError::ImportResolution(msg)) => {
eprintln!("Failed to resolve imports: {}", msg);
},
Err(e) => {
eprintln!("Other error: {}", e);
}
}
Architecture
maple-rs/
├── src/
│ ├── lib.rs # Main library interface
│ ├── error.rs # Error definitions
│ ├── memory_module.rs # Core trait and builder
│ ├── pe.rs # PE format parser
│ ├── windows.rs # Windows implementation
│ └── linux.rs # Linux placeholder
├── examples/ # Usage examples
├── tests/ # Integration tests
└── .github/workflows/ # CI/CD pipeline
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under the GNU GPLv3 License - see the LICENSE file for details.
Acknowledgments
- Inspired by the original MemoryModule C library
Dependencies
~155–730KB
~13K SLoC