Giter Site home page Giter Site logo

wenzel / libmicrovmi Goto Github PK

View Code? Open in Web Editor NEW
157.0 8.0 16.0 2.41 MB

A cross-platform unified Virtual Machine Introspection API library

Home Page: https://wenzel.github.io/libmicrovmi/

License: GNU General Public License v3.0

Rust 74.51% Makefile 0.43% C 3.62% Dockerfile 1.19% Shell 0.39% Python 18.29% CMake 1.58%
introspection vmi hypervisors emulators vmi-api hypervisors-apis rust

libmicrovmi's Introduction

libmicrovmi

A cross-platform unified Virtual Machine Introspection API library

CI crates.io docs.rs gitter gitpod

online_docs

Table of Contents

Overview

libmicrovmi aims to provide a cross-platform unified Virtual Machine Introspection API. (See What's VMI ?)

The term micro (μ) refers to the library's simplicity as well as the letter U standing for Unified interface.

Virtual Machine Introspection has been around since 2003, yet the ecosystem is still heavily fragmented and lacks standards as well as interoperability. (See VMI Ecosystem Fragmentation)

The main objective is to provide the simplest virtual machine introspection abstraction, offering a standard API to interact with any VMI provider, with a high degree of compatibility and composability to be integrated with any high-level VMI application.

libmicrovmi_image

Project Status

Below you can find a table describing the apps and drivers that can be used with libmicrovmi.

App Driver
API Platform
  • ✅ Linux
  • ✅ Windows
  • 🔲 MacOS

Legend:

  • ✅: full support
  • 🟧: partial support
  • 🔲: TODO

Getting Started

The documentation is here to guide you, whether you are a user or developer.

User

User documentation

  • I would like to install libmicrovmi on my system
  • I would like to know how to setup my VMI app with libmicrovmi
  • I would like to know which drivers are available and how to initialize them

Developer

Developer documentation

  • I am developing a memory forensic / VM introspection app, and I want an API that supports multiple hypervisors at glance
  • I want to add a new driver for libmicrovmi

Documentation

Our documentation is hosted online at online_docs

You can find it at doc/ as an mdbook 📖

To build the docs locally:

$ cargo install mdbook
$ mdbook build doc
$ xdg-open doc/book/index.html

Maintainers

License

GNU General Public License v3.0

libmicrovmi's People

Contributors

ajkhoury avatar arnabcs17b006 avatar dependabot[bot] avatar rageagainsthepc avatar wenzel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libmicrovmi's Issues

Physical write function should not require a mutable buffer

When doing a physical write the input byte buffer that is being written to the target is usually not mutated directly. It will just cause the memory of the target to be mutated. Currently, the libmicrovmi API exposes a physical write function that enforces mutability of the input byte buffer though.

    fn write_physical(&self, _paddr: u64, _buf: &mut [u8]) -> Result<(), Box<dyn Error>> {
        unimplemented!();
    }

HyperDBG integration

HyperDbg debugger is an open-source, hypervisor-assisted user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing and reversing.

How does it listen for VM events such as EPT pagefaults ?
What hypervisors are supported ?

Could HyperDBG make use of libmicrovmi ?

cc @SinaKarvandi here :)

Logging

use log crate instead of println! macro

RUSTSEC-2020-0036: failure is officially deprecated/unmaintained

failure is officially deprecated/unmaintained

Details
Status unmaintained
Package failure
Version 0.1.8
URL rust-lang-deprecated/failure#347
Date 2020-05-02

The failure crate is officially end-of-life: it has been marked as deprecated
by the former maintainer, who has announced that there will be no updates or
maintenance work on it going forward.

The following are some suggested actively developed alternatives to switch to:

See advisory page for additional details.

Xen driver not compatible with Ubuntu 16.04

When trying to setup multi distro testing under Github Actions, the Xen driver failed to compiled,
as it relied on xenforeignmemory, which is an API which appeared recently in Xen.

Add more compatibility for the Xen driver.
#45

Volatility3 integration

Writing a new address space for volatility3, to run vol plugins directly on the VM physical memory.

From Ikelos:

Sure, so if you define an appropriate handler (using the python handlers system) similar to the JarHandler we have at https://github.com/volatilityfoundation/volatility3/blob/develop/volatility3/framework/layers/resources.py#L202, then people will be able to use python vol.py --single-location vmi://whatever to run against the VMI image directly.

