Skip to content

Commit 049f195

Browse files
committed
Rust bindings for performing function lifting
1 parent 1ef885f commit 049f195

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,
@@ -45,7 +46,9 @@ use std::{
4546
use crate::function_recognizer::FunctionRecognizer;
4647
use crate::relocation::{CustomRelocationHandlerHandle, RelocationHandler};
4748

49+
use crate::basic_block::BasicBlock;
4850
use crate::confidence::Conf;
51+
use crate::logger::Logger;
4952
use crate::low_level_il::expression::ValueExpr;
5053
use crate::low_level_il::lifting::{
5154
get_default_flag_cond_llil, get_default_flag_write_llil, LowLevelILFlagWriteOp,
@@ -552,13 +555,83 @@ pub trait Architecture: 'static + Sized + AsRef<CoreArchitecture> {
552555

553556
pub struct FunctionLifterContext {
554557
pub(crate) handle: *mut BNFunctionLifterContext,
558+
pub function: *mut BNLowLevelILFunction,
559+
pub platform: Ref<Platform>,
560+
pub logger: Ref<Logger>,
561+
pub blocks: Vec<Ref<BasicBlock<NativeBlock>>>,
562+
pub no_return_calls: HashSet<Location>,
563+
pub contextual_returns: HashMap<Location, bool>,
564+
//pub inline_remapping: HashMap<ArchAndAddr, ArchAndAddr>>,
565+
//pub user_indirect_branches: HashMap<ArchAndAddr, HashSet<ArchAndAddr>>>,
566+
//pub auto_indirect_branches: HashMap<ArchAndAddr, HashSet<ArchAndAddr>>>,
567+
//pub inlined_calls: HashSet<u64>,
555568
}
556569

557570
impl FunctionLifterContext {
558-
pub unsafe fn from_raw(handle: *mut BNFunctionLifterContext) -> Self {
571+
pub unsafe fn from_raw(
572+
function: *mut BNLowLevelILFunction,
573+
handle: *mut BNFunctionLifterContext,
574+
) -> Self {
559575
debug_assert!(!handle.is_null());
576+
let flc_ref = &*handle;
577+
let platform = unsafe { Platform::ref_from_raw(BNNewPlatformReference(flc_ref.platform)) };
578+
let logger = unsafe { Logger::ref_from_raw(BNNewLoggerReference(flc_ref.logger)) };
579+
580+
let mut blocks = Vec::new();
581+
for i in 0..flc_ref.basicBlockCount {
582+
let block = unsafe {
583+
Some(BasicBlock::ref_from_raw(
584+
*flc_ref.basicBlocks.add(i),
585+
NativeBlock::new(),
586+
))
587+
};
588+
589+
blocks.push(block.unwrap());
590+
}
591+
592+
let raw_no_return_calls: &[BNArchitectureAndAddress] =
593+
std::slice::from_raw_parts(flc_ref.noReturnCalls, flc_ref.noReturnCallsCount);
594+
let no_return_calls: HashSet<Location> =
595+
raw_no_return_calls.iter().map(Location::from).collect();
560596

561-
FunctionLifterContext { handle }
597+
let raw_contextual_return_locs: &[BNArchitectureAndAddress] = unsafe {
598+
std::slice::from_raw_parts(
599+
flc_ref.contextualFunctionReturnLocations,
600+
flc_ref.contextualFunctionReturnCount,
601+
)
602+
};
603+
let raw_contextual_return_vals: &[bool] = unsafe {
604+
std::slice::from_raw_parts(
605+
flc_ref.contextualFunctionReturnValues,
606+
flc_ref.contextualFunctionReturnCount,
607+
)
608+
};
609+
let contextual_returns: HashMap<Location, bool> = raw_contextual_return_locs
610+
.iter()
611+
.map(Location::from)
612+
.zip(raw_contextual_return_vals.iter().copied())
613+
.collect();
614+
615+
FunctionLifterContext {
616+
handle,
617+
function,
618+
platform,
619+
logger,
620+
blocks,
621+
no_return_calls,
622+
contextual_returns,
623+
}
624+
}
625+
626+
pub fn prepare_block_translation(
627+
&self,
628+
func: &LowLevelILMutableFunction,
629+
arch: &CoreArchitecture,
630+
address: u64,
631+
) {
632+
unsafe {
633+
BNPrepareBlockTranslation(func.handle, arch.handle, address);
634+
}
562635
}
563636
}
564637

@@ -1477,12 +1550,15 @@ where
14771550
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
14781551
{
14791552
let custom_arch = unsafe { &*(ctxt as *mut A) };
1480-
let function = unsafe {
1481-
LowLevelILMutableFunction::from_raw_with_arch(function, Some(*custom_arch.as_ref()))
1553+
let llil = unsafe {
1554+
LowLevelILMutableFunction::from_raw_with_arch(
1555+
BNNewLowLevelILFunctionReference(function),
1556+
Some(*custom_arch.as_ref()),
1557+
)
14821558
};
1483-
let mut context: FunctionLifterContext =
1484-
unsafe { FunctionLifterContext::from_raw(context) };
1485-
custom_arch.lift_function(function, &mut context)
1559+
1560+
let mut ctx = unsafe { FunctionLifterContext::from_raw(function, context) };
1561+
custom_arch.lift_function(llil, &mut ctx)
14861562
}
14871563

14881564
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)