Architecture

Trait Architecture 

Source
pub trait Architecture:
    'static
    + Sized
    + AsRef<CoreArchitecture> {
    type Handle: Borrow<Self> + Clone;
    type RegisterInfo: RegisterInfo<RegType = Self::Register>;
    type Register: Register<InfoType = Self::RegisterInfo>;
    type RegisterStackInfo: RegisterStackInfo<RegType = Self::Register, RegInfoType = Self::RegisterInfo, RegStackType = Self::RegisterStack>;
    type RegisterStack: RegisterStack<InfoType = Self::RegisterStackInfo, RegType = Self::Register, RegInfoType = Self::RegisterInfo>;
    type Flag: Flag<FlagClass = Self::FlagClass>;
    type FlagWrite: FlagWrite<FlagType = Self::Flag, FlagClass = Self::FlagClass>;
    type FlagClass: FlagClass;
    type FlagGroup: FlagGroup<FlagType = Self::Flag, FlagClass = Self::FlagClass>;
    type Intrinsic: Intrinsic;

Show 48 methods // Required methods fn endianness(&self) -> Endianness; fn address_size(&self) -> usize; fn default_integer_size(&self) -> usize; fn instruction_alignment(&self) -> usize; fn max_instr_len(&self) -> usize; fn instruction_info( &self, data: &[u8], addr: u64, ) -> Option<InstructionInfo>; fn instruction_text( &self, data: &[u8], addr: u64, ) -> Option<(usize, Vec<InstructionTextToken>)>; fn instruction_llil( &self, data: &[u8], addr: u64, il: &LowLevelILMutableFunction, ) -> Option<(usize, bool)>; fn registers_all(&self) -> Vec<Self::Register>; fn register_from_id(&self, id: RegisterId) -> Option<Self::Register>; fn registers_full_width(&self) -> Vec<Self::Register>; fn stack_pointer_reg(&self) -> Option<Self::Register>; fn handle(&self) -> Self::Handle; // Provided methods fn opcode_display_len(&self) -> usize { ... } fn associated_arch_by_addr(&self, _addr: u64) -> CoreArchitecture { ... } fn analyze_basic_blocks( &self, function: &mut Function, context: &mut BasicBlockAnalysisContext, ) { ... } fn lift_function( &self, function: LowLevelILMutableFunction, context: &mut FunctionLifterContext, ) -> bool { ... } fn flag_write_llil<'a>( &self, flag: Self::Flag, flag_write_type: Self::FlagWrite, op: LowLevelILFlagWriteOp<Self::Register>, il: &'a LowLevelILMutableFunction, ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { ... } fn flags_required_for_flag_condition( &self, _condition: FlagCondition, _class: Option<Self::FlagClass>, ) -> Vec<Self::Flag> { ... } fn flag_cond_llil<'a>( &self, cond: FlagCondition, class: Option<Self::FlagClass>, il: &'a LowLevelILMutableFunction, ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { ... } fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, _il: &'a LowLevelILMutableFunction, ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { ... } fn registers_global(&self) -> Vec<Self::Register> { ... } fn registers_system(&self) -> Vec<Self::Register> { ... } fn link_reg(&self) -> Option<Self::Register> { ... } fn register_stacks(&self) -> Vec<Self::RegisterStack> { ... } fn register_stack_from_id( &self, _id: RegisterStackId, ) -> Option<Self::RegisterStack> { ... } fn flags(&self) -> Vec<Self::Flag> { ... } fn flag_from_id(&self, _id: FlagId) -> Option<Self::Flag> { ... } fn flag_write_types(&self) -> Vec<Self::FlagWrite> { ... } fn flag_write_from_id(&self, _id: FlagWriteId) -> Option<Self::FlagWrite> { ... } fn flag_classes(&self) -> Vec<Self::FlagClass> { ... } fn flag_class_from_id(&self, _id: FlagClassId) -> Option<Self::FlagClass> { ... } fn flag_groups(&self) -> Vec<Self::FlagGroup> { ... } fn flag_group_from_id(&self, _id: FlagGroupId) -> Option<Self::FlagGroup> { ... } fn intrinsics(&self) -> Vec<Self::Intrinsic> { ... } fn intrinsic_class(&self, _id: IntrinsicId) -> BNIntrinsicClass { ... } fn intrinsic_from_id(&self, _id: IntrinsicId) -> Option<Self::Intrinsic> { ... } fn can_assemble(&self) -> bool { ... } fn assemble(&self, _code: &str, _addr: u64) -> Result<Vec<u8>, String> { ... } fn is_never_branch_patch_available(&self, data: &[u8], addr: u64) -> bool { ... } fn is_always_branch_patch_available(&self, _data: &[u8], _addr: u64) -> bool { ... } fn is_invert_branch_patch_available(&self, _data: &[u8], _addr: u64) -> bool { ... } fn is_skip_and_return_zero_patch_available( &self, data: &[u8], addr: u64, ) -> bool { ... } fn is_skip_and_return_value_patch_available( &self, _data: &[u8], _addr: u64, ) -> bool { ... } fn convert_to_nop(&self, _data: &mut [u8], _addr: u64) -> bool { ... } fn always_branch(&self, _data: &mut [u8], _addr: u64) -> bool { ... } fn invert_branch(&self, _data: &mut [u8], _addr: u64) -> bool { ... } fn skip_and_return_value( &self, _data: &mut [u8], _addr: u64, _value: u64, ) -> bool { ... }
}
Expand description