In volatility 3, we don't pass parameters, but instead every "Configurable" (some that needs information) provides requirements through the get_requirements method, which contains simple types like int, str, etc, to act as parameters.
You can see this at work for every plugin, but you can also see it in the intel layer here: https://github.com/volatilityfoundation/volatility3/blob/develop/volatility3/framework/layers/intel.py#L231 which can then be accessed via self.config[<requirement name>]. Hopefully that makes a bit more sense? I'd probably go for the handler method, if you've already done something similar for rekall...

TODO:

Build system: opportunistic drivers

PR #151 attempts to have default drivers enabled.

The issue raised by this system is that it requires to have

  • Xen headers
  • libkvmi headers
  • VirtualBox FDP headers

all installed and detected to compile, unless you explicitely disable a driver.

An improvment would be to do like libvmi's cmake build system, and have opportunistic features, where we try to build the crates on which the driver depend upon, and on failure we simply disable the feature and continue.

I don't know how to implement this with cargo, build.rs.

Next step would be to ask on Rust language forums.

Xen API changes in xenctrl

Xen breaks the API between 4.9.2 and 4.11.2

4.9.2: xc_monitor_enable(domid_t domid)
4.11.2: xc_monitor_enable(uint32_t domid)

How to deal with this in Bindgen ?

KVM: Handle read size > 4K

From #161 , Volatility3 is performing huge read operations, far beyong the usual 4K.
However, in KVM invalid_page_access returns true if the size requested is superior to the PAGE_SIZE, which is 4K.

This means that the libmicrovmi should split the read into 4K chunks.

Translate a virtual address

Another goal is to translate a virtual address to a physical address.

This implies parsing the page tables.
Now either the hypervisor supports this already and can offer us an API, or we have to implement this ourselves.

Check from existing crates like x86_64 from rust-osdev if they can share page tables structures definition, and even the translation functions.

First publication on crates.io

This issue tracks what needs to be done for a first publication on crates.io

  • update Cargo.toml
  • convert all git dependencies to crates.io equivalent

upload git dependencies to crates.io

  • xenctrl
    • xenctrl-sys
  • xenstore
    • xenstore-sys
  • xenforeignmemory
    • xenforeignmemory-sys
  • kvmi
    • kvmi-sys
  • fdp
    • fdp-sys

hypervisor detection

Libmicrovmi's api needs to explicitely specify the hypervisor that we want to use.

We could improve that behavior by detecting if a given hypervisor is present, and test all possible hypervisors (the ones compiled in the library).

As we are only compiling a specific hypervisor, there will be only 2 hypervisors available:

  • Dummy
  • the selected feature (xen or kvm at this point)

How can we modify the init function, so that it takes an optional driver type ?

