From bb2870e56d6c9a0a7b96be8287193a753e3a4391 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Jul 2021 15:21:01 -0700 Subject: add ffi wrappers for real mode, protected mode, and a multiarch build --- ffi/README.md | 37 ++++++++++++++++++++++++++++++++++--- ffi/long_mode/Cargo.toml | 2 +- ffi/multiarch/Cargo.toml | 7 ++++++- ffi/multiarch/src/lib.rs | 21 +++++++++++++++++++++ ffi/protected_mode/Cargo.toml | 2 +- ffi/protected_mode/src/lib.rs | 6 +++--- ffi/real_mode/Cargo.toml | 2 +- ffi/real_mode/src/lib.rs | 11 +++++++++++ ffi/src/protected_mode.rs | 17 ++++++++++------- ffi/src/real_mode.rs | 17 ++++++++++------- 10 files changed, 98 insertions(+), 24 deletions(-) (limited to 'ffi') diff --git a/ffi/README.md b/ffi/README.md index 02a20e3..e795389 100644 --- a/ffi/README.md +++ b/ffi/README.md @@ -1,8 +1,39 @@ +# `ffi`/ + +this directory includes (relatively small) repackagings of `yaxpeax-x86` for use from non-Rust callers. these bindings are intended to be expanded on an as-needed basis, so if they are insufficient, please file an issue or contact the maintainers. + # building -for maximum small, ffi crates' `rustflags` includes `-C link-args=-nostdlib`. to avoid conflicts with the native toolchain, this motivates cross-compiling for the native target with `--target x86_64-unknown-linux-gnu`. +for minimal size, ffi crates' `rustflags` includes `-C link-args=-nostdlib`. to avoid conflicts with the native toolchain, this motivates cross-compiling for the native target with `--target x86_64-unknown-linux-gnu`. then, to remove extra `eh_frame` information from core, rebuild core with panic=abort by `-Z build-std` to cargo. in total, a build command for `yaxpeax_x86_ffi*` looks like: ``` -cargo build -Z build-std --release --no-default-features --verbose --target x86_64-unknown-linux-gnu -`` +cargo build -Z build-std --release --no-default-features --target x86_64-unknown-linux-gnu +``` + +where you must replace `x86_64-unknown-linux-gnu` with the target system the build artifacts will be used on. `rustup show` should give a good indication of the local target, and of course you can cross-compile to other architectures and targets if so inclined - `yaxpeax-x86` should have no specific dependencies on any architecture or target. + +because even builds for the current host are technically cross-compiles with the above command, build artifacts will be in `target//{release,debug}/`, instead of the typical `target/{release,debug>/`. for example, when i build these crates the artifacts end up like this: + +``` +target/x86_64-unknown-linux-gnu/ +├── [ 177] CACHEDIR.TAG +└── [4.0K] release + ├── [4.0K] build + ├── [ 12K] deps + ├── [4.0K] examples + ├── [4.0K] incremental + ├── [730K] libyaxpeax_x86_ffi_long_mode.a + ├── [ 909] libyaxpeax_x86_ffi_long_mode.d + ├── [143K] libyaxpeax_x86_ffi_long_mode.so + ├── [1.2M] libyaxpeax_x86_ffi_multiarch.a + ├── [1.0K] libyaxpeax_x86_ffi_multiarch.d + ├── [360K] libyaxpeax_x86_ffi_multiarch.so + ├── [714K] libyaxpeax_x86_ffi_protected_mode.a + ├── [ 929] libyaxpeax_x86_ffi_protected_mode.d + ├── [126K] libyaxpeax_x86_ffi_protected_mode.so + ├── [715K] libyaxpeax_x86_ffi_real_mode.a + └── [ 909] libyaxpeax_x86_ffi_real_mode.d + +5 directories, 12 files +``` diff --git a/ffi/long_mode/Cargo.toml b/ffi/long_mode/Cargo.toml index e96a54f..5196c2d 100644 --- a/ffi/long_mode/Cargo.toml +++ b/ffi/long_mode/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "yaxpeax_x86_ffi_long_mode" -version = "0.0.3" +version = "0.1.0" authors = ["iximeow "] edition = "2018" diff --git a/ffi/multiarch/Cargo.toml b/ffi/multiarch/Cargo.toml index 370d39c..1632996 100644 --- a/ffi/multiarch/Cargo.toml +++ b/ffi/multiarch/Cargo.toml @@ -11,4 +11,9 @@ yaxpeax-arch = { version = "0.1.0", default-features = false } [lib] name = "yaxpeax_x86_ffi_multiarch" path = "src/lib.rs" -crate-type = ["staticlib"] +crate-type = ["staticlib", "cdylib"] + +[features] +default = ["fmt"] + +fmt = ["yaxpeax-x86/fmt"] diff --git a/ffi/multiarch/src/lib.rs b/ffi/multiarch/src/lib.rs index e69de29..61553fc 100644 --- a/ffi/multiarch/src/lib.rs +++ b/ffi/multiarch/src/lib.rs @@ -0,0 +1,21 @@ +#![no_std] + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[path = "../../src/long_mode.rs"] +mod long_mode; + +pub use long_mode::*; + +#[path = "../../src/protected_mode.rs"] +mod protected_mode; + +pub use protected_mode::*; + +#[path = "../../src/real_mode.rs"] +mod real_mode; + +pub use real_mode::*; diff --git a/ffi/protected_mode/Cargo.toml b/ffi/protected_mode/Cargo.toml index 95e8bf4..164c0de 100644 --- a/ffi/protected_mode/Cargo.toml +++ b/ffi/protected_mode/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] yaxpeax-x86 = { path = "../../", default-features = false } -yaxpeax-arch = { version = "0.0.4", default-features = false } +yaxpeax-arch = { version = "0.1.0", default-features = false } [lib] name = "yaxpeax_x86_ffi_protected_mode" diff --git a/ffi/protected_mode/src/lib.rs b/ffi/protected_mode/src/lib.rs index 368f8a9..95fed67 100644 --- a/ffi/protected_mode/src/lib.rs +++ b/ffi/protected_mode/src/lib.rs @@ -5,7 +5,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} } -#[path = "../../src/long_mode.rs"] -mod long_mode; +#[path = "../../src/protected_mode.rs"] +mod protected_mode; -pub use long_mode::*; +pub use protected_mode::*; diff --git a/ffi/real_mode/Cargo.toml b/ffi/real_mode/Cargo.toml index f24f8a4..3451d59 100644 --- a/ffi/real_mode/Cargo.toml +++ b/ffi/real_mode/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] yaxpeax-x86 = { path = "../../", default-features = false } -yaxpeax-arch = { version = "0.0.4", default-features = false } +yaxpeax-arch = { version = "0.1.0", default-features = false } [lib] name = "yaxpeax_x86_ffi_real_mode" diff --git a/ffi/real_mode/src/lib.rs b/ffi/real_mode/src/lib.rs index e69de29..83c1be3 100644 --- a/ffi/real_mode/src/lib.rs +++ b/ffi/real_mode/src/lib.rs @@ -0,0 +1,11 @@ +#![no_std] + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[path = "../../src/real_mode.rs"] +mod real_mode; + +pub use real_mode::*; diff --git a/ffi/src/protected_mode.rs b/ffi/src/protected_mode.rs index fc0c6a9..5c679e4 100644 --- a/ffi/src/protected_mode.rs +++ b/ffi/src/protected_mode.rs @@ -1,10 +1,11 @@ -use yaxpeax_arch::{Arch, Decoder, LengthedInstruction, AddressBase}; +use yaxpeax_arch::{Arch, Decoder, LengthedInstruction, U8Reader, AddressBase}; use yaxpeax_x86::protected_mode; #[no_mangle] -pub unsafe extern "C" fn yaxpeax_x86_32_decode_optimistic(data: *const u8, length: u64, inst: *mut protected_mode::Instruction) -> bool { +pub unsafe extern "C" fn yaxpeax_x86_32_decode(data: *const u8, length: u64, inst: *mut protected_mode::Instruction) -> bool { let inst: &mut protected_mode::Instruction = core::mem::transmute(inst); - ::Decoder::default().decode_into(inst, core::slice::from_raw_parts(data as *const u8, length as usize).iter().cloned()).is_err() + let mut reader = U8Reader::new(core::slice::from_raw_parts(data as *const u8, length as usize)); + ::Decoder::default().decode_into(inst, &mut reader).is_err() } #[no_mangle] @@ -13,15 +14,17 @@ pub unsafe extern "C" fn yaxpeax_x86_32_instr_length(inst: *mut protected_mode:: 0.wrapping_offset(inst.len()).to_linear() } -#[cfg(fmt)] +#[cfg(feature = "fmt")] mod write_sink; -#[cfg(fmt)] +#[cfg(feature = "fmt")] mod fmt { - use write_sink::InstructionSink; + use super::write_sink::InstructionSink; use core::fmt::Write; + use yaxpeax_x86::protected_mode; + #[no_mangle] pub unsafe extern "C" fn yaxpeax_x86_32_fmt(inst: *mut protected_mode::Instruction, text: *mut u8, len: usize) { let inst: &mut protected_mode::Instruction = core::mem::transmute(inst); @@ -31,5 +34,5 @@ mod fmt { } } -#[cfg(fmt)] +#[cfg(feature = "fmt")] pub use fmt::yaxpeax_x86_32_fmt; diff --git a/ffi/src/real_mode.rs b/ffi/src/real_mode.rs index 6a5f866..879bffa 100644 --- a/ffi/src/real_mode.rs +++ b/ffi/src/real_mode.rs @@ -1,10 +1,11 @@ -use yaxpeax_arch::{Arch, Decoder, LengthedInstruction, AddressBase}; +use yaxpeax_arch::{Arch, Decoder, LengthedInstruction, U8Reader, AddressBase}; use yaxpeax_x86::real_mode; #[no_mangle] -pub unsafe extern "C" fn yaxpeax_x86_16_decode_optimistic(data: *const u8, length: u64, inst: *mut real_mode::Instruction) -> bool { +pub unsafe extern "C" fn yaxpeax_x86_16_decode(data: *const u8, length: u64, inst: *mut real_mode::Instruction) -> bool { let inst: &mut real_mode::Instruction = core::mem::transmute(inst); - ::Decoder::default().decode_into(inst, core::slice::from_raw_parts(data as *const u8, length as usize).iter().cloned()).is_err() + let mut reader = U8Reader::new(core::slice::from_raw_parts(data as *const u8, length as usize)); + ::Decoder::default().decode_into(inst, &mut reader).is_err() } #[no_mangle] @@ -13,15 +14,17 @@ pub unsafe extern "C" fn yaxpeax_x86_16_instr_length(inst: *mut real_mode::Instr 0.wrapping_offset(inst.len()).to_linear() } -#[cfg(fmt)] +#[cfg(feature = "fmt")] mod write_sink; -#[cfg(fmt)] +#[cfg(feature = "fmt")] mod fmt { - use write_sink::InstructionSink; + use super::write_sink::InstructionSink; use core::fmt::Write; + use yaxpeax_x86::real_mode; + #[no_mangle] pub unsafe extern "C" fn yaxpeax_x86_16_fmt(inst: *mut real_mode::Instruction, text: *mut u8, len: usize) { let inst: &mut real_mode::Instruction = core::mem::transmute(inst); @@ -31,5 +34,5 @@ mod fmt { } } -#[cfg(fmt)] +#[cfg(feature = "fmt")] pub use fmt::yaxpeax_x86_16_fmt; -- cgit v1.1