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
12 changes: 7 additions & 5 deletions crates/fspy/src/fixture.rs → crates/fspy/src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::{
io::{self, Write},
path::{Path, PathBuf},
};
pub struct Fixture {

/// An artifact (e.g., a DLL or shared library) whose content is embedded and needs to be written to disk.
pub struct Artifact {
pub name: &'static str,
pub content: &'static [u8],
pub hash: &'static str,
Expand All @@ -12,9 +14,9 @@ pub struct Fixture {
#[cfg(target_os = "macos")]
#[doc(hidden)]
#[macro_export]
macro_rules! fixture {
macro_rules! artifact {
($name: literal) => {
$crate::fixture::Fixture::new(
$crate::artifact::Artifact::new(
$name,
::core::include_bytes!(::core::concat!(::core::env!("OUT_DIR"), "/", $name)),
::core::include_str!(::core::concat!(::core::env!("OUT_DIR"), "/", $name, ".hash")),
Expand All @@ -23,9 +25,9 @@ macro_rules! fixture {
}

#[cfg(target_os = "macos")]
pub use fixture;
pub use artifact;

impl Fixture {
impl Artifact {
#[cfg(not(target_os = "linux"))]
pub const fn new(name: &'static str, content: &'static [u8], hash: &'static str) -> Self {
Self { name, content, hash }
Expand Down
2 changes: 1 addition & 1 deletion crates/fspy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![feature(once_cell_try)]

// Persist the injected DLL/shared library somewhere in the filesystem.
mod fixture;
mod artifact;

pub mod error;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::fixture::{Fixture, fixture};
use crate::artifact::{Artifact, artifact};

pub const COREUTILS_BINARY: Fixture = fixture!("coreutils");
pub const OILS_BINARY: Fixture = fixture!("oils-for-unix");
pub const COREUTILS_BINARY: Artifact = artifact!("coreutils");
pub const OILS_BINARY: Artifact = artifact!("oils-for-unix");

#[cfg(test)]
mod tests {
Expand Down
20 changes: 10 additions & 10 deletions crates/fspy/src/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
mod syscall_handler;

#[cfg(target_os = "macos")]
mod macos_fixtures;
mod macos_artifacts;

use std::{io, path::Path};

#[cfg(target_os = "linux")]
use fspy_seccomp_unotify::supervisor::supervise;
use fspy_shared::ipc::{NativeString, PathAccess, channel::channel};
#[cfg(target_os = "macos")]
use fspy_shared_unix::payload::Fixtures;
use fspy_shared_unix::payload::Artifacts;
use fspy_shared_unix::{
exec::ExecResolveConfig,
payload::{Payload, encode_payload},
Expand All @@ -31,7 +31,7 @@ use crate::{
#[derive(Debug, Clone)]
pub struct SpyImpl {
#[cfg(target_os = "macos")]
fixtures: Fixtures,
artifacts: Artifacts,

preload_path: NativeString,
}
Expand All @@ -44,9 +44,9 @@ impl SpyImpl {
use const_format::formatcp;
use xxhash_rust::const_xxh3::xxh3_128;

use crate::fixture::Fixture;
use crate::artifact::Artifact;

const PRELOAD_CDYLIB: Fixture = Fixture {
const PRELOAD_CDYLIB: Artifact = Artifact {
name: "fspy_preload",
content: PRELOAD_CDYLIB_BINARY,
hash: formatcp!("{:x}", xxh3_128(PRELOAD_CDYLIB_BINARY)),
Expand All @@ -56,10 +56,10 @@ impl SpyImpl {
Ok(Self {
preload_path: preload_cdylib_path.as_path().into(),
#[cfg(target_os = "macos")]
fixtures: {
let coreutils_path = macos_fixtures::COREUTILS_BINARY.write_to(dir, "")?;
let bash_path = macos_fixtures::OILS_BINARY.write_to(dir, "")?;
Fixtures {
artifacts: {
let coreutils_path = macos_artifacts::COREUTILS_BINARY.write_to(dir, "")?;
let bash_path = macos_artifacts::OILS_BINARY.write_to(dir, "")?;
Artifacts {
bash_path: bash_path.as_path().into(),
coreutils_path: coreutils_path.as_path().into(),
}
Expand All @@ -78,7 +78,7 @@ impl SpyImpl {
ipc_channel_conf,

#[cfg(target_os = "macos")]
fixtures: self.fixtures.clone(),
artifacts: self.artifacts.clone(),

preload_path: self.preload_path.clone(),

Expand Down
22 changes: 11 additions & 11 deletions crates/fspy/src/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ use xxhash_rust::const_xxh3::xxh3_128;

use crate::{
ChildTermination, TrackedChild,
artifact::Artifact,
command::Command,
error::SpawnError,
fixture::Fixture,
ipc::{OwnedReceiverLockGuard, SHM_CAPACITY},
};

const PRELOAD_CDYLIB_BINARY: &[u8] = include_bytes!(env!("CARGO_CDYLIB_FILE_FSPY_PRELOAD_WINDOWS"));
const INTERPOSE_CDYLIB: Fixture = Fixture::new(
const INTERPOSE_CDYLIB: Artifact = Artifact::new(
"fsyp_preload",
PRELOAD_CDYLIB_BINARY,
formatcp!("{:x}", xxh3_128(PRELOAD_CDYLIB_BINARY)),
Expand All @@ -52,27 +52,27 @@ impl PathAccessIterable {

#[derive(Debug, Clone)]
pub struct SpyImpl {
asni_dll_path_with_nul: Arc<CStr>,
ansi_dll_path_with_nul: Arc<CStr>,
}

impl SpyImpl {
pub fn init_in(path: &Path) -> io::Result<Self> {
let dll_path = INTERPOSE_CDYLIB.write_to(&path, ".dll").unwrap();

let wide_dll_path = dll_path.as_os_str().encode_wide().collect::<Vec<u16>>();
let mut asni_dll_path =
let mut ansi_dll_path =
winsafe::WideCharToMultiByte(CP::ACP, WC::NoValue, &wide_dll_path, None, None)
.map_err(|err| io::Error::from_raw_os_error(err.raw() as i32))?;

asni_dll_path.push(0);
ansi_dll_path.push(0);

let asni_dll_path_with_nul =
unsafe { CStr::from_bytes_with_nul_unchecked(asni_dll_path.as_slice()) };
Ok(Self { asni_dll_path_with_nul: asni_dll_path_with_nul.into() })
let ansi_dll_path_with_nul =
unsafe { CStr::from_bytes_with_nul_unchecked(ansi_dll_path.as_slice()) };
Ok(Self { ansi_dll_path_with_nul: ansi_dll_path_with_nul.into() })
}

pub(crate) async fn spawn(&self, command: Command) -> Result<TrackedChild, SpawnError> {
let asni_dll_path_with_nul = Arc::clone(&self.asni_dll_path_with_nul);
let ansi_dll_path_with_nul = Arc::clone(&self.ansi_dll_path_with_nul);
let mut command = command.into_tokio_command();

command.creation_flags(CREATE_SUSPENDED);
Expand All @@ -87,7 +87,7 @@ impl SpyImpl {
let std_child = std_command.spawn()?;
*spawn_success = true;

let mut dll_paths = asni_dll_path_with_nul.as_ptr().cast::<c_char>();
let mut dll_paths = ansi_dll_path_with_nul.as_ptr().cast::<c_char>();
let process_handle = std_child.as_raw_handle().cast::<winapi::ctypes::c_void>();
let success =
unsafe { DetourUpdateProcessWithDll(process_handle, &mut dll_paths, 1) };
Expand All @@ -97,7 +97,7 @@ impl SpyImpl {

let payload = Payload {
channel_conf: channel_conf.clone(),
asni_dll_path_with_nul: asni_dll_path_with_nul.to_bytes(),
ansi_dll_path_with_nul: ansi_dll_path_with_nul.to_bytes(),
};
let payload_bytes = bincode::encode_to_vec(payload, BINCODE_CONFIG).unwrap();
let success = unsafe {
Expand Down
4 changes: 2 additions & 2 deletions crates/fspy_preload_windows/src/windows/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ impl<'a> Client<'a> {
}
}

pub fn asni_dll_path(&self) -> &'a CStr {
unsafe { CStr::from_bytes_with_nul_unchecked(self.payload.asni_dll_path_with_nul) }
pub fn ansi_dll_path(&self) -> &'a CStr {
unsafe { CStr::from_bytes_with_nul_unchecked(self.payload.ansi_dll_path_with_nul) }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static DETOUR_CREATE_PROCESS_W: Detour<
lp_current_directory,
lp_startup_info,
lp_process_information,
client.asni_dll_path().as_ptr().cast(),
client.ansi_dll_path().as_ptr().cast(),
Some(create_process_with_payload_w),
)
}
Expand Down Expand Up @@ -261,7 +261,7 @@ static DETOUR_CREATE_PROCESS_A: Detour<
lp_current_directory,
lp_startup_info,
lp_process_information,
client.asni_dll_path().as_ptr().cast(),
client.ansi_dll_path().as_ptr().cast(),
Some(create_process_with_payload_a),
)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/fspy_shared/src/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ DEFINE_GUID!(PAYLOAD_ID, 0xfc4845f1, 0x3a8b, 0x4f05, 0xa3, 0xd3, 0xa5, 0xe9, 0xe
#[derive(Encode, BorrowDecode, Debug, Clone)]
pub struct Payload<'a> {
pub channel_conf: ChannelConf,
pub asni_dll_path_with_nul: &'a [u8],
pub ansi_dll_path_with_nul: &'a [u8],
}
4 changes: 2 additions & 2 deletions crates/fspy_shared_unix/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ pub struct Payload {
pub preload_path: NativeString,

#[cfg(target_os = "macos")]
pub fixtures: Fixtures,
pub artifacts: Artifacts,

#[cfg(target_os = "linux")]
pub seccomp_payload: fspy_seccomp_unotify::payload::SeccompPayload,
}

#[cfg(target_os = "macos")]
#[derive(Debug, Encode, Decode, Clone)]
pub struct Fixtures {
pub struct Artifacts {
pub bash_path: NativeString,
pub coreutils_path: NativeString,
// pub interpose_cdylib_path: NativeString,
Expand Down
6 changes: 3 additions & 3 deletions crates/fspy_shared_unix/src/spawn/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ pub fn handle_exec(
(program_path.parent(), program_path.file_name())
{
if matches!(parent.as_os_str().as_bytes(), b"/bin" | b"/usr/bin") {
let fixtures = &encoded_payload.payload.fixtures;
let artifacts = &encoded_payload.payload.artifacts;
if matches!(file_name.as_bytes(), b"sh" | b"bash") {
command.program = fixtures.bash_path.as_os_str().as_bytes().into();
command.program = artifacts.bash_path.as_os_str().as_bytes().into();
true
} else if COREUTILS_FUNCTIONS.contains(file_name.as_bytes()) {
command.program = fixtures.coreutils_path.as_os_str().as_bytes().into();
command.program = artifacts.coreutils_path.as_os_str().as_bytes().into();
true
} else {
false
Expand Down