Added auto-clear argument which enables auto-clear functionality of status registers in pcileech; Added feature-gate to prevent re-generating bindings which removes the requirement of having libclang installed; Added more build-pipelines

next nightly
ko1N 2 years ago
parent 8f6a51e894
commit 0c0352b4b1

@ -7,7 +7,7 @@ env:
jobs:
build_ubuntu_x86-64:
build_ubuntu_x86-64_bundled:
name: Build for ubuntu-latest (x86-64)
runs-on: ubuntu-latest
steps:
@ -17,13 +17,46 @@ jobs:
- name: install libusb-1.0
run: sudo apt-get install libusb-1.0-0-dev
- name: build
run: cargo build --workspace --all-features --verbose
run: cargo build --workspace --verbose
- name: run tests
run: cargo test --workspace --verbose
- name: build examples
run: cargo build --workspace --all-features --examples --verbose
run: cargo build --workspace --examples --verbose
build_windows_x86-64:
build_ubuntu_x86-64_bindgen:
name: Build for ubuntu-latest (x86-64)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'true'
- name: install libusb-1.0
run: sudo apt-get install libusb-1.0-0-dev
- name: build
run: cargo build --workspace --features bindgen --verbose
- name: run tests
run: cargo test --workspace --features bindgen --verbose
- name: build examples
run: cargo build --workspace --features bindgen --examples --verbose
build_windows_x86-64_bundled:
name: Build for windows-latest (x86-64)
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'true'
- name: build
shell: bash
run: cargo build --workspace --verbose
- name: run tests
shell: bash
run: cargo test --workspace --verbose
- name: build examples
shell: bash
run: cargo build --workspace --examples --verbose
build_windows_x86-64_bindgen:
name: Build for windows-latest (x86-64)
runs-on: windows-latest
steps:
@ -39,13 +72,13 @@ jobs:
run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
- name: build
shell: bash
run: cargo build --workspace --all-features --verbose
run: cargo build --workspace --features bindgen --verbose
- name: run tests
shell: bash
run: cargo test --workspace --verbose
run: cargo test --workspace --features bindgen --verbose
- name: build examples
shell: bash
run: cargo build --workspace --all-features --examples --verbose
run: cargo build --workspace --features bindgen --examples --verbose
lint:
runs-on: ubuntu-latest

@ -0,0 +1,57 @@
name: Nightly build
on:
push:
branch:
- 'main'
env:
CARGO_TERM_COLOR: always
jobs:
build_ubuntu_x86-64:
name: Publish binary builds for linux (x86-64)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'true'
- name: install libusb-1.0
run: sudo apt-get install libusb-1.0-0-dev
- name: Download renamer
run: curl -sSf https://raw.githubusercontent.com/memflow/memflowup/master/target_rename.sh > target_rename.sh
- name: build
run: cargo build --workspace --verbose
- name: Rename and collect artifacts
id: artifacts
run: echo "::set-output name=artifact::$(sh ./target_rename.sh "x86_64-unknown-linux-gnu" | head -n 1)"
- name: Upload build artifacts
uses: softprops/action-gh-release@v1
with:
tag_name: nightly
files: |
${{ steps.artifacts.outputs.artifact }}
build_windows_x86-64:
name: Publish binary builds for windows (x86-64)
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'true'
- name: Download renamer
run: curl -sSf https://raw.githubusercontent.com/memflow/memflowup/master/target_rename.sh > target_rename.sh
- name: build
shell: bash
run: cargo build --workspace --verbose
- name: Rename and collect artifacts
id: artifacts
shell: bash
run: echo "::set-output name=artifact::$(sh ./target_rename.sh "x86_64-pc-windows-msvc" | head -n 1)"
- name: Upload build artifacts
uses: softprops/action-gh-release@v1
with:
tag_name: nightly
files: |
${{ steps.artifacts.outputs.artifact }}