The Architecture trait is the backbone of Binary Ninja’s analysis capabilities. It tells the core how to interpret the machine code into LLIL, a generic intermediate representation for program analysis.

To add support for a new Instruction Set Architecture (ISA), you must implement this trait and register it. The core analysis loop relies on your implementation for three critical stages:

  1. Disassembly (Architecture::instruction_text): Machine code into human-readable text (e.g., 55 -> push rbp).
  2. Control Flow Analysis (Architecture::instruction_info): Identifying where execution goes next (e.g., “This is a call instruction, it targets address 0x401000”).
  3. Lifting (Architecture::instruction_llil): Translating machine code into Low Level Intermediate Language (LLIL), which enables decompilation and automated analysis.

Required Associated Types§

Source

type Handle: Borrow<Self> + Clone

Source

type RegisterInfo: RegisterInfo<RegType = Self::Register>

The RegisterInfo associated with this architecture.

Source

type Register: Register<InfoType = Self::RegisterInfo>

The Register associated with this architecture.

Source

type RegisterStackInfo: RegisterStackInfo<RegType = Self::Register, RegInfoType = Self::RegisterInfo, RegStackType = Self::RegisterStack>

The RegisterStackInfo associated with this architecture.

You may only set this to UnusedRegisterStack if Self::RegisterStack is as well.

Source

type RegisterStack: RegisterStack<InfoType = Self::RegisterStackInfo, RegType = Self::Register, RegInfoType = Self::RegisterInfo>

The RegisterStack associated with this architecture.

If you do not override Architecture::register_stack_from_id and Architecture::register_stacks, you may set this to UnusedRegisterStack.

Source

type Flag: Flag<FlagClass = Self::FlagClass>

The Flag associated with this architecture.

If you do not override Architecture::flag_from_id and Architecture::flags, you may set this to UnusedFlag.

Source

type FlagWrite: FlagWrite<FlagType = Self::Flag, FlagClass = Self::FlagClass>

The FlagWrite associated with this architecture.

Can only be set to UnusedFlag if Self::Flag is as well. Otherwise, it is expected that this points to a custom FlagWrite with the following functions defined:

Source

type FlagClass: FlagClass

The FlagClass associated with this architecture.

Can only be set to UnusedFlag if Self::Flag is as well. Otherwise, it is expected that this points to a custom FlagClass with the following functions defined:

Source

type FlagGroup: FlagGroup<FlagType = Self::Flag, FlagClass = Self::FlagClass>

The FlagGroup associated with this architecture.

Can only be set to UnusedFlag if Self::Flag is as well. Otherwise, it is expected that this points to a custom FlagGroup with the following functions defined:

Source

type Intrinsic: Intrinsic

Required Methods§

Source

fn endianness(&self) -> Endianness

Source

fn address_size(&self) -> usize

Source

fn default_integer_size(&self) -> usize

Source

fn instruction_alignment(&self) -> usize

