mirror of
https://github.com/EddieIvan01/memexec
synced 2024-06-16 03:58:02 +00:00
216 lines
5.6 KiB
Rust
216 lines
5.6 KiB
Rust
#![allow(non_camel_case_types)]
|
|
#![allow(non_snake_case)]
|
|
#![allow(overflowing_literals)]
|
|
#![allow(non_upper_case_globals)]
|
|
|
|
pub mod error;
|
|
pub mod peloader;
|
|
pub mod peparser;
|
|
|
|
use error::Result;
|
|
use peloader::{DllLoader, ExeLoader};
|
|
use peparser::PE;
|
|
use std::os::raw::c_void;
|
|
|
|
#[cfg(feature = "hook")]
|
|
pub use peloader::hook;
|
|
#[cfg(feature = "hook")]
|
|
use peloader::hook::ProcDesc;
|
|
#[cfg(feature = "hook")]
|
|
use std::collections::HashMap;
|
|
|
|
pub unsafe fn memexec_exe(bs: &[u8]) -> Result<()> {
|
|
let pe = PE::new(bs)?;
|
|
#[cfg(feature = "hook")]
|
|
let loader = ExeLoader::new(&pe, None)?;
|
|
#[cfg(not(feature = "hook"))]
|
|
let loader = ExeLoader::new(&pe)?;
|
|
Ok(loader.invoke_entry_point())
|
|
}
|
|
|
|
#[cfg(feature = "hook")]
|
|
pub unsafe fn memexec_exe_with_hooks(
|
|
bs: &[u8],
|
|
hooks: &HashMap<ProcDesc, *const c_void>,
|
|
) -> Result<()> {
|
|
let pe = PE::new(bs)?;
|
|
let loader = ExeLoader::new(&pe, Some(hooks))?;
|
|
Ok(loader.invoke_entry_point())
|
|
}
|
|
|
|
pub unsafe fn memexec_dll(
|
|
bs: &[u8],
|
|
hmod: *const c_void,
|
|
reason_for_call: u32,
|
|
lp_reserved: *const c_void,
|
|
) -> Result<bool> {
|
|
let pe = PE::new(bs)?;
|
|
#[cfg(feature = "hook")]
|
|
let loader = DllLoader::new(&pe, None)?;
|
|
#[cfg(not(feature = "hook"))]
|
|
let loader = DllLoader::new(&pe)?;
|
|
Ok(loader.invoke_entry_point(hmod, reason_for_call, lp_reserved))
|
|
}
|
|
|
|
#[cfg(feature = "hook")]
|
|
pub unsafe fn memexec_dll_with_hooks(
|
|
bs: &[u8],
|
|
hmod: *const c_void,
|
|
reason_for_call: u32,
|
|
lp_reserved: *const c_void,
|
|
hooks: &HashMap<ProcDesc, *const c_void>,
|
|
) -> Result<bool> {
|
|
let pe = PE::new(bs)?;
|
|
let loader = DllLoader::new(&pe, Some(hooks))?;
|
|
Ok(loader.invoke_entry_point(hmod, reason_for_call, lp_reserved))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use std::fs::File;
|
|
use std::io::Read;
|
|
|
|
#[test]
|
|
#[cfg(not(feature = "hook"))]
|
|
fn test_dll() {
|
|
let mut buf = Vec::new();
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
File::open("./test.x64.dll")
|
|
.unwrap()
|
|
.read_to_end(&mut buf)
|
|
.unwrap();
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
File::open("./test.x86.dll")
|
|
.unwrap()
|
|
.read_to_end(&mut buf)
|
|
.unwrap();
|
|
|
|
unsafe {
|
|
memexec_dll(&buf, 0 as _, peloader::def::DLL_PROCESS_ATTACH, 0 as _).unwrap();
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
#[cfg(not(feature = "hook"))]
|
|
fn test_exe() {
|
|
let mut buf = Vec::new();
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
File::open("./test.x64.exe")
|
|
.unwrap()
|
|
.read_to_end(&mut buf)
|
|
.unwrap();
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
File::open("./test.x86.exe")
|
|
.unwrap()
|
|
.read_to_end(&mut buf)
|
|
.unwrap();
|
|
|
|
unsafe {
|
|
memexec_exe(&buf).unwrap();
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "hook")]
|
|
use std::mem;
|
|
|
|
#[cfg(feature = "hook")]
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
extern "cdecl" 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_name\0"
|
|
.chars()
|
|
.map(|c| (c as u16).to_le())
|
|
.collect();
|
|
let a1: Vec<_> = "token::whoami\0"
|
|
.chars()
|
|
.map(|c| (c as u16).to_le())
|
|
.collect();
|
|
*_Argv = [a0.as_ptr(), a1.as_ptr()].as_ptr();
|
|
|
|
mem::forget(a0);
|
|
mem::forget(a1);
|
|
}
|
|
|
|
0
|
|
}
|
|
|
|
#[test]
|
|
#[cfg(feature = "hook")]
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
fn hook_x86() {
|
|
let mut buf = Vec::new();
|
|
File::open("./test.x86.exe")
|
|
.unwrap()
|
|
.read_to_end(&mut buf)
|
|
.unwrap();
|
|
|
|
let mut hooks = HashMap::new();
|
|
|
|
unsafe {
|
|
hooks.insert(
|
|
"msvcrt.dll!__wgetmainargs".into(),
|
|
mem::transmute::<extern "cdecl" fn(_, _, _, _, _) -> _, _>(__wgetmainargs),
|
|
);
|
|
memexec_exe_with_hooks(&buf, &hooks).unwrap();
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "hook")]
|
|
#[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_name\0"
|
|
.chars()
|
|
.map(|c| (c as u16).to_le())
|
|
.collect();
|
|
let a1: Vec<_> = "token::whoami\0"
|
|
.chars()
|
|
.map(|c| (c as u16).to_le())
|
|
.collect();
|
|
*_Argv = [a0.as_ptr(), a1.as_ptr()].as_ptr();
|
|
|
|
mem::forget(a0);
|
|
mem::forget(a1);
|
|
}
|
|
|
|
0
|
|
}
|
|
|
|
#[test]
|
|
#[cfg(feature = "hook")]
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
fn hook_x64() {
|
|
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_exe_with_hooks(&buf, &hooks).unwrap();
|
|
}
|
|
}
|
|
}
|