From 1f07d192437aab83f259de3a3792710ef0b3e04f Mon Sep 17 00:00:00 2001 From: Truman Kilen Date: Wed, 3 Dec 2025 03:32:05 -0600 Subject: [PATCH 1/2] Pass arch to finalized LowLevelILFunction to fix disassociated arch in case of no owning functino --- rust/src/low_level_il/function.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/low_level_il/function.rs b/rust/src/low_level_il/function.rs index b473b64d8f..15a83c19e7 100644 --- a/rust/src/low_level_il/function.rs +++ b/rust/src/low_level_il/function.rs @@ -254,7 +254,7 @@ impl Ref> { unsafe { BNFinalizeLowLevelILFunction(self.handle); // Now that we have finalized return the function as is so the caller can reference the "finalized function". - LowLevelILFunction::from_raw(self.handle).to_owned() + LowLevelILFunction::from_raw_with_arch(self.handle, self.arch).to_owned() } } } From ec721b0827332374f9a618814662912339053283 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Thu, 4 Dec 2025 13:17:58 -0500 Subject: [PATCH 2/2] Add test --- rust/tests/low_level_il.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/rust/tests/low_level_il.rs b/rust/tests/low_level_il.rs index 84ae32471f..79a7996487 100644 --- a/rust/tests/low_level_il.rs +++ b/rust/tests/low_level_il.rs @@ -1,4 +1,6 @@ -use binaryninja::architecture::{ArchitectureExt, Intrinsic, Register}; +use binaryninja::architecture::{ + Architecture, ArchitectureExt, CoreArchitecture, Intrinsic, Register, +}; use binaryninja::binary_view::BinaryViewExt; use binaryninja::headless::Session; use binaryninja::low_level_il::expression::{ @@ -8,7 +10,9 @@ use binaryninja::low_level_il::instruction::{ InstructionHandler, LowLevelILInstructionKind, LowLevelInstructionIndex, }; use binaryninja::low_level_il::operation::IntrinsicOutput; -use binaryninja::low_level_il::{LowLevelILRegisterKind, LowLevelILSSARegisterKind, VisitorAction}; +use binaryninja::low_level_il::{ + LowLevelILMutableFunction, LowLevelILRegisterKind, LowLevelILSSARegisterKind, VisitorAction, +}; use std::path::PathBuf; #[test] @@ -349,3 +353,29 @@ fn test_llil_intrinsic() { _ => panic!("Expected Intrinsic"), } } + +#[test] +fn test_llil_unbacked_function_creation() { + let _session = Session::new().expect("Failed to initialize session"); + let arch = CoreArchitecture::by_name("x86_64").unwrap(); + // Create an LLIL function backed by no Function. + let llil = LowLevelILMutableFunction::new(arch, None); + let (instr_len, _) = arch.instruction_llil(&[0x8b, 0xd9], 0x0, &llil).unwrap(); + assert_eq!(instr_len, 2); + let llil = llil.finalized(); + + // Validate to make sure we can read the llil instruction for a non-backed LLIL function. + let inst = llil + .instruction_from_index(LowLevelInstructionIndex(0)) + .unwrap(); + let LowLevelILInstructionKind::SetReg(inst_operation) = inst.kind() else { + panic!("Expected SetReg"); + }; + let LowLevelILExpressionKind::Reg(src_operation) = inst_operation.source_expr().kind() else { + panic!("Expected Reg"); + }; + let src_reg = src_operation.source_reg(); + assert_eq!(src_reg.name(), "ecx"); + let dest_reg = inst_operation.dest_reg(); + assert_eq!(dest_reg.name(), "ebx"); +}