Skip to content

Commit

Permalink
examples/fake-signing: Make runnable on Linux (#26)
Browse files Browse the repository at this point in the history
* examples/fake-signing: Fix printing success even when mismatched

And some other cleanups.

* 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).
  • Loading branch information
MarijnS95 authored Jan 31, 2022
1 parent 518eb2d commit 5335634
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 45 deletions.
52 changes: 28 additions & 24 deletions examples/validate-fake-signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<MinimalHeader>();
let header_ref = unsafe { &*header_ptr };
header_ref.hash_digest
}

use hassle_rs::{compile_hlsl, fake_sign_dxil_in_place, validate_dxil};
Expand All @@ -33,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 &= true;
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");
}
}
23 changes: 6 additions & 17 deletions examples/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<MinimalHeader>();
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::<MinimalHeader>();
let header_ref = unsafe { &*header_ptr };
header_ref.hash_digest
}

fn main() {
Expand Down
8 changes: 4 additions & 4 deletions src/fake_sign/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 <https://github.com/baldurk/renderdoc/blob/v1.x/renderdoc/driver/shaders/dxbc/dxbc_container.cpp#L832>
Expand Down

0 comments on commit 5335634

Please sign in to comment.