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
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"ghcr.io/devcontainers/features/rust:1": {
"version": "1.87",
"profile": "minimal",
"targets": "aarch64-unknown-linux-gnu,x86_64-unknown-linux-musl,x86_64-pc-windows-gnu,aarch64-apple-darwin,x86_64-apple-darwin"
"targets": "aarch64-unknown-linux-gnu,x86_64-unknown-linux-musl,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc,aarch64-apple-darwin,x86_64-apple-darwin"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "lts"
Expand Down Expand Up @@ -65,5 +65,5 @@
// "mounts": [
// "source=${localEnv:HOME}${localEnv:USERPROFILE}/MacOSX.sdk,target=/MacOSX.sdk,readonly,type=bind"
// ],
"postAttachCommand": "cargo install cargo-zigbuild"
"postAttachCommand": "cargo install cargo-zigbuild && cargo install xwin --target x86_64-unknown-linux-gnu"
}
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ jobs:
uses: dtolnay/rust-toolchain@master
if: matrix.os == 'windows-latest'
with:
toolchain: 'nightly-2025-01-31'
toolchain: 'nightly-2025-11-27'
default: false
profile: minimal
components: rust-src
components: rust-src, rustfmt
- name: rust-cache
uses: Swatinem/rust-cache@v2
with:
Expand All @@ -73,7 +73,7 @@ jobs:
name: Build reflective loader
run: |
cd ./bin/reflective_loader/
cargo +nightly-2025-01-31 build --release -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
cargo +nightly-2025-11-27 build --release -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
- name: Install latest nextest & cargo-llvm-cov release
uses: taiki-e/install-action@v2
with:
Expand Down
1 change: 0 additions & 1 deletion bin/reflective_loader/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[build]
target = "x86_64-pc-windows-msvc"
rustflags = ["-Z", "share-generics=n"]
profiler = false
2 changes: 1 addition & 1 deletion bin/reflective_loader/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[toolchain]
channel = "nightly-2025-01-31"
channel = "nightly-2025-11-27"
151 changes: 82 additions & 69 deletions implants/lib/eldritch/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ fn build_bin_create_file_dll() {
println!("cargo:rerun-if-changed=../../../bin/create_file_dll/src/main.rs");
println!("cargo:rerun-if-changed=../../../bin/create_file_dll/Cargo.toml");

let target_arch = std::env::var_os("CARGO_CFG_TARGET_ARCH").unwrap();
let target_arch_str = target_arch.to_str().unwrap();
let target_vendor = std::env::var_os("CARGO_CFG_TARGET_VENDOR").unwrap();
let target_vendor_str = target_vendor.to_str().unwrap();
let target_os = std::env::var_os("CARGO_CFG_TARGET_OS").unwrap();
let target_os_str = target_os.to_str().unwrap();
let target_env = std::env::var_os("CARGO_CFG_TARGET_ENV").unwrap();
let target_env_str = target_env.to_str().unwrap();

let target_triple =
format!("{target_arch_str}-{target_vendor_str}-{target_os_str}-{target_env_str}");

// Get the path of the create_file_dll workspace member
let cargo_root = env!("CARGO_MANIFEST_DIR");
let relative_path_to_test_dll = "../../../bin/create_file_dll/";
Expand All @@ -22,7 +34,7 @@ fn build_bin_create_file_dll() {

println!("Starting cargo build lib");
let res = Command::new("cargo")
.args(["build", "--lib"])
.args(["build", "--lib", &format!("--target={target_triple}")])
.current_dir(test_dll_path)
.stderr(Stdio::piped())
.spawn()
Expand All @@ -37,7 +49,7 @@ fn build_bin_create_file_dll() {
.for_each(|line| println!("cargo dll build: {}", line));

let relative_path_to_test_dll_file =
"../../../bin/create_file_dll/target/debug/create_file_dll.dll";
&format!("../../../bin/create_file_dll/target/{target_triple}/debug/create_file_dll.dll");
let test_dll_path = Path::new(cargo_root).join(relative_path_to_test_dll_file);
assert!(test_dll_path.is_file());
}
Expand All @@ -49,90 +61,91 @@ fn build_bin_reflective_loader() {
process::{Command, Stdio},
};

let target_arch = std::env::var_os("CARGO_CFG_TARGET_ARCH").unwrap();
let target_arch_str = target_arch.to_str().unwrap();
let target_vendor = std::env::var_os("CARGO_CFG_TARGET_VENDOR").unwrap();
let target_vendor_str = target_vendor.to_str().unwrap();
let target_os = std::env::var_os("CARGO_CFG_TARGET_OS").unwrap();
let target_os_str = target_os.to_str().unwrap();
let target_env = std::env::var_os("CARGO_CFG_TARGET_ENV").unwrap();
let target_env_str = target_env.to_str().unwrap();

let target_triple =
format!("{target_arch_str}-{target_vendor_str}-{target_os_str}-{target_env_str}");

let cargo_root = env!("CARGO_MANIFEST_DIR");
// Hardcoded target for the reflective loader as per manual instructions
let loader_target_triple = "x86_64-pc-windows-msvc";

let reflective_loader_path_str = "../../../bin/reflective_loader";
let loader_files = [
"src/lib.rs",
"src/loader.rs",
"Cargo.toml",
&format!("target/{target_triple}/release/reflective_loader.dll"),
];
// Define which files should cause this section to be rebuilt.

// Define triggers for rebuild
let loader_files = ["src/lib.rs", "src/loader.rs", "Cargo.toml"];
for f in loader_files {
let binding = format!("{}/{}", reflective_loader_path_str, f);
let tmp_path = Path::new(cargo_root).join(binding.as_str());
let tmp_str = tmp_path.to_str().unwrap();
println!("cargo:rerun-if-changed={tmp_str}");
// Only trigger rerun if the source file actually exists
if let Ok(canon_path) = tmp_path.canonicalize() {
println!("cargo:rerun-if-changed={}", canon_path.to_str().unwrap());
}
}

// Get the path of the create_file_dll workspace member
let relative_path_to_test_dll = "../../../bin/reflective_loader/";
let test_dll_path = Path::new(cargo_root)
.join(relative_path_to_test_dll)
// Get the absolute path of the reflective_loader workspace member
let loader_root_path = Path::new(cargo_root)
.join(reflective_loader_path_str)
.canonicalize()
.expect("Could not find reflective_loader directory");

assert!(loader_root_path.is_dir());

println!("Starting cargo xwin build for reflective_loader");

// Command:
// cargo xwin build --release \
// -Z build-std=core,compiler_builtins \
// -Z build-std-features=compiler-builtins-mem \
// --target x86_64-pc-windows-msvc

let res_build = Command::new("cargo")
.args([
"+nightly", // -Z flags require nightly
"xwin",
"build",
"--release",
"-Z",
"build-std=core,compiler_builtins",
"-Z",
"build-std-features=compiler-builtins-mem",
"--target",
loader_target_triple,
])
.current_dir(&loader_root_path)
// Clean environment to prevent host compilation flags from leaking into target compilation
.env_remove("TARGET")
.env_remove("CARGO")
.env_remove("RUSTC")
.env_remove("RUSTUP_TOOLCHAIN")
// We generally want to remove CARGO_TARGET_DIR so the nested cargo uses its own target dir
.env_remove("CARGO_TARGET_DIR")
.env_remove("CARGO_MANIFEST_DIR")
.env(
"RUSTFLAGS",
"-C target-feature=+crt-static -C link-arg=/FIXED",
)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to spawn cargo xwin build")
.stderr
.unwrap();
assert!(test_dll_path.is_dir());

println!("Starting cargo build lib");
// Define custom builds based on the target triple
let res_build = match target_triple.as_str() {
"x86_64-pc-windows-msvc" => Command::new("cargo")
.args([
"build",
"--release",
"-Z",
"build-std=core,compiler_builtins",
"-Z",
"build-std-features=compiler-builtins-mem",
&format!("--target={target_triple}"),
])
.current_dir(test_dll_path.clone())
.env("RUSTFLAGS", "-C target-feature=+crt-static")
.stderr(Stdio::piped())
.spawn()
.unwrap()
.stderr
.unwrap(),
_ => Command::new("cargo")
.args([
"build",
"--release",
"--lib",
&format!("--target={target_triple}"),
])
.current_dir(test_dll_path.clone())
.env("RUSTFLAGS", "-C target-feature=+crt-static")
.stderr(Stdio::piped())
.spawn()
.unwrap()
.stderr
.unwrap(),
};

let reader = BufReader::new(res_build);
reader
.lines()
.map_while(Result::ok)
.for_each(|line| println!("cargo dll build: {}", line));
.for_each(|line| println!("cargo loader build: {}", line));

// Verify the file exists at the expected location
// ../../../bin/reflective_loader/target/x86_64-pc-windows-msvc/release/reflective_loader.dll
let relative_path_to_loader_dll = format!(
"{}/target/{}/release/reflective_loader.dll",
reflective_loader_path_str, loader_target_triple
);

let relative_path_to_test_dll_file = format!(
"../../../bin/reflective_loader/target/{target_triple}/release/reflective_loader.dll"
let loader_dll_path = Path::new(cargo_root).join(relative_path_to_loader_dll);
assert!(
loader_dll_path.exists(),
"reflective_loader.dll not found at expected path: {:?}",
loader_dll_path
);
let loader_dll_path = Path::new(cargo_root).join(relative_path_to_test_dll_file);
assert!(loader_dll_path.is_file());
}

#[cfg(windows)]
Expand Down
9 changes: 8 additions & 1 deletion implants/lib/eldritch/src/sys/dll_inject_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,15 @@ mod tests {

// Get the path to our test dll file.
let cargo_root = env!("CARGO_MANIFEST_DIR");

#[cfg(host_family = "windows")]
let relative_path_to_test_dll =
"..\\..\\..\\bin\\create_file_dll\\target\\x86_64-pc-windows-msvc\\debug\\create_file_dll.dll";

#[cfg(host_family = "unix")]
let relative_path_to_test_dll =
"..\\..\\..\\bin\\create_file_dll\\target\\debug\\create_file_dll.dll";
"../../../../../bin/create_file_dll/target/x86_64-pc-windows-gnu/debug/create_file_dll.dll";

let test_dll_path = Path::new(cargo_root).join(relative_path_to_test_dll);
assert!(test_dll_path.is_file());

Expand Down
24 changes: 8 additions & 16 deletions implants/lib/eldritch/src/sys/dll_reflect_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,6 @@ use {
},
};

#[cfg(all(host_family = "windows", target_os = "windows"))]
macro_rules! win_target {
() => {
r"x86_64-pc-windows-msvc"
};
}
#[cfg(all(host_family = "unix", target_os = "windows"))]
macro_rules! win_target {
() => {
r"x86_64-pc-windows-gnu"
};
}

#[cfg(all(host_family = "unix", target_os = "windows"))]
macro_rules! sep {
() => {
Expand Down Expand Up @@ -65,7 +52,7 @@ const LOADER_BYTES: &[u8] = include_bytes!(concat!(
sep!(),
"target",
sep!(),
win_target!(),
"x86_64-pc-windows-msvc",
sep!(),
"release",
sep!(),
Expand Down Expand Up @@ -413,9 +400,14 @@ mod tests {
use sysinfo::{Pid, PidExt, ProcessExt, Signal, System, SystemExt};
use tempfile::NamedTempFile;

#[cfg(target_os = "windows")]
#[cfg(host_family = "windows")]
const TEST_DLL_BYTES: &[u8] = include_bytes!(
"..\\..\\..\\..\\..\\bin\\create_file_dll\\target\\x86_64-pc-windows-msvc\\debug\\create_file_dll.dll"
);

#[cfg(host_family = "unix")]
const TEST_DLL_BYTES: &[u8] = include_bytes!(
"..\\..\\..\\..\\..\\bin\\create_file_dll\\target\\debug\\create_file_dll.dll"
"../../../../../bin/create_file_dll/target/x86_64-pc-windows-gnu/debug/create_file_dll.dll"
);

#[test]
Expand Down
Loading