Source

fn max_instr_len(&self) -> usize

The maximum length of an instruction in bytes. This is used to determine the size of the buffer given to callbacks such as Architecture::instruction_info, Architecture::instruction_text and Architecture::instruction_llil.

NOTE: The maximum CANNOT be greater than 256.

Source

fn instruction_info(&self, data: &[u8], addr: u64) -> Option<InstructionInfo>

Returns the InstructionInfo at the given virtual address with data.

The InstructionInfo object should always fill the proper length and branches if not, the next instruction will likely be incorrect.

Source

fn instruction_text( &self, data: &[u8], addr: u64, ) -> Option<(usize, Vec<InstructionTextToken>)>

Disassembles a raw byte sequence into a human-readable list of text tokens.

This function is responsible for the visual representation of assembly instructions. It does not define semantics (use Architecture::instruction_llil for that); it simply tells the UI how to print the instruction.

§Returns

An Option containing a tuple:

  • usize: The size of the decoded instruction in bytes. Is used to advance to the next instruction.
  • Vec<InstructionTextToken>: A list of text tokens representing the instruction.

Returns None if the bytes do not form a valid instruction.

Source

fn instruction_llil( &self, data: &[u8], addr: u64, il: &LowLevelILMutableFunction, ) -> Option<(usize, bool)>

Appends arbitrary low-level il instructions to il.

If None is returned, no instructions were appended and the data is invalid. If Some is returned, the instructions consumed length is returned (necessary for variable length instruction decoding).

Source

fn registers_all(&self) -> Vec<Self::Register>

Source

fn register_from_id(&self, id: RegisterId) -> Option<Self::Register>

Source

fn registers_full_width(&self) -> Vec<Self::Register>

Source

fn stack_pointer_reg(&self) -> Option<Self::Register>

Source

fn handle(&self) -> Self::Handle

Provided Methods§

Source

fn opcode_display_len(&self) -> usize

How many bytes to display in the opcode space before displaying a ..., typically set to the Architecture::max_instr_len, however, can be overridden to display a truncated opcode.

Source

fn associated_arch_by_addr(&self, _addr: u64) -> CoreArchitecture

In binaries with multiple architectures, you may wish to associate a specific architecture with a given virtual address. This can be seen in armv7 where odd addresses are associated with the thumb architecture.

Source

fn analyze_basic_blocks( &self, function: &mut Function, context: &mut BasicBlockAnalysisContext, )

Performs basic block recovery and commits the results to the function analysis.

NOTE: Only implement this method if function-level analysis is required. Otherwise, do not implement to let default basic block analysis take place.

Source

fn lift_function( &self, function: LowLevelILMutableFunction, context: &mut FunctionLifterContext, ) -> bool

Source

fn flag_write_llil<'a>( &self, flag: Self::Flag, flag_write_type: Self::FlagWrite, op: LowLevelILFlagWriteOp<Self::Register>, il: &'a LowLevelILMutableFunction, ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>>

Fallback flag value calculation path. This method is invoked when the core is unable to recover the flag using semantics and resorts to emitting instructions that explicitly set each observed flag to the value of an expression returned by this function.

This function MUST NOT append instructions that have side effects.

This function MUST NOT observe the values of other flags.

This function MUST return None or an expression representing a boolean value.

Source

fn flags_required_for_flag_condition( &self, _condition: FlagCondition, _class: Option<Self::FlagClass>, ) -> Vec<Self::Flag>

Determines what flags need to be examined to attempt automatic recovery of the flag uses semantics.

If automatic recovery is not possible, the Architecture::flag_cond_llil method will be invoked to give this Architecture implementation arbitrary control over the expression to be evaluated.

Source

fn flag_cond_llil<'a>( &self, cond: FlagCondition, class: Option<Self::FlagClass>, il: &'a LowLevelILMutableFunction, ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>>

This function MUST NOT append instructions that have side effects.

This function MUST NOT observe the values of flags not returned by flags_required_for_flag_condition.

This function MUST return None or an expression representing a boolean value.

Source

fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, _il: &'a LowLevelILMutableFunction, ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>>

