4 releases

0.1.5 Apr 27, 2020
0.1.4 Apr 12, 2020
0.1.2 Apr 1, 2020
0.1.1 Mar 30, 2020

#881 in Unix APIs

23 downloads per month

MIT license

90KB
2.5K SLoC

C 1.5K SLoC // 0.0% comments Rust 437 SLoC C++ 392 SLoC Prolog 18 SLoC Shell 13 SLoC

Rust bindings for linux vmread library

Crates.io MIT licensed

API Docs

Main crates

  • vmread: Safe high-level API
  • vmread-sys: Unsafe generated low-level API

Examples

Build the examples with the following command:

cargo build --examples <--features kmod_rw>

Be sure to run them as root, they will be placed in target/(debug|release)/examples/ directory

More information

  • If kmod_rw feature is used, the required kernel module gets built inside target vmread-sys directory
  • For more information go to the vmread repo

lib.rs:

A library for reading and writing windows memory running on a KVM-based virtual machine

Feature flags

vmread uses a set of feature flags to switch between different modes of operation. This is to allow maximum performance in given circumstances. Currently there are 3 available modes:

  • default: Uses system calls to perform memory read/write operations. It is the safest option available, although rather slow.
  • internal_rw: Accesses memory directly. This is meant for shared libraries that get loaded into the KVM process (usually qemu-system-x86_64). This is the least safe option, and is very inconsistent to pull off across various system installations.
  • kmod_rw: With the help of a kernel module we are able to map the entirety of KVM address space into our current address space and access it directly. It is a great blend between the default and internal modes, and is the best way forward if running custom kernel modules is an option.

Example

A simple process list:

extern crate vmread;

fn main() {
    let ctx_ret = vmread::create_context(0);

    if ctx_ret.is_ok() {
        let (mut ctx, _) = ctx_ret.unwrap();
        println!("VMRead initialized!");

        println!("Process List:\nPID\tVIRT\t\t\tPHYS\t\tBASE\t\tNAME");
        for i in &(ctx.refresh_processes().process_list) {
           println!("{:#4x}\t{:#16x}\t{:#9x}\t{:#9x}\t{}", i.proc.pid, i.proc.process, i.proc.physProcess, i.proc.dirBase, i.name); 
        }
    } else {
        let (eval, estr) = ctx_ret.err().unwrap();
        println!("Initialization error {}: {}", eval, estr);
    }
}

Dependencies

~0–2MB
~40K SLoC