Skip to content

Commit c11e627

Browse files
committed
Rust bindings for performing function lifting
1 parent 328995d commit c11e627

3 files changed

Lines changed: 101 additions & 9 deletions

File tree

rust/src/architecture.rs

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ use crate::{
2626
calling_convention::CoreCallingConvention,
2727
data_buffer::DataBuffer,
2828
disassembly::InstructionTextToken,
29-
function::Function,
29+
function::{Function, Location, NativeBlock},
3030
platform::Platform,
3131
rc::*,
3232
relocation::CoreRelocationHandler,
3333
string::{IntoCStr, *},
3434
types::{NameAndType, Type},
3535
Endianness,
3636
};
37+
use std::collections::{HashMap, HashSet};
3738
use std::ops::Deref;
3839
use std::{
3940
borrow::Borrow,
@@ -47,7 +48,9 @@ use std::ptr::NonNull;
4748
use crate::function_recognizer::FunctionRecognizer;
4849
use crate::relocation::{CustomRelocationHandlerHandle, RelocationHandler};
4950

51+
use crate::basic_block::BasicBlock;
5052
use crate::confidence::Conf;
53+
use crate::logger::Logger;
5154
use crate::low_level_il::expression::ValueExpr;
5255
use crate::low_level_il::lifting::{
5356
get_default_flag_cond_llil, get_default_flag_write_llil, LowLevelILFlagWriteOp,
@@ -591,13 +594,83 @@ pub trait ArchitectureWithFunctionContext: Architecture {
591594

592595
pub struct FunctionLifterContext {
593596
pub(crate) handle: *mut BNFunctionLifterContext,
597+
pub function: *mut BNLowLevelILFunction,
598+
pub platform: Ref<Platform>,
599+
pub logger: Ref<Logger>,
600+
pub blocks: Vec<Ref<BasicBlock<NativeBlock>>>,
601+
pub no_return_calls: HashSet<Location>,
602+
pub contextual_returns: HashMap<Location, bool>,
603+
//pub inline_remapping: HashMap<ArchAndAddr, ArchAndAddr>>,
604+
//pub user_indirect_branches: HashMap<ArchAndAddr, HashSet<ArchAndAddr>>>,
605+
//pub auto_indirect_branches: HashMap<ArchAndAddr, HashSet<ArchAndAddr>>>,
606+
//pub inlined_calls: HashSet<u64>,
594607
}
595608

596609
impl FunctionLifterContext {
597-
pub unsafe fn from_raw(handle: *mut BNFunctionLifterContext) -> Self {
610+
pub unsafe fn from_raw(
611+
function: *mut BNLowLevelILFunction,
612+
handle: *mut BNFunctionLifterContext,
613+
) -> Self {
598614
debug_assert!(!handle.is_null());
615+
let flc_ref = &*handle;
616+
let platform = unsafe { Platform::ref_from_raw(BNNewPlatformReference(flc_ref.platform)) };
617+
let logger = unsafe { Logger::ref_from_raw(BNNewLoggerReference(flc_ref.logger)) };
618+
619+
let mut blocks = Vec::new();
620+
for i in 0..flc_ref.basicBlockCount {
621+
let block = unsafe {
622+
Some(BasicBlock::ref_from_raw(
623+
*flc_ref.basicBlocks.add(i),
624+
NativeBlock::new(),
625+
))
626+
};
627+
628+
blocks.push(block.unwrap());
629+
}
630+
631+
let raw_no_return_calls: &[BNArchitectureAndAddress] =
632+
std::slice::from_raw_parts(flc_ref.noReturnCalls, flc_ref.noReturnCallsCount);
633+
let no_return_calls: HashSet<Location> =
634+
raw_no_return_calls.iter().map(Location::from).collect();
599635

600-
FunctionLifterContext { handle }
636+
let raw_contextual_return_locs: &[BNArchitectureAndAddress] = unsafe {
637+
std::slice::from_raw_parts(
638+
flc_ref.contextualFunctionReturnLocations,
639+
flc_ref.contextualFunctionReturnCount,
640+
)
641+
};
642+
let raw_contextual_return_vals: &[bool] = unsafe {
643+
std::slice::from_raw_parts(
644+
flc_ref.contextualFunctionReturnValues,
645+
flc_ref.contextualFunctionReturnCount,
646+
)
647+
};
648+
let contextual_returns: HashMap<Location, bool> = raw_contextual_return_locs
649+
.iter()
650+
.map(Location::from)
651+
.zip(raw_contextual_return_vals.iter().copied())
652+
.collect();
653+
654+
FunctionLifterContext {
655+
handle,
656+
function,
657+
platform,
658+
logger,
659+
blocks,
660+
no_return_calls,
661+
contextual_returns,
662+
}
663+
}
664+
665+
pub fn prepare_block_translation(
666+
&self,
667+
func: &LowLevelILMutableFunction,
668+
arch: &CoreArchitecture,
669+
address: u64,
670+
) {
671+
unsafe {
672+
BNPrepareBlockTranslation(func.handle, arch.handle, address);
673+
}
601674
}
602675

603676
pub fn get_function_arch_context<A: ArchitectureWithFunctionContext>(
@@ -1622,12 +1695,15 @@ where
16221695
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
16231696
{
16241697
let custom_arch = unsafe { &*(ctxt as *mut A) };
1625-
let function = unsafe {
1626-
LowLevelILMutableFunction::from_raw_with_arch(function, Some(*custom_arch.as_ref()))
1698+
let llil = unsafe {
1699+
LowLevelILMutableFunction::from_raw_with_arch(
1700+
BNNewLowLevelILFunctionReference(function),
1701+
Some(*custom_arch.as_ref()),
1702+
)
16271703
};
1628-
let mut context: FunctionLifterContext =
1629-
unsafe { FunctionLifterContext::from_raw(context) };
1630-
custom_arch.lift_function(function, &mut context)
1704+
1705+
let mut ctx = unsafe { FunctionLifterContext::from_raw(function, context) };
1706+
custom_arch.lift_function(llil, &mut ctx)
16311707
}
16321708

16331709
extern "C" fn cb_reg_name<A>(ctxt: *mut c_void, reg: u32) -> *mut c_char

rust/src/logger.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ impl Logger {
5757
Self::new_with_session(name, LOGGER_DEFAULT_SESSION_ID)
5858
}
5959

60+
pub fn ref_from_raw(handle: *mut BNLogger) -> Ref<Logger> {
61+
unsafe {
62+
Ref::new(Logger {
63+
handle: NonNull::new(handle).unwrap(),
64+
})
65+
}
66+
}
67+
6068
/// Create a logger scoped with the specific [`SessionId`], hiding the logs when the session
6169
/// is not active in the UI.
6270
///

rust/src/low_level_il/lifting.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ use crate::architecture::{CoreRegister, Register as ArchReg};
2323
use crate::architecture::{
2424
Flag, FlagClass, FlagCondition, FlagGroup, FlagRole, FlagWrite, Intrinsic,
2525
};
26-
use crate::function::Location;
26+
use crate::basic_block::BasicBlock;
27+
use crate::function::{Location, NativeBlock};
2728

2829
pub trait LiftableLowLevelIL<'func> {
2930
type Result: ExpressionResultType;
@@ -1512,6 +1513,13 @@ impl LowLevelILMutableFunction {
15121513
}
15131514
}
15141515

1516+
pub fn set_current_source_block(&self, source: &BasicBlock<NativeBlock>) {
1517+
use binaryninjacore_sys::BNLowLevelILSetCurrentSourceBlock;
1518+
unsafe {
1519+
BNLowLevelILSetCurrentSourceBlock(self.handle, source.handle);
1520+
}
1521+
}
1522+
15151523
pub fn label_for_address<L: Into<Location>>(&self, loc: L) -> Option<LowLevelILLabel> {
15161524
use binaryninjacore_sys::BNGetLowLevelILLabelForAddress;
15171525

0 commit comments

Comments
 (0)