pub fn init(driver_type: Option<DriverType>, domain_name: &String) -> Box<Introspectable> {

So we could pass None and let the function decide.

What do you think @tathanhdinh, how to implement this feature ?

Thanks.

initial setup with example code results in a segmentation fault / xen on linux

Context

As discussed on twitter (@deiderajr) i receive a segmentation fault after using the mem-dump example code (same for other examples).

Process

This is our testing environment:

xlinfo.txt

Steps to reproduce the error:

  1. Downloaded the repository from github (master branch)
  2. cd to libmicrovmi/target/debug/examples
  3. RUST_LOG=debug cargo run --features xen --example mem-dump

Retrieving data with libvmi works (see terminal_libvmi.png).

terminal_libvmi

Expected result

Getting a correct .dump file

Current result

Segmentation fault (see terminal_libmicrovmi.png)

terminal_libmicrovmi

End

If i missed important information please let me know. Thanks!

API design: events interfaces and traits

Following #49 I'm opening this issue to start the discussion on how the event API should be implemented.

I'm reposting an idea from @kylerky, where each driver event (KVMEvent, XenEvent...) should implement a set of traits, and Event should contain generic type:

pub struct Event {
    common: EventCommon,
    extra: EventExtra,
}

pub enum EventExtra<CR>
    where CR: CREvent
{
    CR(CR),
    Pause,
}

pub trait CREvent {
    fn get_old() -> u64;
    fn get_new() -> u64;
}

pub struct KVMCrEvent {
    pub fn construct_reply(...) -> KVMCrReply {

    }
}

impl CREvent for KVMCrEvent {...}

struct KVMCrReply {...}
impl Reply for KVMCrReply {...}

fn main() {
    let kvm_cr_event = ...;
    let reply = kvm_cr_event.construct_reply(Continue, new);
    dom.send(reply);
}

fn send<T: Reply>(reply: T) { ... }

mem-dump.rs writes invalid memory dumps

Volatility was unable to read a requested page: Page error 0xffff81e13858 in layer primary (Page Fault at entry 0x0 in table page directory)

Strange, are you using Volatility3 ?
Maybe open an issue on their repo, they will get back to you.

The problem is that mem-dump.rs does not create a valid memory dump, in the sense that it simply skips non-accessible pages, and thus physical address and offset in dump file will not match. Volatility depends on both being the same.

Something like this results in a working dump file (as sparse file, so not wasting disk space). Tested on Linux only, I am not familiar with Windows, if it supports sparse file that way as well.

--- a/examples/mem-dump.rs
+++ b/examples/mem-dump.rs
@@ -1,6 +1,9 @@
 use std::fs::File;
 use std::io::Write;
 use std::path::Path;
+use std::io::SeekFrom;
+use std::io::Seek;
+use std::convert::TryInto;
 
 use clap::{App, Arg, ArgMatches};
 use env_logger;
@@ -56,7 +59,9 @@ fn main() {
                     .write_all(&buffer)
                     .expect("failed to write to file");
             }
-            Err(_error) => (),
+            Err(_error) => {
+               dump_file.seek(SeekFrom::Current(PAGE_SIZE.try_into().unwrap())).expect("failed to seek in file");
+           },
         }
     }


Driver dynamic loading

Today libmicrovmi has 2 limitations:

  • only one driver is compiled-in
  • the resulting binary links with the driver libraries

We should produce a library that detects at runtime which libraries are available and initializes the compatible drivers.

However, we rely on bindgen, and this feature is not ready yet:
rust-lang/rust-bindgen#1541

libmicrovmi python bindings

Create Python bindings to call libmicrovmi from Python

TODO (updated):

  • decide how to integrate this new library in our build system
  • expose DriverType and DriverInitParam
  • expose read_physical
  • package and upload to PyPI
  • update setup.py to accept --features parameter, and set features in RustExtension
  • create new Dockerfile based on quay.io/pypa/manylinux2014_x86_64 and install all the drivers required development headers
  • update build-wheels.sh to accept --features and pass them to setup.py
  • read all relevant fields of python/Cargo.toml to fill setup.py metadata

We should use the rust-cpython project

rust-cpython will help us to generate a Python extension module, wrapping the libmicrovmi Rust API.

how to integrate this new library

  1. create a separate repository
  2. use cargo workspace to manage both Rust library and Python extension in the same git repository, in tandem.
  3. maybe generate both with the same cargo.toml (I doubt this is possible)

@rageagainsthepc if you have an opinion

Hyper-V: filter by VM name

The Hyper-V driver currenty loops over all vmwp.exe and returns when he found a partition handle.

This means that the vm_name parameter is not checked.

We need to list runnings Hyper-V VMs, and match the vm_name parameter.

Move mem-dump as example

Cargo already knows how to deal with examples binaries with the examples folder.
Move it there.

Enabling logging output from C

libmicrovmi is using the log crate to define its log messages.
These message are enabled by the env_logger, initialized at beginning of each example.

However, how can we initialize the env_logger with the C API ? 🤔

Even if I export RUST_LOG=debug now, I have no debug output when running a LibVMI example :/

Icebox integration

Icebox is a Virtual Machine Introspection solution that enable you to stealthily trace and debug any process (kernel or user).

The project is based on the Fast Debugging Protocol library, which ties it to VirtualBox for now.

A libmicrovmi integration could be handy for the Icebox project to support KVM or Xen

Redesign the init function so it returns result objects

When using libmicrovmi in an external project it is rather unfortunate to have the init function just panic if something goes wrong. Imho it would be better to have it return result objects instead so the caller can decide how to handle the situation.
One example is libvmi which tests hypervisor connections by initializing them. If one fails, libvmi just moves on to the next one.

Expose a C-compatible API

Libmicrovmi aims to be compatible with LibVMI and other already existing C projects.

We need to build and expose a C API.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.