@ -19,7 +19,7 @@ jobs:
- name: install libusb-1.0
run: sudo apt-get install libusb-1.0-0-dev
- name: build
run: cargo build --release --workspace --all-features --verbose
run: cargo build --release --workspace --verbose
- uses: actions/upload-artifact@v2
with:
name: library-ubuntu
@ -41,7 +41,7 @@ jobs:
run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
- name: build
shell: bash
run: cargo build --release --workspace --all-features --verbose
run: cargo build --release --workspace --verbose
- uses: actions/upload-artifact@v2
with:
name: library-windows

1
.gitignore vendored

@ -2,3 +2,4 @@
**/*.rs.bk
*.swp
.vscode
TODO.md

505
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -14,7 +14,7 @@ git submodule update --init
Install the following build tools:
- gcc
- clang
- clang (only required when selecting feature `bindgen`)
- libusb-1.0 (only required on linux)
Make sure that libclang can be found by either adding it to your `PATH` or via the `LIBCLANG_PATH` environment variable.
@ -54,11 +54,17 @@ Remarks: The `install.sh` script does currently not place the `leechcore_ft601_d
### Building the stand-alone connector for dynamic loading
To compile a dynamic library for use with the connector inventory use the following command:
```
cargo build --release
```
If you want to manually execute bindgen at buildtime (e.g. when changing/updating the underlying pcileech repository) then use the following command to build:
```
cargo build --release --all-features
cargo build --release --features bindgen
```
Note: This requires `clang` (libclang) to be installed on your system.
As mentioned above the `leechcore_ft601_driver_linux.so` or `FTD3XX.dll` have to be placed in the same folder the connector library is placed in.
### Using the library in a rust project

@ -2,7 +2,7 @@
// builds the connector from a given path (never called by the engine directly)
fn build_from_path(ctx, repo_path) {
info("Installing connector");
cargo("build --release --all-features", repo_path);
cargo("build --release", repo_path);
ctx.copy_cargo_plugin_artifact(repo_path, name_to_lib(ctx.crate_name()));
// TODO: download leechcore_ft601_driver_linux

@ -1,19 +0,0 @@
#!/bin/bash
cargo build --release --all-features
# install connector to system dir
if [ ! -z "$1" ] && [ $1 = "--system" ]; then
echo "installing connector system-wide in /usr/lib/memflow"
if [[ ! -d /usr/lib/memflow ]]; then
sudo mkdir /usr/lib/memflow
fi
sudo cp target/release/libmemflow_pcileech.so /usr/lib/memflow/libmemflow_pcileech.7.so
fi
# install connector in user dir
echo "installing connector for user in ~/.local/lib/memflow"
if [[ ! -d ~/.local/lib/memflow ]]; then
mkdir -p ~/.local/lib/memflow
fi
cp target/release/libmemflow_pcileech.so ~/.local/lib/memflow/libmemflow_pcileech.7.so

@ -1,6 +1,6 @@
[package]
name = "leechcore-sys"
version = "0.2.0-beta5"
version = "0.2.0-beta9"
authors = ["ko1N <ko1N1337@gmail.com>"]
edition = "2018"
readme = "../README.md"
@ -13,5 +13,9 @@ ctor = "0.1"
[build-dependencies]
cc = "1.0"
bindgen = "^0.60.1"
pkg-config = "0.3"
bindgen = { version = "^0.63.0", optional = true }
[features]
default = [ ]
bindgen = [ "dep:bindgen" ]

@ -1,10 +1,12 @@
extern crate bindgen;
extern crate cc;
extern crate pkg_config;
use std::env;
use std::path::PathBuf;
#[cfg(bindgen)]
extern crate bindgen;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::{env, fs};
#[cfg(target_os = "windows")]
fn os_define() -> &'static str {
@ -98,14 +100,8 @@ fn build_leechcore(target: &str) {
println!("cargo:rustc-link-lib=static=leechcore");
}
fn main() {
let target = env::var("TARGET").unwrap();
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
// build leechcore
build_leechcore(&target);
// generate bindings
#[cfg(bindgen)]
fn gen_leechcore<P: AsRef<Path>>(target: &str, out_dir: P) {
let mut builder = bindgen::builder()
.clang_arg(format!("-D{} -D_GNU_SOURCE", os_define()))
.header("./src/leechcore/leechcore/leechcore.h");
@ -120,8 +116,30 @@ fn main() {
.generate()
.unwrap_or_else(|err| panic!("Failed to generate bindings: {:?}", err));
let bindings_path = out_dir.join("leechcore.rs");
let bindings_path = out_dir.as_ref().to_path_buf().join("leechcore.rs");
bindings
.write_to_file(&bindings_path)
.unwrap_or_else(|_| panic!("Failed to write {}", bindings_path.display()));
}
#[cfg(not(bindgen))]
fn gen_leechcore<P: AsRef<Path>>(_target: &str, out_dir: P) {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let bindings_src_path = manifest_dir.join("src").join("leechcore.rs");
let bindings_dst_path = out_dir.as_ref().to_path_buf().join("leechcore.rs");
fs::copy(bindings_src_path, bindings_dst_path)
.expect("Failed to copy leechcore.rs bindings to OUT_DIR");
}
fn main() {
let target = env::var("TARGET").unwrap();
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
// build leechcore
build_leechcore(&target);
// generate or copy bindings
gen_leechcore(&target, out_dir);
}

@ -1 +1 @@
Subproject commit 7a8b693be0e750d548c6a38dd1864a360dac6db4
Subproject commit 94d2abdb39c515790558feaff31cb4a65c3e1307

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
[package]
name = "memflow-pcileech"
version = "0.2.0-beta7"
version = "0.2.0-beta9"
authors = ["ko1N <ko1N1337@gmail.com>"]
edition = "2018"
description = "qemu procfs connector for leechcore/pcileech"
@ -16,14 +16,17 @@ categories = [ "api-bindings", "memory-management", "os" ]
crate-type = ["lib", "cdylib"]
[dependencies]
memflow = { version = "^0.2.0-beta7", features = ["plugins", "memmapfiles"] }
leechcore-sys = { version = "0.2.0-beta1", path = "../leechcore-sys" }
memflow = { version = "^0.2.0-beta9", features = ["plugins", "memmapfiles"] }
leechcore-sys = { version = "0.2.0-beta9", path = "../leechcore-sys" }
log = "^0.4.14"
[dev-dependencies]
clap = { version = "^3.0.5", features = ["cargo"] }
simplelog = "^0.11.1"
memflow-win32 = { version = "^0.2.0-beta7" }
simplelog = "^0.12.0"
memflow-win32 = { version = "^0.2.0-beta9" }
[features]
default = [ ]
bindgen = [ "leechcore-sys/bindgen" ]
[[example]]
name = "read_phys"

@ -1,3 +1,4 @@
use ::std::ptr::null_mut;
use std::ffi::c_void;
use std::os::raw::c_char;
use std::path::Path;
@ -5,6 +6,7 @@ use std::ptr;
use std::slice;
use std::sync::{Arc, Mutex};
use log::warn;
use log::{error, info};
use memflow::cglue;
@ -63,22 +65,30 @@ unsafe impl Send for PciLeech {}
// TODO: proper drop + free impl -> LcMemFree(pLcErrorInfo);
#[allow(clippy::mutex_atomic)]
impl PciLeech {
pub fn new(device: &str) -> Result<Self> {
Self::new_internal(device, None)
pub fn new(device: &str, auto_clear: bool) -> Result<Self> {
Self::new_internal(device, None, auto_clear)
}
pub fn with_mem_map_file<P: AsRef<Path>>(device: &str, path: P) -> Result<Self> {
pub fn with_mem_map_file<P: AsRef<Path>>(
device: &str,
path: P,
auto_clear: bool,
) -> Result<Self> {
info!(
"loading memory mappings from file: {}",
path.as_ref().to_string_lossy()
);
let mem_map = MemoryMap::open(path)?;
info!("{:?}", mem_map);
Self::new_internal(device, Some(mem_map))
Self::new_internal(device, Some(mem_map), auto_clear)
}
#[allow(clippy::mutex_atomic)]
fn new_internal(device: &str, mem_map: Option<MemoryMap<(Address, umem)>>) -> Result<Self> {
fn new_internal(
device: &str,
mem_map: Option<MemoryMap<(Address, umem)>>,
auto_clear: bool,
) -> Result<Self> {
// open device
let mut conf = build_lc_config(device);
let err = std::ptr::null_mut::<PLC_CONFIG_ERRORINFO>();
@ -90,6 +100,50 @@ impl PciLeech {
.log_error(&format!("unable to create leechcore context: {:?}", err)));
}
// TODO: allow handling these errors properly
/*
typedef struct tdLC_CONFIG_ERRORINFO {
DWORD dwVersion; // must equal LC_CONFIG_ERRORINFO_VERSION
DWORD cbStruct;
DWORD _FutureUse[16];
BOOL fUserInputRequest;
DWORD cwszUserText;
WCHAR wszUserText[];
} LC_CONFIG_ERRORINFO, *PLC_CONFIG_ERRORINFO, **PPLC_CONFIG_ERRORINFO;
*/
if auto_clear {
let (mut id, mut version_major, mut version_minor) = (0, 0, 0);
unsafe {
LcGetOption(handle, LC_OPT_FPGA_FPGA_ID, &mut id);
LcGetOption(handle, LC_OPT_FPGA_VERSION_MAJOR, &mut version_major);
LcGetOption(handle, LC_OPT_FPGA_VERSION_MINOR, &mut version_minor);
}
if version_major >= 4 && (version_major >= 5 || version_minor >= 7) {
// enable auto-clear of status register [master abort].
info!("Trying to enable status register auto-clear");
let mut data = [0x10, 0x00, 0x10, 0x00];
if unsafe {
LcCommand(
handle,
LC_CMD_FPGA_CFGREGPCIE_MARKWR | 0x002,
data.len() as u32,
data.as_mut_ptr(),
null_mut(),
null_mut(),
)
} != 0
{
info!("Successfully enabled status register auto-clear");
} else {
warn!("Could not enable status register auto-clear");
}
} else {
return Err(Error(ErrorOrigin::Connector, ErrorKind::Configuration)
.log_error("Could not enable status register auto-clear due to outdated bitstream. Auto-clear is only available for bitstreams 4.7 and newer."));
}
}
Ok(Self {
handle: Arc::new(Mutex::new(handle)),
conf,
@ -419,6 +473,7 @@ fn validator() -> ArgsValidator {
.arg(ArgDescriptor::new("default").description("the target device to be used by LeechCore"))
.arg(ArgDescriptor::new("device").description("the target device to be used by LeechCore"))
.arg(ArgDescriptor::new("memmap").description("the memory map file of the target machine"))
.arg(ArgDescriptor::new("auto-clear").description("tries to enable the status register auto-clear function (only available for bitstreams 4.7 and upwards)"))
}
/// Creates a new PciLeech Connector instance.
@ -437,11 +492,11 @@ pub fn create_connector(args: &ConnectorArgs) -> Result<PciLeech> {
Error(ErrorOrigin::Connector, ErrorKind::ArgValidation)
.log_error("'device' argument is missing")
})?;
let auto_clear = args.get("auto-clear").is_some();
if let Some(memmap) = args.get("memmap") {
PciLeech::with_mem_map_file(device, memmap)
PciLeech::with_mem_map_file(device, memmap, auto_clear)
} else {
PciLeech::new(device)
PciLeech::new(device, auto_clear)
}
}
Err(err) => {

Loading…
Cancel
Save