Performs fallback resolution when the core was unable to recover the semantics of a LLIL_FLAG_GROUP expression. This occurs when multiple instructions may have set the flags at the flag group query, or when the FlagGroup::flag_conditions() map doesn’t have an entry for the FlagClass associated with the FlagWrite type of the expression that last set the flags required by the FlagGroup group.

In this fallback path, the Architecture must generate the boolean expression in terms of the values of that flags returned by group’s flags_required method.

This function must return an expression representing a boolean (as in, size of 0) value. It is not allowed to add any instructions that can cause side effects.

This function must not observe the values of any flag not returned by group’s flags_required method.

Source

fn registers_global(&self) -> Vec<Self::Register>

Source

fn registers_system(&self) -> Vec<Self::Register>

Source

fn register_stacks(&self) -> Vec<Self::RegisterStack>

List of concrete register stacks for this architecture.

You must override the following functions as well:

Source

fn register_stack_from_id( &self, _id: RegisterStackId, ) -> Option<Self::RegisterStack>

Get the Self::RegisterStack associated with the given RegisterStackId.

You must override the following functions as well:

Source

fn flags(&self) -> Vec<Self::Flag>

Source

fn flag_from_id(&self, _id: FlagId) -> Option<Self::Flag>

Source

fn flag_write_types(&self) -> Vec<Self::FlagWrite>

Source

fn flag_write_from_id(&self, _id: FlagWriteId) -> Option<Self::FlagWrite>

Source

fn flag_classes(&self) -> Vec<Self::FlagClass>

Source

fn flag_class_from_id(&self, _id: FlagClassId) -> Option<Self::FlagClass>

Source

fn flag_groups(&self) -> Vec<Self::FlagGroup>

Source

fn flag_group_from_id(&self, _id: FlagGroupId) -> Option<Self::FlagGroup>

Source

fn intrinsics(&self) -> Vec<Self::Intrinsic>

List of concrete intrinsics for this architecture.

You must override the following functions as well:

Source

fn intrinsic_class(&self, _id: IntrinsicId) -> BNIntrinsicClass

Source

fn intrinsic_from_id(&self, _id: IntrinsicId) -> Option<Self::Intrinsic>

Get the Self::Intrinsic associated with the given IntrinsicId.

You must override the following functions as well:

Source

fn can_assemble(&self) -> bool

Let the UI display this patch option.

If set to true, you must override Architecture::assemble.

Source

fn assemble(&self, _code: &str, _addr: u64) -> Result<Vec<u8>, String>

Assemble the code at the specified address and return the machine code in bytes.

If overridden, you must set Architecture::can_assemble to true.

Source

fn is_never_branch_patch_available(&self, data: &[u8], addr: u64) -> bool

Let the UI display this patch option.

If set to true, you must override Architecture::invert_branch.

Source

fn is_always_branch_patch_available(&self, _data: &[u8], _addr: u64) -> bool

Let the UI display this patch option.

If set to true, you must override Architecture::always_branch.

Source

fn is_invert_branch_patch_available(&self, _data: &[u8], _addr: u64) -> bool

Let the UI display this patch option.

If set to true, you must override Architecture::invert_branch.

Source

fn is_skip_and_return_zero_patch_available( &self, data: &[u8], addr: u64, ) -> bool

Let the UI display this patch option.

If set to true, you must override Architecture::skip_and_return_value.

Source

fn is_skip_and_return_value_patch_available( &self, _data: &[u8], _addr: u64, ) -> bool

Let the UI display this patch option.

If set to true, you must override Architecture::skip_and_return_value.

Source

fn convert_to_nop(&self, _data: &mut [u8], _addr: u64) -> bool

Source

fn always_branch(&self, _data: &mut [u8], _addr: u64) -> bool

Patch the instruction to always branch.

If overridden, you must also override Architecture::is_always_branch_patch_available.

Source

fn invert_branch(&self, _data: &mut [u8], _addr: u64) -> bool

Patch the instruction to invert the branch condition.

If overridden, you must also override Architecture::is_invert_branch_patch_available.

Source

fn skip_and_return_value( &self, _data: &mut [u8], _addr: u64, _value: u64, ) -> bool

Patch the instruction to skip and return value.

If overridden, you must also override Architecture::is_skip_and_return_value_patch_available.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§