From 7ff4869a55c76337570b1b1c0a5a3de52d6d3623 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 12 Jan 2022 10:42:55 +0100 Subject: [PATCH 1/2] examples/fake-signing: Fix printing success even when mismatched And some other cleanups. --- examples/validate-fake-signing.rs | 15 ++++----------- examples/validate.rs | 23 ++++++----------------- src/fake_sign/mod.rs | 8 ++++---- 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/examples/validate-fake-signing.rs b/examples/validate-fake-signing.rs index d2782fd..0d45905 100644 --- a/examples/validate-fake-signing.rs +++ b/examples/validate-fake-signing.rs @@ -5,16 +5,9 @@ pub struct MinimalHeader { } fn get_digest(buffer: &[u8]) -> [u32; 4] { - let buffer_ptr: *const u8 = buffer.as_ptr(); - let header_ptr: *const MinimalHeader = buffer_ptr as *const _; - let header_ref: &MinimalHeader = unsafe { &*header_ptr }; - let digest: [u32; 4] = [ - header_ref.hash_digest[0], - header_ref.hash_digest[1], - header_ref.hash_digest[2], - header_ref.hash_digest[3], - ]; - digest + let header_ptr = buffer.as_ptr().cast::(); + let header_ref = unsafe { &*header_ptr }; + header_ref.hash_digest } use hassle_rs::{compile_hlsl, fake_sign_dxil_in_place, validate_dxil}; @@ -49,7 +42,7 @@ fn main() { if fake_signed_digest != with_digest { println!("---- Mismatch in file {} ----", idx); - all_matches &= true; + all_matches &= false; } } diff --git a/examples/validate.rs b/examples/validate.rs index 484b5a5..52b3397 100644 --- a/examples/validate.rs +++ b/examples/validate.rs @@ -10,26 +10,15 @@ pub struct MinimalHeader { // zero_digest & get_digest from https://github.com/gwihlidal/dxil-signing/blob/master/rust/src/main.rs fn zero_digest(buffer: &mut [u8]) { - let buffer_ptr: *mut u8 = buffer.as_mut_ptr(); - let header_ptr: *mut MinimalHeader = buffer_ptr as *mut _; - let header_mut: &mut MinimalHeader = unsafe { &mut *header_ptr }; - header_mut.hash_digest[0] = 0x0; - header_mut.hash_digest[1] = 0x0; - header_mut.hash_digest[2] = 0x0; - header_mut.hash_digest[3] = 0x0; + let header_ptr = buffer.as_mut_ptr().cast::(); + let header_ref = unsafe { &mut *header_ptr }; + header_ref.hash_digest = [0; 4]; } fn get_digest(buffer: &[u8]) -> [u32; 4] { - let buffer_ptr: *const u8 = buffer.as_ptr(); - let header_ptr: *const MinimalHeader = buffer_ptr as *const _; - let header_ref: &MinimalHeader = unsafe { &*header_ptr }; - let digest: [u32; 4] = [ - header_ref.hash_digest[0], - header_ref.hash_digest[1], - header_ref.hash_digest[2], - header_ref.hash_digest[3], - ]; - digest + let header_ptr = buffer.as_ptr().cast::(); + let header_ref = unsafe { &*header_ptr }; + header_ref.hash_digest } fn main() { diff --git a/src/fake_sign/mod.rs b/src/fake_sign/mod.rs index 7c6a781..ab16b04 100644 --- a/src/fake_sign/mod.rs +++ b/src/fake_sign/mod.rs @@ -14,17 +14,17 @@ const DXIL_HEADER_CONTAINER_VERSION_OFFSET: usize = 20; const DXBC_FOURCC: u32 = u32::from_le_bytes([b'D', b'X', b'B', b'C']); fn read_fourcc(dxil: &[u8]) -> u32 { - let header: *const FileHeader = dxil.as_ptr() as *const _; + let header: *const FileHeader = dxil.as_ptr().cast(); unsafe { (*header).fourcc } } fn read_file_length(dxil: &[u8]) -> u32 { - let header: *const FileHeader = dxil.as_ptr() as *const _; + let header: *const FileHeader = dxil.as_ptr().cast(); unsafe { (*header).file_length } } fn write_hash_value(dxil: &mut [u8], state: [u32; 4]) { - let header: *mut FileHeader = dxil.as_mut_ptr() as *mut _; + let header: *mut FileHeader = dxil.as_mut_ptr().cast(); unsafe { (*header).hash_value.copy_from_slice(&state); @@ -34,7 +34,7 @@ fn write_hash_value(dxil: &mut [u8], state: [u32; 4]) { /// Helper function for signing DXIL binary blobs when /// `dxil.dll` might not be available (such as on Linux based /// platforms). -/// This essentially performs the same functionality as `validate_dxil` +/// This essentially performs the same functionality as [`crate::validate_dxil()`] /// but in a more cross platform way. /// /// Ported from From 996f32a7fbf23fd8fd5ccb476daf98968c7fc1f9 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 12 Jan 2022 11:14:33 +0100 Subject: [PATCH 2/2] examples/fake-signing: Make runnable on Linux The main reason for fake signing is making it run on Linux - and not depend on `dxil.dll` on Windows - so it's great if this example runs on Linux as well to see it all working even if that requires a few nasty cfg blocks. Note that this is done with `cfg!()` and regular `if` blocks instead of attributes, such that this code lints and compiles on both Windows and Linux even if the `validate_dxil()` codepath is never entered on the latter (and that way includes, `let mut all_matches` etc don't need to be `#[cfg(windows)]`'ed out either). --- examples/validate-fake-signing.rs | 39 ++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/examples/validate-fake-signing.rs b/examples/validate-fake-signing.rs index 0d45905..351fab9 100644 --- a/examples/validate-fake-signing.rs +++ b/examples/validate-fake-signing.rs @@ -26,27 +26,38 @@ fn main() { let without_digest = get_digest(&dxil); - let validated_dxil = validate_dxil(&dxil).unwrap(); - - let with_digest = get_digest(&validated_dxil); - let result = fake_sign_dxil_in_place(&mut dxil); assert!(result); let fake_signed_digest = get_digest(&dxil); - println!( - "\tAfter compilation: {:?}\n\tAfter dxil.dll: {:?}\n\tAfter fake signing: {:?}", - without_digest, with_digest, fake_signed_digest - ); - - if fake_signed_digest != with_digest { - println!("---- Mismatch in file {} ----", idx); - all_matches &= false; + if cfg!(windows) { + let validated_dxil = validate_dxil(&dxil).unwrap(); + + let with_digest = get_digest(&validated_dxil); + + println!( + "\tAfter compilation: {:?}\n\tAfter dxil.dll: {:?}\n\tAfter fake signing: {:?}", + without_digest, with_digest, fake_signed_digest + ); + + if fake_signed_digest != with_digest { + println!("---- Mismatch in file {} ----", idx); + all_matches &= false; + } + } else { + println!( + "\tAfter compilation: {:?}\n\tAfter fake signing: {:?}", + without_digest, fake_signed_digest + ); } } - if all_matches { - println!("Success"); + if cfg!(windows) { + if all_matches { + println!("Success"); + } + } else { + println!("Warning: Signatures not validated against `dxil.dll` - this is only possible on Windows"); } }