From 67cdcc2e12118becb823e20a40cc2687f2b8425a Mon Sep 17 00:00:00 2001 From: Adam Carpenter <53hornet@gmail.com> Date: Wed, 27 Mar 2019 15:32:37 -0400 Subject: Started Rust in Action MEAP. --- meap/meap-code/ch6/ch6-meminfo-win/Cargo.lock | 31 ++++++++++++++ meap/meap-code/ch6/ch6-meminfo-win/Cargo.toml | 9 ++++ meap/meap-code/ch6/ch6-meminfo-win/src/main.rs | 59 ++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 meap/meap-code/ch6/ch6-meminfo-win/Cargo.lock create mode 100644 meap/meap-code/ch6/ch6-meminfo-win/Cargo.toml create mode 100644 meap/meap-code/ch6/ch6-meminfo-win/src/main.rs (limited to 'meap/meap-code/ch6/ch6-meminfo-win') diff --git a/meap/meap-code/ch6/ch6-meminfo-win/Cargo.lock b/meap/meap-code/ch6/ch6-meminfo-win/Cargo.lock new file mode 100644 index 0000000..99ff3ec --- /dev/null +++ b/meap/meap-code/ch6/ch6-meminfo-win/Cargo.lock @@ -0,0 +1,31 @@ +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "meminfo" +version = "0.1.0" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/meap/meap-code/ch6/ch6-meminfo-win/Cargo.toml b/meap/meap-code/ch6/ch6-meminfo-win/Cargo.toml new file mode 100644 index 0000000..5c44b56 --- /dev/null +++ b/meap/meap-code/ch6/ch6-meminfo-win/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "meminfo" +version = "0.1.0" +authors = ["Tim McNamara "] + +[dependencies] +#libc = "0.2" +winapi = "0.2" +kernel32-sys = "0.2" \ No newline at end of file diff --git a/meap/meap-code/ch6/ch6-meminfo-win/src/main.rs b/meap/meap-code/ch6/ch6-meminfo-win/src/main.rs new file mode 100644 index 0000000..cbeb18b --- /dev/null +++ b/meap/meap-code/ch6/ch6-meminfo-win/src/main.rs @@ -0,0 +1,59 @@ +extern crate kernel32; +extern crate winapi; + +use winapi::{ + DWORD, // <1> u32 + HANDLE, // <2> Pointer types for various internal APIs without an associated type. In Rust, defined in `std::os::raw::c_void` + LPVOID, // <2> + PVOID, // <3> + SIZE_T, // <4> u64 (usize on this machine) + LPSYSTEM_INFO, // <5> A pointer to a SYSTEM_INFO struct + SYSTEM_INFO, // <6> Some structs defined by Windows internally + MEMORY_BASIC_INFORMATION, // <6> +}; + +fn main() { + let this_pid: DWORD; // <7> These variables will be initialized from within `unsafe` blocks. To make them accessible in the outer scope, they need to be defined here. + let this_proc: HANDLE; // <7> + let min_app_addr: LPVOID; // <7> + let max_app_addr: LPVOID; // <7> + let mut base_addr: PVOID; // <7> + let mut proc_info: SYSTEM_INFO; // <7> + let mut mem_info: MEMORY_BASIC_INFORMATION; // <7> + + const MEMINFO_SIZE: usize = std::mem::size_of::(); + + unsafe { // <8> This block guarantees that all memory is initialized + base_addr = std::mem::zeroed(); + proc_info = std::mem::zeroed(); + mem_info = std::mem::zeroed(); + } + + unsafe { // <9> This block of code is where system calls are made + this_pid = kernel32::GetCurrentProcessId(); + this_proc = kernel32::GetCurrentProcess(); + kernel32::GetSystemInfo(&mut proc_info as LPSYSTEM_INFO); // <10> Rather than use a return value, this function makes use of a C idiom to provide its result to the caller. We provide a pointer to some pre-defined struct, then read that struct's new values once the function has returned to see the results. + }; + + min_app_addr = proc_info.lpMinimumApplicationAddress; // <11> Renaming these variables for convienence. + max_app_addr = proc_info.lpMaximumApplicationAddress; // <11> + + println!("{:?} @ {:p}", this_pid, this_proc); + println!("{:?}", proc_info); + println!("min: {:p}, max: {:p}", min_app_addr, max_app_addr); + + + loop { // <12> This loop does the work of scanning through the address space + let rc: SIZE_T = unsafe { + kernel32::VirtualQueryEx(this_proc, base_addr, + &mut mem_info, MEMINFO_SIZE as SIZE_T) + }; + + if rc == 0 { + break + } + + println!("{:#?}", mem_info); + base_addr = ((base_addr as u64) + mem_info.RegionSize) as PVOID; + } +} \ No newline at end of file -- cgit v1.2.3