diff --git a/Cargo.lock b/Cargo.lock index 140c3fd..aad0bc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.8.11" @@ -147,6 +158,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "as_derive_utils" version = "0.10.3" @@ -209,18 +229,54 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "cc" version = "1.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -294,6 +350,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -335,6 +401,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -356,6 +428,30 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f3b219d28b6e3b4ac87bc1fc522e0803ab22e055da177bff0068c4150c61a6" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -380,6 +476,16 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "ctor" version = "0.4.2" @@ -443,6 +549,43 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50eb3a329e19d78c3a3dfa4ec5a51ecb84fa3a20c06edad04be25356018218f9" +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + [[package]] name = "dirs" version = "5.0.1" @@ -577,6 +720,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -585,7 +738,21 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -621,6 +788,15 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "iana-time-zone" version = "0.1.63" @@ -813,6 +989,15 @@ dependencies = [ "web-time", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -885,6 +1070,16 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.2", + "libc", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -969,6 +1164,27 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "memchr" version = "2.7.4" @@ -1027,11 +1243,15 @@ name = "memflow-pcileech" version = "0.2.0" dependencies = [ "env_logger", + "indicatif", "leechcore-sys", "log", "memflow", "memflow-win32", "parking_lot 0.12.3", + "progress-streams", + "ureq", + "zip", ] [[package]] @@ -1109,6 +1329,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -1190,6 +1416,16 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + [[package]] name = "pdb" version = "0.8.0" @@ -1263,6 +1499,12 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "prettyplease" version = "0.2.32" @@ -1307,6 +1549,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rangemap" version = "1.5.1" @@ -1337,7 +1585,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.16", "libredox", "thiserror", ] @@ -1388,7 +1636,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -1556,12 +1804,29 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "smallvec" version = "1.15.0" @@ -1645,6 +1910,25 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + [[package]] name = "tinystr" version = "0.7.6" @@ -1735,6 +2019,12 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -1822,13 +2112,22 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasix" version = "0.12.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" dependencies = [ - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -2152,6 +2451,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -2176,6 +2484,15 @@ dependencies = [ "volatile", ] +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "yoke" version = "0.7.5" @@ -2246,6 +2563,20 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] [[package]] name = "zerovec" @@ -2268,3 +2599,71 @@ dependencies = [ "quote", "syn 2.0.101", ] + +[[package]] +name = "zip" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "flate2", + "getrandom 0.3.2", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/memflow-pcileech/Cargo.toml b/memflow-pcileech/Cargo.toml index 8261e26..fe556fd 100644 --- a/memflow-pcileech/Cargo.toml +++ b/memflow-pcileech/Cargo.toml @@ -21,13 +21,20 @@ leechcore-sys = { version = "0.2", path = "../leechcore-sys" } log = "0.4" parking_lot = "0.12" +ureq = { version = "2.10", optional = true } +zip = { version = "2.6", optional = true } +indicatif = { version = "0.17", optional = true } +progress-streams = { version = "1.1", optional = true } + [dev-dependencies] env_logger = "0.11" memflow-win32 = { version = "0.2" } [features] -default = [ ] -bindgen = [ "leechcore-sys/bindgen" ] +default = ["download_drivers", "download_progress"] +bindgen = ["leechcore-sys/bindgen"] +download_drivers = ["ureq", "zip"] +download_progress = ["indicatif", "progress-streams"] [[example]] name = "read_phys" diff --git a/memflow-pcileech/src/download.rs b/memflow-pcileech/src/download.rs new file mode 100644 index 0000000..f7755bc --- /dev/null +++ b/memflow-pcileech/src/download.rs @@ -0,0 +1,164 @@ +use log::info; +use std::fs::File; +use std::io::{self, Cursor, Read, Write}; +use std::path::PathBuf; +use zip::ZipArchive; + +use memflow::error::{Error, ErrorKind, ErrorOrigin, Result}; + +#[cfg(feature = "download_progress")] +use { + indicatif::{ProgressBar, ProgressStyle}, + progress_streams::ProgressReader, + std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}, + std::sync::Arc, +}; + +fn download_file(url: &str) -> Result> { + info!("downloading file from {}", url); + let resp = ureq::get(url).call().map_err(|_| { + Error(ErrorOrigin::Connector, ErrorKind::Http).log_error("unable to download file") + })?; + + assert!(resp.has("Content-Length")); + let len = resp + .header("Content-Length") + .and_then(|s| s.parse::().ok()) + .unwrap(); + + let mut reader = resp.into_reader(); + let buffer = read_to_end(&mut reader, len)?; + + assert_eq!(buffer.len(), len); + Ok(buffer) +} + +#[cfg(feature = "download_progress")] +fn read_to_end(reader: &mut T, len: usize) -> Result> { + let mut buffer = vec![]; + + let total = Arc::new(AtomicUsize::new(0)); + let mut reader = ProgressReader::new(reader, |progress: usize| { + total.fetch_add(progress, Ordering::SeqCst); + }); + let pb = ProgressBar::new(len as u64); + pb.set_style(ProgressStyle::default_bar() + .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})") + .unwrap() + .progress_chars("#>-")); + + let finished = Arc::new(AtomicBool::new(false)); + let thread = { + let finished_thread = finished.clone(); + let total_thread = total.clone(); + + std::thread::spawn(move || { + while !finished_thread.load(Ordering::Relaxed) { + pb.set_position(total_thread.load(Ordering::SeqCst) as u64); + std::thread::sleep(std::time::Duration::from_millis(10)); + } + pb.finish_with_message("downloaded"); + }) + }; + + reader.read_to_end(&mut buffer).map_err(|_| { + Error(ErrorOrigin::Connector, ErrorKind::Http).log_error("unable to read from http request") + })?; + finished.store(true, Ordering::Relaxed); + thread.join().unwrap(); + + Ok(buffer) +} + +#[cfg(not(feature = "download_progress"))] +fn read_to_end(reader: &mut T, _len: usize) -> Result> { + let mut buffer = vec![]; + reader.read_to_end(&mut buffer).map_err(|_| { + Error(ErrorOrigin::Connector, ErrorKind::Http).log_error("unable to read from http request") + })?; + Ok(buffer) +} + +#[cfg(all(target_os = "windows", target_arch = "x86_64"))] +pub fn download_url() -> (&'static str, &'static str) { + ( + "https://ftdichip.com/wp-content/uploads/2023/11/FTD3XXLibrary_v1.3.0.8.zip", + "FTD3XXLibrary_v1.3.0.8/x64/DLL/FTD3XX.dll", + ) +} + +// TODO: +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +pub fn download_url() -> (&'static str, &'static str) { + ( + "https://ftdichip.com/wp-content/uploads/2023/11/FTD3XXLibrary_v1.3.0.8.zip", + "FTD3XXLibrary_v1.3.0.8/x64/DLL/FTD3XX.dll", + ) +} + +pub fn download_driver() -> Result<()> { + let (url, file_to_extract) = download_url(); + + let file_to_extract_path: PathBuf = file_to_extract.parse().unwrap(); + let file_to_extract_name = file_to_extract_path.file_name().unwrap().to_str().unwrap(); + + // Get the current executable directory + let exe_path = std::env::current_exe().expect("Failed to get current executable path"); + let exe_dir = exe_path + .parent() + .expect("Failed to get parent directory of executable"); + + // Create the output path + let output_path = exe_dir.join(file_to_extract_name); + + // TODO: check hashsum + // Check if file exists in current path already and return Ok(()) + if output_path.exists() { + info!("ftdi driver found"); + return Ok(()); + } + + let contents = download_file(url)?; + + // Read the zip file in memory + let cursor = Cursor::new(contents); + let mut archive = ZipArchive::new(cursor).map_err(|_| { + Error(ErrorOrigin::Connector, ErrorKind::Http).log_error("Failed to parse zip archive") + })?; + + // Find and extract the specific file + for i in 0..archive.len() { + let mut file = archive + .by_index(i) + .map_err(|_| Error(ErrorOrigin::Connector, ErrorKind::UnableToReadFile))?; + println!("file.name: {}", file.name()); + if file.name() == file_to_extract { + info!("Found file to extract: {}", file_to_extract); + + info!("Extracting to: {}", output_path.display()); + + // Create the output file + let mut output_file = File::create(&output_path).expect(&format!( + "Failed to create output file: {}", + output_path.display() + )); + + // Copy the file content + io::copy(&mut file, &mut output_file).expect("Failed to write extracted file"); + + info!( + "Successfully extracted {} to {}", + file_to_extract, + output_path.display() + ); + return Ok(()); + } + } + + Err( + Error(ErrorOrigin::Connector, ErrorKind::NotFound).log_error(format!( + "file '{}' not found in zip archive", + file_to_extract + )), + ) +} diff --git a/memflow-pcileech/src/lib.rs b/memflow-pcileech/src/lib.rs index 843e35f..7ba885e 100644 --- a/memflow-pcileech/src/lib.rs +++ b/memflow-pcileech/src/lib.rs @@ -16,6 +16,9 @@ use memflow::prelude::v1::*; use leechcore_sys::*; +#[cfg(feature = "download_drivers")] +mod download; + const PAGE_SIZE: usize = 0x1000usize; // the absolute minimum BUF_ALIGN is 4. @@ -122,6 +125,10 @@ impl PciLeech { mem_map: Option>, auto_clear: bool, ) -> Result { + // ensure ftdi driver exists + #[cfg(feature = "download_drivers")] + download::download_driver().unwrap(); + // open device let mut conf = build_lc_config(device, remote, mem_map.is_some()); let p_lc_config_error_info = std::ptr::null_mut::();