From 696e382ba52e18a3d86392b18d3e5ef8ac0dd394 Mon Sep 17 00:00:00 2001 From: ko1N Date: Wed, 22 Feb 2023 00:11:01 +0100 Subject: [PATCH] Added remote argument for pcileech --- README.md | 3 ++- memflow-pcileech/src/lib.rs | 35 +++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9583bc1..a39d125 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,8 @@ let mut conn = memflow_pcileech::create_connector(&connector_args) The following arguments can be used when loading the connector: -- `device` - The name of the pcileech device to open (e.g. FPGA) (default argument, required) +- `device` - The name of the pcileech device to open (e.g. `FPGA`) (default argument, required) +- `remote` - The remote connection string of the pcileech (e.g. `rpc://insecure:computername.local`) (optional) - `memmap` - A file that contains a custom memory map in TOML format (optional) - `auto-clear` - Enables auto-clear of status registers in LeechCore (Auto-clear is only available for bitstreams 4.7 and newer.) diff --git a/memflow-pcileech/src/lib.rs b/memflow-pcileech/src/lib.rs index 0788fca..1a82120 100644 --- a/memflow-pcileech/src/lib.rs +++ b/memflow-pcileech/src/lib.rs @@ -25,20 +25,31 @@ const BUF_LEN_ALIGN: usize = 8; cglue_impl_group!(PciLeech, ConnectorInstance<'a>, {}); -fn build_lc_config(device: &str) -> LC_CONFIG { +fn build_lc_config(device: &str, remote: Option<&str>, with_mem_map: bool) -> LC_CONFIG { + // TODO: refactor how the static strings are handled let cdevice = unsafe { &*(device.as_bytes() as *const [u8] as *const [c_char]) }; let mut adevice: [c_char; 260] = [0; 260]; adevice[..device.len().min(260)].copy_from_slice(&cdevice[..device.len().min(260)]); - // TODO: copy device + remote + // set remote in case user specified the remote flag + let mut aremote: [c_char; 260] = [0; 260]; + if let Some(remote) = remote { + let cremote = unsafe { &*(remote.as_bytes() as *const [u8] as *const [c_char]) }; + aremote[..remote.len().min(260)].copy_from_slice(&cremote[..remote.len().min(260)]); + } + + // set paMax to -1 if mem map is set to disable automatic scanning + let pa_max = if with_mem_map { u64::MAX } else { 0 }; LC_CONFIG { dwVersion: LC_CONFIG_VERSION, dwPrintfVerbosity: LC_CONFIG_PRINTF_ENABLED | LC_CONFIG_PRINTF_V | LC_CONFIG_PRINTF_VV, szDevice: adevice, - szRemote: [0; 260], + szRemote: aremote, pfn_printf_opt: None, // TODO: custom info() wrapper - paMax: 0, + paMax: pa_max, + + // these are set by leechcore so we dont touch them fVolatile: 0, fWritable: 0, fRemote: 0, @@ -64,12 +75,13 @@ unsafe impl Send for PciLeech {} // TODO: proper drop + free impl -> LcMemFree(pLcErrorInfo); #[allow(clippy::mutex_atomic)] impl PciLeech { - pub fn new(device: &str, auto_clear: bool) -> Result { - Self::new_internal(device, None, auto_clear) + pub fn new(device: &str, remote: Option<&str>, auto_clear: bool) -> Result { + Self::new_internal(device, remote, None, auto_clear) } pub fn with_mem_map_file>( device: &str, + remote: Option<&str>, path: P, auto_clear: bool, ) -> Result { @@ -79,17 +91,18 @@ impl PciLeech { ); let mem_map = MemoryMap::open(path)?; info!("{:?}", mem_map); - Self::new_internal(device, Some(mem_map), auto_clear) + Self::new_internal(device, remote, Some(mem_map), auto_clear) } #[allow(clippy::mutex_atomic)] fn new_internal( device: &str, + remote: Option<&str>, mem_map: Option>, auto_clear: bool, ) -> Result { // open device - let mut conf = build_lc_config(device); + let mut conf = build_lc_config(device, remote, mem_map.is_some()); let err = std::ptr::null_mut::(); let handle = unsafe { LcCreateEx(&mut conf, err) }; if handle.is_null() { @@ -472,6 +485,7 @@ fn validator() -> ArgsValidator { ArgsValidator::new() .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("remote").description("the remote target 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)")) } @@ -492,11 +506,12 @@ pub fn create_connector(args: &ConnectorArgs) -> Result { Error(ErrorOrigin::Connector, ErrorKind::ArgValidation) .log_error("'device' argument is missing") })?; + let remote = args.get("remote"); let auto_clear = args.get("auto-clear").is_some(); if let Some(memmap) = args.get("memmap") { - PciLeech::with_mem_map_file(device, memmap, auto_clear) + PciLeech::with_mem_map_file(device, remote, memmap, auto_clear) } else { - PciLeech::new(device, auto_clear) + PciLeech::new(device, remote, auto_clear) } } Err(err) => {