How to implement custom Architecture as a Rust plugin #3203
-
Hello, Source (ignore the crap in the use std::collections::HashMap;
use std::borrow::Cow;
use binaryninja::binaryninjacore_sys::{
BNEndianness,
BNLowLevelILFlagCondition,
BNImplicitRegisterExtend,
BNArchitecture,
BNRegisterInfo,
BNFlagRole
};
use binaryninja::{
llil::{
Mutable,
NonSSA,
LiftedNonSSA,
Expression,
ValueExpr
},
rc::{
Array
},
disassembly::{
InstructionTextToken
},
logger,
architecture::{
register_architecture,
Architecture,
CoreArchitecture,
CustomArchitectureHandle,
InstructionInfo,
RegisterInfo,
Register,
Flag,
FlagClass,
FlagWrite,
FlagGroup
}
};
use log::{
info,
LevelFilter
};
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
struct TricoreArchRegister(*mut BNArchitecture, u32);
impl Register for TricoreArchRegister {
type InfoType = TricoreArchRegisterInfo;
fn name(&self) -> Cow<'_, str> { todo!() }
fn info(&self) -> <Self as binaryninja::architecture::Register>::InfoType { todo!() }
fn id(&self) -> u32 { todo!() }
}
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
struct TricoreArchFlag(*mut BNArchitecture, u32);
impl Flag for TricoreArchFlag {
type FlagClass = TricoreArchFlagClass;
fn name(&self) -> Cow<'_, str> { todo!() }
fn role(&self, _: Option<<Self as binaryninja::architecture::Flag>::FlagClass>) -> BNFlagRole { todo!() }
fn id(&self) -> u32 { todo!() }
}
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
struct TricoreArchFlagClass(*mut BNArchitecture, u32);
impl FlagClass for TricoreArchFlagClass {
fn name(&self) -> Cow<'_, str> { todo!() }
fn id(&self) -> u32 { todo!() }
}
struct TricoreArchRegisterInfo(*mut BNArchitecture, u32, BNRegisterInfo);
impl RegisterInfo for TricoreArchRegisterInfo {
type RegType = TricoreArchRegister;
fn parent(&self) -> Option<<Self as RegisterInfo>::RegType> { todo!() }
fn size(&self) -> usize { todo!() }
fn offset(&self) -> usize { todo!() }
fn implicit_extend(&self) -> BNImplicitRegisterExtend { todo!() }
}
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
struct TricoreArchFlagWrite(*mut BNArchitecture, u32);
impl FlagWrite for TricoreArchFlagWrite {
type FlagType = TricoreArchFlag;
type FlagClass = TricoreArchFlagClass;
fn name(&self) -> Cow<'_, str> { todo!() }
fn class(&self) -> Option<<Self as FlagWrite>::FlagClass> { todo!() }
fn id(&self) -> u32 { todo!() }
fn flags_written(&self) -> Vec<<Self as FlagWrite>::FlagType> { todo!() }
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct TricoreArchFlagGroup(*mut BNArchitecture, u32);
impl FlagGroup for TricoreArchFlagGroup {
type FlagType = TricoreArchFlag;
type FlagClass = TricoreArchFlagClass;
fn name(&self) -> Cow<'_, str> { todo!() }
fn id(&self) -> u32 { todo!() }
fn flags_required(&self) -> Vec<<Self as binaryninja::architecture::FlagGroup>::FlagType> { todo!() }
fn flag_conditions(&self) -> HashMap<<Self as binaryninja::architecture::FlagGroup>::FlagClass, BNLowLevelILFlagCondition> { todo!() }
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
struct TricoreArch(pub(crate) *mut BNArchitecture);
impl Architecture for TricoreArch {
type Handle = Self;
type RegisterInfo = TricoreArchRegisterInfo;
type Register = TricoreArchRegister;
type Flag = TricoreArchFlag;
type FlagWrite = TricoreArchFlagWrite;
type FlagClass = TricoreArchFlagClass;
type FlagGroup = TricoreArchFlagGroup;
fn endianness(&self) -> BNEndianness { todo!() }
fn address_size(&self) -> usize { todo!() }
fn default_integer_size(&self) -> usize { todo!() }
fn instruction_alignment(&self) -> usize { todo!() }
fn max_instr_len(&self) -> usize { todo!() }
fn opcode_display_len(&self) -> usize { todo!() }
fn associated_arch_by_addr(&self, _: &mut u64) -> CoreArchitecture { todo!() }
fn registers_all(&self) -> Vec<<Self as Architecture>::Register> { todo!() }
fn registers_full_width(&self) -> Vec<<Self as Architecture>::Register> { todo!() }
fn flag_group_llil<'a>(&self, _: <Self as Architecture>::FlagGroup, _: &'a mut binaryninja::llil::Function<Self, Mutable, NonSSA<LiftedNonSSA>>) -> Option<Expression<'a, Self, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>> { todo!() }
fn flags_required_for_flag_condition(&self, _: BNLowLevelILFlagCondition, _: Option<<Self as Architecture>::FlagClass>) -> Vec<<Self as Architecture>::Flag> { todo!() }
fn registers_global(&self) -> Vec<<Self as Architecture>::Register> { todo!() }
fn registers_system(&self) -> Vec<<Self as Architecture>::Register> { todo!() }
fn flags(&self) -> Vec<<Self as Architecture>::Flag> { todo!() }
fn flag_write_types(&self) -> Vec<<Self as Architecture>::FlagWrite> { todo!() }
fn instruction_llil(&self, _: &[u8], _: u64, _: &mut binaryninja::llil::Function<Self, Mutable, NonSSA<LiftedNonSSA>>) -> Option<(usize, bool)> { todo!() }
fn instruction_text(&self, _: &[u8], _: u64) -> Option<(usize, Array<InstructionTextToken>)> { todo!() }
fn instruction_info(&self, _: &[u8], _: u64) -> Option<InstructionInfo> { todo!() }
fn flag_classes(&self) -> Vec<<Self as Architecture>::FlagClass> { todo!() }
fn flag_groups(&self) -> Vec<<Self as Architecture>::FlagGroup> { todo!() }
fn stack_pointer_reg(&self) -> Option<<Self as Architecture>::Register> { todo!() }
fn link_reg(&self) -> Option<<Self as Architecture>::Register> { todo!() }
fn register_from_id(&self, _: u32) -> Option<<Self as Architecture>::Register> { todo!() }
fn flag_from_id(&self, _: u32) -> Option<<Self as Architecture>::Flag> { todo!() }
fn flag_write_from_id(&self, _: u32) -> Option<<Self as Architecture>::FlagWrite> { todo!() }
fn flag_class_from_id(&self, _: u32) -> Option<<Self as Architecture>::FlagClass> { todo!() }
fn flag_group_from_id(&self, _: u32) -> Option<<Self as Architecture>::FlagGroup> { todo!() }
fn handle(&self) -> <Self as Architecture>::Handle { todo!() }
}
impl AsRef<TricoreArch> for TricoreArch {
fn as_ref(&self) -> &TricoreArch {
self
}
}
#[no_mangle]
pub extern "C" fn UIPluginInit() -> bool {
logger::init(LevelFilter::Info).unwrap();
info!("Hello World");
let tricore = |_: CustomArchitectureHandle<TricoreArch>, _: CoreArchitecture| -> TricoreArch {
let tricore_struct = TricoreArch{};
tricore_struct
};
register_architecture("TriCore",tricore);
true
} Error message:
Thanks for any help :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi there! I was just testing things out and figured it out! Your custom Here's a template of the code required to create and register an Architecture: use binaryninja::{
architecture::{
register_architecture, Architecture, CoreArchitecture, CustomArchitectureHandle,
},
logger,
};
pub struct MyArch(CustomArchitectureHandle<Self>, CoreArchitecture);
impl MyArch {
pub fn new(handle: CustomArchitectureHandle<Self>, core_arch: CoreArchitecture) -> Self {
Self(handle, core_arch)
}
}
impl AsRef<CoreArchitecture> for MyArch {
fn as_ref(&self) -> &CoreArchitecture {
&self.1
}
}
impl Architecture for MyArch {
type Handle = CustomArchitectureHandle<Self>;
fn handle(&self) -> Self::Handle {
self.0
}
// fill in with the rest of your implementation
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CorePluginInit() -> bool {
logger::init(log::LevelFilter::Trace).expect("Failed to initialize logger");
register_architecture("myarch", MyArch::new);
log::info!("Registered custom architecture");
true
} |
Beta Was this translation helpful? Give feedback.
Hi there! I was just testing things out and figured it out!
Your custom
Architecture
needs to implementbinaryninja::architecture::Architecture
, of course, but you need to settype Handle = CustomArchitectureHandle<YourArch>
, and do a few other things as well.Here's a template of the code required to create and register an Architecture: