Skip to content

Commit c604548

Browse files
committed
Add Assert and ForceVersion operations to Rust API
1 parent 5ab7c8a commit c604548

File tree

2 files changed

+185
-4
lines changed

2 files changed

+185
-4
lines changed

rust/src/low_level_il/instruction.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ where
240240
Bp(Operation<'func, M, F, operation::NoArgs>),
241241
Trap(Operation<'func, M, F, operation::Trap>),
242242
Undef(Operation<'func, M, F, operation::NoArgs>),
243+
Assert(Operation<'func, M, F, operation::Assert>),
244+
AssertSsa(Operation<'func, M, F, operation::AssertSsa>),
245+
ForceVersion(Operation<'func, M, F, operation::ForceVersion>),
246+
ForceVersionSsa(Operation<'func, M, F, operation::ForceVersionSsa>),
243247

244248
/// The instruction is an expression.
245249
Value(LowLevelILExpression<'func, M, F, ValueExpr>),
@@ -332,6 +336,18 @@ where
332336
LLIL_UNDEF => {
333337
LowLevelILInstructionKind::Undef(Operation::new(function, op, expr_index))
334338
}
339+
LLIL_ASSERT => {
340+
LowLevelILInstructionKind::Assert(Operation::new(function, op, expr_index))
341+
}
342+
LLIL_ASSERT_SSA => {
343+
LowLevelILInstructionKind::AssertSsa(Operation::new(function, op, expr_index))
344+
}
345+
LLIL_FORCE_VER => {
346+
LowLevelILInstructionKind::ForceVersion(Operation::new(function, op, expr_index))
347+
}
348+
LLIL_FORCE_VER_SSA => {
349+
LowLevelILInstructionKind::ForceVersionSsa(Operation::new(function, op, expr_index))
350+
}
335351
_ => LowLevelILInstructionKind::Value(LowLevelILExpression::new(function, expr_index)),
336352
}
337353
}
@@ -384,7 +400,8 @@ where
384400
}
385401
Value(e) => visit!(e),
386402
// Do not have any sub expressions.
387-
Nop(_) | NoRet(_) | Goto(_) | Syscall(_) | Bp(_) | Trap(_) | Undef(_) => {}
403+
Nop(_) | NoRet(_) | Goto(_) | Syscall(_) | Bp(_) | Trap(_) | Undef(_) | Assert(_)
404+
| AssertSsa(_) | ForceVersion(_) | ForceVersionSsa(_) => {}
388405
}
389406

390407
VisitorAction::Sibling

rust/src/low_level_il/operation.rs

Lines changed: 167 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
// limitations under the License.
1414

1515
use binaryninjacore_sys::{
16-
BNGetLowLevelILByIndex, BNLowLevelILFreeOperandList, BNLowLevelILGetOperandList,
17-
BNLowLevelILInstruction,
16+
BNGetCachedLowLevelILPossibleValueSet, BNGetLowLevelILByIndex, BNLowLevelILFreeOperandList,
17+
BNLowLevelILGetOperandList, BNLowLevelILInstruction,
1818
};
1919

2020
use super::*;
2121
use crate::architecture::{
2222
CoreFlag, CoreFlagGroup, CoreFlagWrite, CoreIntrinsic, CoreRegister, CoreRegisterStack,
2323
FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId,
2424
};
25+
use crate::variable::PossibleValueSet;
2526
use std::collections::BTreeMap;
2627
use std::fmt::{Debug, Formatter};
2728
use std::marker::PhantomData;
@@ -62,7 +63,7 @@ where
6263
self.op.address
6364
}
6465

65-
pub fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> {
66+
fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> {
6667
let mut count = 0;
6768
let raw_list_ptr = unsafe {
6869
BNLowLevelILGetOperandList(
@@ -77,6 +78,16 @@ where
7778
unsafe { BNLowLevelILFreeOperandList(raw_list_ptr) };
7879
list
7980
}
81+
82+
fn get_constraint(&self, operand_idx: usize) -> PossibleValueSet {
83+
let raw_pvs = unsafe {
84+
BNGetCachedLowLevelILPossibleValueSet(
85+
self.function.handle,
86+
self.op.operands[operand_idx] as usize,
87+
)
88+
};
89+
PossibleValueSet::from_owned_raw(raw_pvs)
90+
}
8091
}
8192

8293
impl<M, O> Operation<'_, M, NonSSA<LiftedNonSSA>, O>
@@ -1870,6 +1881,155 @@ where
18701881
}
18711882
}
18721883

1884+
// LLIL_ASSERT
1885+
pub struct Assert;
1886+
1887+
impl<M, F> Operation<'_, M, F, Assert>
1888+
where
1889+
M: FunctionMutability,
1890+
F: FunctionForm,
1891+
{
1892+
pub fn size(&self) -> usize {
1893+
self.op.size
1894+
}
1895+
1896+
pub fn source_reg(&self) -> LowLevelILRegisterKind<CoreRegister> {
1897+
let raw_id = RegisterId(self.op.operands[0] as u32);
1898+
LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID")
1899+
}
1900+
1901+
pub fn constraint(&self) -> PossibleValueSet {
1902+
self.get_constraint(1)
1903+
}
1904+
}
1905+
1906+
impl<M, F> Debug for Operation<'_, M, F, Assert>
1907+
where
1908+
M: FunctionMutability,
1909+
F: FunctionForm,
1910+
{
1911+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1912+
f.debug_struct("Assert")
1913+
.field("size", &self.size())
1914+
.field("source_reg", &self.source_reg())
1915+
.field("constraint", &self.constraint())
1916+
.finish()
1917+
}
1918+
}
1919+
1920+
// LLIL_ASSERT_SSA
1921+
pub struct AssertSsa;
1922+
1923+
impl<M, F> Operation<'_, M, F, AssertSsa>
1924+
where
1925+
M: FunctionMutability,
1926+
F: FunctionForm,
1927+
{
1928+
pub fn size(&self) -> usize {
1929+
self.op.size
1930+
}
1931+
1932+
pub fn source_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> {
1933+
let raw_id = RegisterId(self.op.operands[0] as u32);
1934+
let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id)
1935+
.expect("Bad register ID");
1936+
let version = self.op.operands[1] as u32;
1937+
LowLevelILSSARegisterKind::new_full(reg_kind, version)
1938+
}
1939+
1940+
pub fn constraint(&self) -> PossibleValueSet {
1941+
self.get_constraint(2)
1942+
}
1943+
}
1944+
1945+
impl<M, F> Debug for Operation<'_, M, F, AssertSsa>
1946+
where
1947+
M: FunctionMutability,
1948+
F: FunctionForm,
1949+
{
1950+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1951+
f.debug_struct("AssertSsa")
1952+
.field("size", &self.size())
1953+
.field("source_reg", &self.source_reg())
1954+
.field("constraint", &self.constraint())
1955+
.finish()
1956+
}
1957+
}
1958+
1959+
// LLIL_FORCE_VER
1960+
pub struct ForceVersion;
1961+
1962+
impl<M, F> Operation<'_, M, F, ForceVersion>
1963+
where
1964+
M: FunctionMutability,
1965+
F: FunctionForm,
1966+
{
1967+
pub fn size(&self) -> usize {
1968+
self.op.size
1969+
}
1970+
1971+
pub fn dest_reg(&self) -> LowLevelILRegisterKind<CoreRegister> {
1972+
let raw_id = RegisterId(self.op.operands[0] as u32);
1973+
LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID")
1974+
}
1975+
}
1976+
1977+
impl<M, F> Debug for Operation<'_, M, F, ForceVersion>
1978+
where
1979+
M: FunctionMutability,
1980+
F: FunctionForm,
1981+
{
1982+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1983+
f.debug_struct("ForceVersion")
1984+
.field("size", &self.size())
1985+
.field("dest_reg", &self.dest_reg())
1986+
.finish()
1987+
}
1988+
}
1989+
1990+
// LLIL_FORCE_VER_SSA
1991+
pub struct ForceVersionSsa;
1992+
1993+
impl<M, F> Operation<'_, M, F, ForceVersionSsa>
1994+
where
1995+
M: FunctionMutability,
1996+
F: FunctionForm,
1997+
{
1998+
pub fn size(&self) -> usize {
1999+
self.op.size
2000+
}
2001+
2002+
pub fn dest_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> {
2003+
let raw_id = RegisterId(self.op.operands[0] as u32);
2004+
let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id)
2005+
.expect("Bad register ID");
2006+
let version = self.op.operands[1] as u32;
2007+
LowLevelILSSARegisterKind::new_full(reg_kind, version)
2008+
}
2009+
2010+
pub fn source_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> {
2011+
let raw_id = RegisterId(self.op.operands[2] as u32);
2012+
let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id)
2013+
.expect("Bad register ID");
2014+
let version = self.op.operands[3] as u32;
2015+
LowLevelILSSARegisterKind::new_full(reg_kind, version)
2016+
}
2017+
}
2018+
2019+
impl<M, F> Debug for Operation<'_, M, F, ForceVersionSsa>
2020+
where
2021+
M: FunctionMutability,
2022+
F: FunctionForm,
2023+
{
2024+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2025+
f.debug_struct("ForceVersionSsa")
2026+
.field("size", &self.size())
2027+
.field("dest_reg", &self.dest_reg())
2028+
.field("source_reg", &self.source_reg())
2029+
.finish()
2030+
}
2031+
}
2032+
18732033
// TODO TEST_BIT
18742034

18752035
pub trait OperationArguments: 'static {}
@@ -1923,3 +2083,7 @@ impl OperationArguments for DoublePrecDivOp {}
19232083
impl OperationArguments for UnaryOp {}
19242084
impl OperationArguments for Condition {}
19252085
impl OperationArguments for UnimplMem {}
2086+
impl OperationArguments for Assert {}
2087+
impl OperationArguments for AssertSsa {}
2088+
impl OperationArguments for ForceVersion {}
2089+
impl OperationArguments for ForceVersionSsa {}

0 commit comments

Comments
 (0)