memexec/peloader/
winapi.rs1use super::def::*;
2use super::error::{Error, Result};
3use std::ffi::CString;
4use std::mem;
5use std::os::raw::c_char;
6
7extern "system" {
8 fn LoadLibraryA(lpLibFileName: LPCSTR) -> HMODULE;
9 fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> PVOID;
10 fn GetCurrentProcess() -> HANDLE;
11}
12
13pub fn load_library(lib: &str) -> Result<HMODULE> {
14 if let Ok(lib) = CString::new(lib) {
15 let hmod = unsafe { LoadLibraryA(lib.as_ptr()) };
16 if hmod == 0 as HMODULE {
17 Err(Error::LoadLibararyFail)
18 } else {
19 Ok(hmod)
20 }
21 } else {
22 Err(Error::InvalidCString)
23 }
24}
25
26pub fn get_proc_address_by_name(hmod: HMODULE, proc_name: &str) -> Result<PVOID> {
27 if let Ok(proc_name) = CString::new(proc_name) {
28 let proc = unsafe { GetProcAddress(hmod, proc_name.as_ptr()) };
29 if proc == 0 as PVOID {
30 Err(Error::GetProcAddressFail)
31 } else {
32 Ok(proc)
33 }
34 } else {
35 Err(Error::InvalidCString)
36 }
37}
38
39pub fn get_proc_address_by_ordinal(hmod: HMODULE, proc_ordinal: isize) -> Result<PVOID> {
40 let proc = unsafe { GetProcAddress(hmod, proc_ordinal as *const c_char) };
41 if proc == 0 as PVOID {
42 Err(Error::GetProcAddressFail)
43 } else {
44 Ok(proc)
45 }
46}
47
48static mut p_nt_alloc_vm: usize = 0_usize;
50static mut p_nt_protect_vm: usize = 0_usize;
51
52pub unsafe fn nt_alloc_vm(
67 base_addr: *const PVOID,
68 size: PSIZE_T,
69 allocation_typ: ULONG,
70 protect: ULONG,
71) -> Result<()> {
72 if p_nt_alloc_vm == 0 as _ {
73 p_nt_alloc_vm =
74 get_proc_address_by_name(load_library("ntdll.dll")?, "NtAllocateVirtualMemory")? as _;
75 };
76
77 let ret = mem::transmute::<
78 usize,
79 unsafe extern "system" fn(
80 HANDLE,
81 *const PVOID,
82 ULONG_PTR,
83 PSIZE_T,
84 ULONG,
85 ULONG,
86 ) -> NTSTATUS,
87 >(p_nt_alloc_vm)(
88 GetCurrentProcess(),
89 base_addr,
90 0,
91 size,
92 allocation_typ,
93 protect,
94 );
95
96 if 0 == ret {
97 Ok(())
98 } else {
99 Err(Error::NtAllocVmErr(ret))
100 }
101}
102
103pub unsafe fn nt_protect_vm(
116 base_addr: *const PVOID,
117 size: PSIZE_T,
118 new_protect: ULONG,
119) -> Result<()> {
120 if p_nt_protect_vm == 0 as _ {
121 p_nt_protect_vm =
122 get_proc_address_by_name(load_library("ntdll.dll")?, "NtProtectVirtualMemory")? as _;
123 };
124
125 let old_protect: ULONG = 0;
126 let ret = mem::transmute::<
127 usize,
128 unsafe extern "system" fn(HANDLE, *const PVOID, PSIZE_T, ULONG, PULONG) -> NTSTATUS,
129 >(p_nt_protect_vm)(
130 GetCurrentProcess(),
131 base_addr,
132 size,
133 new_protect,
134 &old_protect as PULONG,
135 );
136
137 if 0 == ret {
138 Ok(())
139 } else {
140 Err(Error::NtProtectVmErr(ret))
141 }
142}