Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,29 @@ jobs:
flags: unittests
fail_ci_if_error: true

memflow:
runs-on: ubuntu-20.04

steps:
- name: install stable toolchain with clippy
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
components: clippy
- uses: actions/checkout@v1
- name: build Memflow driver
uses: actions-rs/cargo@v1
with:
command: build
args: --features mflow
- name: annotate commit with clippy warnings
uses: actions-rs/clippy-check@v1
with:
name: clippy memflow
token: ${{ secrets.GITHUB_TOKEN }}
args: --features mflow -- -D warnings

virtualbox:
runs-on: ubuntu-20.04

Expand Down Expand Up @@ -248,7 +271,7 @@ jobs:
uses: satackey/action-docker-layer-caching@v0.0.11

- name: Build Wheels with manylinux
run: nox -r -s generate_wheels -- --features xen,kvm,virtualbox --release
run: nox -r -s generate_wheels -- --features xen,kvm,virtualbox,mflow --release
working-directory: python

# upload all generated wheels *.whl
Expand Down Expand Up @@ -311,7 +334,7 @@ jobs:
run: cargo install cargo-deb

- name: build debian package
run: cargo deb -- --features xen,kvm,virtualbox
run: cargo deb -- --features xen,kvm,virtualbox,mflow

- name: upload artifact
uses: actions/upload-artifact@v2
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ xen = ["xenctrl", "xenstore-rs", "xenforeignmemory", "xenevtchn", "xenvmevent-sy
kvm = ["kvmi"]
# VirtualBox driver
virtualbox = ["fdp"]
# memflow driver
# feature name is "mflow" to avoid conflict with the dependency
mflow = ["memflow"]


[dependencies]
Expand All @@ -42,6 +45,7 @@ winapi = { version = "0.3", features = ["tlhelp32", "winnt", "handleapi", "secur
widestring = { version = "0.4", optional = true }
ntapi = { version = "0.3", optional = true }
vid-sys = { version = "=0.3.0", features = ["deprecated-apis"], optional = true }
memflow = { version = "0.1.5", optional = true }

[dev-dependencies]
utilities = { path = "utilities" }
Expand Down
10 changes: 10 additions & 0 deletions doc/src/reference/drivers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ This section documents the drivers available and the requirements to compile the
| `xen` | Build the Xen driver |
| `kvm` | Build the KVM driver |
| `virtualbox` | Build the VirtualBox driver |
| `mflow` | Build the memflow driver |

Example
~~~
$ cargo build --features xen,kvm
~~~

## Rust API initialization parameters

To initialize each Driver from the Rust API,
please check [`DriverInitParams`](https://docs.rs/microvmi/api/params/struct.DriverInitParams.html).

## Xen

~~~
Expand Down Expand Up @@ -48,3 +54,7 @@ $ g++ -std=c++11 -shared -fPIC FDP.cpp -o libFDP.so
$ sudo mv include/* /usr/local/include/
$ sudo mv libFDP.so /usr/local/lib/
~~~

## Memflow

Please follow the instructions at [memflow](https://github.com/memflow/memflow)
2 changes: 2 additions & 0 deletions python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ xen = ["microvmi/xen"]
kvm = ["microvmi/kvm"]
# VirtualBox driver
virtualbox = ["microvmi/virtualbox"]
# memflow driver
mflow = ["microvmi/mflow"]

[dependencies]
log = "0.4"
Expand Down
2 changes: 1 addition & 1 deletion python/microvmi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from microvmi.microvmi import DriverType, Microvmi

from .pymicrovmi import CommonInitParamsPy, DriverInitParamsPy, KVMInitParamsPy
from .pymicrovmi import CommonInitParamsPy, DriverInitParamsPy, KVMInitParamsPy, MemflowInitParamsPy
10 changes: 9 additions & 1 deletion python/microvmi/volatility/vmi_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from urllib.parse import parse_qs, urlparse
from urllib.request import BaseHandler, Request

from microvmi import CommonInitParamsPy, DriverInitParamsPy, DriverType, KVMInitParamsPy, Microvmi
from microvmi import CommonInitParamsPy, DriverInitParamsPy, DriverType, KVMInitParamsPy, MemflowInitParamsPy, Microvmi

# to be used by volatility, the VMIHandler should inherit from VolatilityHandler
# in order to be non cacheable
Expand Down Expand Up @@ -101,16 +101,24 @@ def _parse_driver_init_params(query: str) -> Optional[DriverInitParamsPy]:
return None
common = None
kvm = None
memflow = None
for param, list_value in url_params.items():
if param == "vm_name":
common = CommonInitParamsPy()
common.vm_name = list_value[0]
elif param == "kvm_unix_socket":
kvm = KVMInitParamsPy()
kvm.unix_socket = list_value[0]
elif param == "memflow_connector_name":
memflow = MemflowInitParamsPy(list_value[0])
elif param == "memflow_connector_args":
if memflow is None:
raise MicrovmiHandlerError("memflow connector args received but no connector name specified")
memflow.connector_args = list_value
else:
raise MicrovmiHandlerError(f"Unknown driver initialization parameter: {param}")
init_params = DriverInitParamsPy()
init_params.common = common
init_params.kvm = kvm
init_params.memflow = memflow
return init_params
30 changes: 30 additions & 0 deletions python/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,36 @@ def test_volatility_kvm(session):
)


@nox.session
def test_volatility_memflow(session):
"""Run the PsList volatility plugin on the memflow connector specified by the URL"""
# example:
# nox -r -s test_volatility_memflow -- vmi:///?memflow_connector_name=qemu_procfs
args = session.posargs
if not args:
raise RuntimeError("URL required. Example: nox -r -s test_volatility_memflow -- vmi:///...")
# we need to compile and install the extension
session.install("-r", "requirements.txt")
# make sure we have volatility
# Note: we need to use the latest unreleased dev code from Github
session.install("git+https://github.com/volatilityfoundation/volatility3@af090bf29e6bb26a5961e0a6c25b5d1ec6e82498")
# can't use pip install
# see: https://github.com/PyO3/maturin/issues/330
session.run(f'{CUR_DIR / "setup.py"}', "develop", "--features", "mflow")
vol_path = Path(__file__).parent / ".nox" / "test_volatility_memflow" / "bin" / "vol"
plugins_dir = Path(__file__).parent / "microvmi" / "volatility"
session.run(
"sudo",
"-E",
str(vol_path),
"--plugin-dirs",
str(plugins_dir),
"--single-location",
*args,
"windows.pslist.PsList",
)


@nox.session
def coverage_html(session):
session.install("coverage==5.3")
Expand Down
9 changes: 8 additions & 1 deletion python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use errors::PyMicrovmiError;
use microvmi::api as rapi; // rust api
use microvmi::api::params as rparams; // rust params
use microvmi::init;
use params::{CommonInitParamsPy, DriverInitParamsPy, KVMInitParamsPy};
use params::{CommonInitParamsPy, DriverInitParamsPy, KVMInitParamsPy, MemflowInitParamsPy};

/// microvmi Python module declaration
#[pymodule]
Expand All @@ -24,6 +24,7 @@ fn pymicrovmi(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<DriverInitParamsPy>()?;
m.add_class::<CommonInitParamsPy>()?;
m.add_class::<KVMInitParamsPy>()?;
m.add_class::<MemflowInitParamsPy>()?;

Ok(())
}
Expand Down Expand Up @@ -89,6 +90,12 @@ impl MicrovmiExt {
kvm: v.kvm.map(|k| rparams::KVMInitParams::UnixSocket {
path: k.unix_socket,
}),
memflow: v.memflow.map(|k| rparams::MemflowInitParams {
connector_name: k.connector_name,
connector_args: Some(rparams::MemflowConnectorParams::Default {
args: k.connector_args,
}),
}),
..Default::default()
});

Expand Down
23 changes: 23 additions & 0 deletions python/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ impl KVMInitParamsPy {
}
}

/// equivalent of `MemflowInitParams` for Python
#[pyclass]
#[derive(Default, Debug, Clone)]
pub struct MemflowInitParamsPy {
#[pyo3(get, set)]
pub connector_name: String,
#[pyo3(get, set)]
pub connector_args: Vec<String>,
}

#[pymethods]
impl MemflowInitParamsPy {
#[new]
fn new(name: &str) -> Self {
Self {
connector_name: String::from(name),
connector_args: Vec::new(),
}
}
}

/// equivalent of `DriverInitParams` for Python
///
/// # Examples
Expand All @@ -58,6 +79,8 @@ pub struct DriverInitParamsPy {
pub common: Option<CommonInitParamsPy>,
#[pyo3(get, set)]
pub kvm: Option<KVMInitParamsPy>,
#[pyo3(get, set)]
pub memflow: Option<MemflowInitParamsPy>,
}

#[pymethods]
Expand Down
1 change: 1 addition & 0 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bitflags! {
#[derive(Debug, Copy, Clone, PartialEq, IntoEnumIterator)]
pub enum DriverType {
KVM,
Memflow,
VirtualBox,
Xen,
}
Expand Down
80 changes: 79 additions & 1 deletion src/api/params.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/// This module describes initialization parameters for all libmicrovmi drivers
//! This module describes initialization parameters for all libmicrovmi drivers
//!
//! The [`DriverInitParams`](struct.DriverInitParams.html) is used to pass additional driver initialization parameters.
//! You might want to check it's documentation for examples on how to initialize your driver.

/// Xen initialization parameters
#[derive(Debug, Clone, PartialEq)]
Expand All @@ -10,6 +13,46 @@ pub enum KVMInitParams {
UnixSocket { path: String },
}

/// Memflow connector parameters
///
/// This enumeration reflects the possibilities to initialize Memflow
/// - default: will simply forward the string arguments to the connector
// TODO
// - [`qemu_procfs`](https://github.com/memflow/memflow-qemu-procfs)
// - [`kvm`](https://github.com/memflow/memflow-kvm)
// - [`pcileech`](https://github.com/memflow/memflow-pcileech)
// - [`coredump`](https://github.com/memflow/memflow-coredump)
#[derive(Debug, Clone, PartialEq)]
pub enum MemflowConnectorParams {
// allow to pass an abritrary list of Strings as parameters
Default { args: Vec<String> },
// TODO
// // optional vm_name, otherwise will search for the first QEMU process
// QEMUProcFs {
// vm_name: Option<String>,
// },
// KVM {
// pid: u32,
// },
// // default value for device: "FPGA"
// PCILeech {
// device: Option<String>,
// memmap: Option<String>,
// },
// Coredump {
// filepath: String,
// },
}

/// Memflow initialization parameters
#[derive(Debug, Default, Clone, PartialEq)]
pub struct MemflowInitParams {
/// connector name
pub connector_name: String,
/// optional connector initialization parameters
pub connector_args: Option<MemflowConnectorParams>,
}

/// VirtualBox initialization parameters
#[derive(Debug, Clone, PartialEq)]
pub enum VBoxInitParams {}
Expand All @@ -25,10 +68,45 @@ pub struct CommonInitParams {
}

/// This struct is used to specify the initialization parameters for all drivers
///
/// # Examples
///
/// ```no_run
/// // Xen
/// // common.vm_name: mandatory
/// use microvmi::api::params::{DriverInitParams, CommonInitParams, KVMInitParams, MemflowInitParams};
/// let init_params = DriverInitParams {
/// common: Some(CommonInitParams { vm_name: String::from("windows10")}),
/// ..Default::default()
/// };
/// // KVM
/// // common.vm_name: mandatory
/// // kvm.unix_socket: mandatory
/// let init_params = DriverInitParams {
/// common: Some(CommonInitParams { vm_name: String::from("windows10")}),
/// kvm: Some(KVMInitParams::UnixSocket { path: String::from("/tmp/introspector")}),
/// ..Default::default()
/// };
/// // VirtualBox
/// // common.vm_name: mandatory
/// let init_params = DriverInitParams {
/// common: Some(CommonInitParams { vm_name: String::from("windows10")}),
/// ..Default::default()
/// };
/// // Memflow
/// // memflow.connector_name: mandatory
/// // memflow.connector_args: optional
/// let init_params = DriverInitParams {
/// memflow: Some(MemflowInitParams { connector_name: String::from("qemu_procfs"), ///
/// ..Default::default()}),
/// ..Default::default()
/// };
/// ```
#[derive(Default, Debug, Clone, PartialEq)]
pub struct DriverInitParams {
pub common: Option<CommonInitParams>,
pub xen: Option<XenInitParams>,
pub kvm: Option<KVMInitParams>,
pub memflow: Option<MemflowInitParams>,
pub virtualbox: Option<VBoxInitParams>,
}
Loading