diff options
| author | Glenn Smith <glenn@vector35.com> | 2024-12-27 16:14:46 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2025-01-30 17:20:05 -0500 |
| commit | 8862696926173104957729683832591438161557 (patch) | |
| tree | 78ba6d7dc8144430136086c8dc84726171eec8ab /rust/tests/render_layer.rs | |
| parent | 5a5426d030b6be26d4564ba1eba2d8a275533256 (diff) | |
Render Layers
Diffstat (limited to 'rust/tests/render_layer.rs')
| -rw-r--r-- | rust/tests/render_layer.rs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/rust/tests/render_layer.rs b/rust/tests/render_layer.rs new file mode 100644 index 00000000..6c914564 --- /dev/null +++ b/rust/tests/render_layer.rs @@ -0,0 +1,96 @@ +use binaryninja::basic_block::BasicBlock; +use binaryninja::disassembly::{DisassemblyOption, DisassemblySettings, DisassemblyTextLine}; +use binaryninja::function::NativeBlock; +use binaryninja::headless::Session; +use binaryninja::linear_view::LinearViewObject; +use binaryninja::render_layer::{register_render_layer, CoreRenderLayer, RenderLayer}; +use rstest::{fixture, rstest}; +use std::path::PathBuf; + +#[fixture] +#[once] +fn session() -> Session { + Session::new().expect("Failed to initialize session") +} + +#[rstest] +fn test_render_layer_register(_session: &Session) { + struct EmptyRenderLayer; + impl RenderLayer for EmptyRenderLayer {} + register_render_layer("Test Render Layer", EmptyRenderLayer); + CoreRenderLayer::render_layer_by_name("Test Render Layer").expect("Failed to get render layer"); +} + +#[rstest] +fn test_render_layer_linear_view(_session: &Session) { + let out_dir = env!("OUT_DIR").parse::<PathBuf>().unwrap(); + let view = binaryninja::load(out_dir.join("atox.obj")).expect("Failed to create view"); + + struct NopRenderLayer; + impl RenderLayer for NopRenderLayer { + fn apply_to_disassembly_block( + &self, + _block: &BasicBlock<NativeBlock>, + lines: Vec<DisassemblyTextLine>, + ) -> Vec<DisassemblyTextLine> { + println!("Nothing added to disassembly block"); + lines + } + } + let (_, nop_render_layer) = register_render_layer("Nop Render Layer", NopRenderLayer); + + // Create linear view object stuff + let settings = DisassemblySettings::new(); + settings.set_option(DisassemblyOption::ShowAddress, false); + settings.set_option(DisassemblyOption::WaitForIL, true); + settings.set_option(DisassemblyOption::IndentHLILBody, false); + settings.set_option(DisassemblyOption::ShowCollapseIndicators, false); + settings.set_option(DisassemblyOption::ShowFunctionHeader, false); + + let linear_view = LinearViewObject::disassembly(&view, &settings); + let mut cursor = linear_view.create_cursor(); + // Seek to the start of the function `__crt_strtox::is_overflow_condition<uint64_t>` + cursor.seek_to_address(0x26240); + let current_object = cursor.current_object(); + let current_lines = cursor.lines().to_vec(); + + let new_lines = nop_render_layer.apply_to_linear_view_object( + ¤t_object, + None, + None, + current_lines.clone(), + ); + + // These should 100% be in the same order. If not that is a bug. + + for (i, (current_line, new_line)) in current_lines.iter().zip(new_lines.iter()).enumerate() { + if current_line != new_line { + assert_eq!(current_line, new_line, "Line mismatch at index {}", i); + } + } + + struct AddRenderLayer; + impl RenderLayer for AddRenderLayer { + fn apply_to_disassembly_block( + &self, + _block: &BasicBlock<NativeBlock>, + mut lines: Vec<DisassemblyTextLine>, + ) -> Vec<DisassemblyTextLine> { + println!("Adding to disassembly block"); + lines.push(DisassemblyTextLine::from("heyyyyy")); + lines + } + } + let (_, adding_render_layer) = register_render_layer("Add Render Layer", AddRenderLayer); + + // Calling lines() again should now have the render layer applied. + cursor.add_render_layer(&adding_render_layer); + let new_current_lines = cursor.lines().to_vec(); + // Assert that new_current_lines is one longer than current_lines (we added a line) + assert_eq!(new_current_lines.len(), current_lines.len() + 1); + + // Remove the render layer and make sure that the line is no longer present. + cursor.remove_render_layer(&adding_render_layer); + let new_new_current_lines = cursor.lines().to_vec(); + assert_eq!(new_new_current_lines.len(), current_lines.len()); +} |
