memexec
A library for loading and executing PE (Portable Executable) from memory without ever touching the disk
Features
- Applicable to EXE and DLL (except .NET assembly)
- Cross-architecture, applicable to x86 and x86-64
- Zero-dependency
- Contains a simple, zero-copy PE parser submodule
- Provides an IAT hooking interface
Install
# Cargo.toml
[]
= "0.2"
Usage
Execute from memory
⚠The architecture of target program must be same as current process, otherwise an error will occur
use memexec;
use File;
use Read;
/***********************************************************/
/* EXE */
/***********************************************************/
let mut buf = Vec new;
open
.unwrap
.read_to_end
.unwrap;
unsafe
/***********************************************************/
/* DLL */
/***********************************************************/
let mut buf = Vec new;
open
.unwrap
.read_to_end
.unwrap;
use DLL_PROCESS_ATTACH;
unsafe
IAT hooking
Add the hook
feature in Cargo.toml
[]
= { ="0.2", =[ "hook" ] }
Hook the __wgetmainargs
function (see example/hook.rs
)
let mut buf = Vec new;
open
.unwrap
.read_to_end
.unwrap;
let mut hooks = new;
unsafe
The definition of __wgetmainargs
(notice the calling convention on different archtectures):
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/getmainargs-wgetmainargs?view=msvc-160
/*
int __wgetmainargs (
int *_Argc,
wchar_t ***_Argv,
wchar_t ***_Env,
int _DoWildCard,
_startupinfo * _StartInfo)
*/
extern "win64"
Parse PE
PE parser could parse programs which have different architectures from current process
use PE;
// Zero copy
// Make sure that the lifetime of `buf` is longer than `pe`
let pe = PE new;
println!;
TODO
-
Replace
LoadLibrary
with callingload_pe_into_mem
recursively -
Replace
GetProcAddress
with self-implementedLdrpSnapThunk
, so as to support resolving proc address byIMAGE_IMPORT_BY_NAME.Hint
License
The GPLv3 license