Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/ memexec Public

A library for loading and executing PE (Portable Executable) from memory without ever touching the disk

License

Notifications You must be signed in to change notification settings

FssAy/memexec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

1 Commit

Repository files navigation

memexec

A library for loading and executing PE (Portable Executable) from memory without ever touching the disk

This is my own version for specific projects.
Original crate: https://crates.io/crates/memexec

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
[dependencies]
git = "https://github.com/DmitrijVC/memexec"
memexec = "0.3"

Usage

Execute from memory

⚠The architecture of target program must be same as current process, otherwise an error will occur

use memexec;
use std::fs::File;
use std::io::Read;
/***********************************************************/
/* EXE */
/***********************************************************/
let mut buf = Vec::new();
File::open("./test.exe")
 .unwrap()
 .read_to_end(&mut buf)
 .unwrap();
unsafe {
 // If you need to pass command line parameters,
 // try to modify PEB's command line buffer
 // Or use `memexec_exe_with_hooks` to hook related functions (see below)
 memexec::memexec_exe(&buf).unwrap();
}
/***********************************************************/
/* DLL */
/***********************************************************/
let mut buf = Vec::new();
File::open("./test.dll")
 .unwrap()
 .read_to_end(&mut buf)
 .unwrap();
use memexec::peloader::def::DLL_PROCESS_ATTACH;
unsafe {
 // DLL's entry point is DllMain
 memexec_dll(&buf, 0 as _, DLL_PROCESS_ATTACH, 0 as _).unwrap();
}

IAT hooking

Add the hook feature in Cargo.toml

[dependencies]
memexec = { git = "https://github.com/DmitrijVC/memexec", version="0.3", features=[ "hook" ] }

Hook the __wgetmainargs function (see example/__wgetmainargs_hook.rs)

let mut buf = Vec::new();
File::open("./test.x64.exe")
 .unwrap()
 .read_to_end(&mut buf)
 .unwrap();
let mut hooks = HashMap::new();
unsafe {
 hooks.insert(
 "msvcrt.dll!__wgetmainargs".into(),
 mem::transmute::<extern "win64" fn(_, _, _, _, _) -> _, _>(__wgetmainargs),
 );
 memexec::memexec_exe_with_hooks(&buf, &hooks).unwrap();
}

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)
*/
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
extern "win64" fn __wgetmainargs(
 _Argc: *mut i32,
 _Argv: *mut *const *const u16,
 _Env: *const c_void,
 _DoWildCard: i32,
 _StartInfo: *const c_void,
) -> i32 {
 unsafe {
 *_Argc = 2;
 let a0: Vec<_> = "program_name0円"
 .chars()
 .map(|c| (c as u16).to_le())
 .collect();
 let a1: Vec<_> = "token::whoami0円"
 .chars()
 .map(|c| (c as u16).to_le())
 .collect();
 *_Argv = [a0.as_ptr(), a1.as_ptr()].as_ptr();
 // Avoid calling destructor
 mem::forget(a0);
 mem::forget(a1);
 }
 0
}

PE parser

PE parser could parse programs which have different architectures from current process

use memexec::peparser::PE;
// Zero copy
// Make sure that the lifetime of `buf` is longer than `pe`
let pe = PE::new(&buf);
println!("{:?}", pe);

TODO

  • Replace LoadLibrary with calling load_pe_into_mem recursively

  • Replace GetProcAddress with self-implemented LdrpSnapThunk, so as to support resolving proc address by IMAGE_IMPORT_BY_NAME.Hint

License

The GPLv3 license

About

A library for loading and executing PE (Portable Executable) from memory without ever touching the disk

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /