summaryrefslogtreecommitdiff
path: root/rust/src/llil
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2021-01-21 18:35:20 +0000
committerKyleMiles <krm504@nyu.edu>2021-01-21 19:07:07 +0000
commit2fcacc55d5466a7d17bdc0b3ce988772aa6d0653 (patch)
tree9d0f2ba19117843575936f2b93e0b6a578a84dc8 /rust/src/llil
parenta0da07c5c2860a5bd69921d38e438bbc1d43912f (diff)
cargo fmt and all my changes
Diffstat (limited to 'rust/src/llil')
-rw-r--r--rust/src/llil/block.rs24
-rw-r--r--rust/src/llil/expression.rs391
-rw-r--r--rust/src/llil/function.rs32
-rw-r--r--rust/src/llil/instruction.rs45
-rw-r--r--rust/src/llil/lifting.rs638
-rw-r--r--rust/src/llil/mod.rs36
-rw-r--r--rust/src/llil/operation.rs153
7 files changed, 688 insertions, 631 deletions
diff --git a/rust/src/llil/block.rs b/rust/src/llil/block.rs
index 543ab670..63e93338 100644
--- a/rust/src/llil/block.rs
+++ b/rust/src/llil/block.rs
@@ -1,3 +1,17 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
use std::ops::Range;
use crate::architecture::Architecture;
@@ -31,8 +45,6 @@ where
}
}
-
-
pub struct Block<'func, A, M, F>
where
A: 'func + Architecture,
@@ -72,7 +84,7 @@ where
fn iter(&self, block: &BasicBlock<Self>) -> BlockIter<'func, A, M, F> {
BlockIter {
function: self.function,
- range: block.raw_start() .. block.raw_end(),
+ range: block.raw_start()..block.raw_end(),
}
}
}
@@ -84,8 +96,8 @@ where
F: FunctionForm,
{
fn clone(&self) -> Self {
- Block { function: self.function }
+ Block {
+ function: self.function,
+ }
}
}
-
-
diff --git a/rust/src/llil/expression.rs b/rust/src/llil/expression.rs
index 1e1edda4..4cf2cad5 100644
--- a/rust/src/llil/expression.rs
+++ b/rust/src/llil/expression.rs
@@ -1,12 +1,26 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
use binaryninjacore_sys::BNGetLowLevelILByIndex;
use binaryninjacore_sys::BNLowLevelILInstruction;
-use std::marker::PhantomData;
use std::fmt;
+use std::marker::PhantomData;
-use super::*;
use super::operation;
use super::operation::Operation;
+use super::*;
use crate::architecture::Architecture;
use crate::architecture::RegisterInfo;
@@ -61,8 +75,10 @@ where
}
}
-fn common_info<'func, A, M, F>(function: &'func Function<A, M, F>, op: BNLowLevelILInstruction)
- -> ExprInfo<'func, A, M, F>
+fn common_info<'func, A, M, F>(
+ function: &'func Function<A, M, F>,
+ op: BNLowLevelILInstruction,
+) -> ExprInfo<'func, A, M, F>
where
A: 'func + Architecture,
M: FunctionMutability,
@@ -79,7 +95,7 @@ where
LLIL_SUB => ExprInfo::Sub(Operation::new(function, op)),
LLIL_SBB => ExprInfo::Sbb(Operation::new(function, op)),
LLIL_AND => ExprInfo::And(Operation::new(function, op)),
- LLIL_OR => ExprInfo::Or (Operation::new(function, op)),
+ LLIL_OR => ExprInfo::Or(Operation::new(function, op)),
LLIL_XOR => ExprInfo::Xor(Operation::new(function, op)),
LLIL_LSL => ExprInfo::Lsl(Operation::new(function, op)),
LLIL_LSR => ExprInfo::Lsr(Operation::new(function, op)),
@@ -132,8 +148,10 @@ where
_ => {
#[cfg(debug_assertions)]
{
- error!("Got unexpected operation {:?} in value expr at 0x{:x}",
- op.operation, op.address);
+ error!(
+ "Got unexpected operation {:?} in value expr at 0x{:x}",
+ op.operation, op.address
+ );
}
ExprInfo::Undef(Operation::new(function, op))
@@ -151,8 +169,7 @@ macro_rules! visit {
}
}
-fn common_visit<'func, A, M, F, CB>(info: &ExprInfo<'func, A, M, F>, f: &mut CB)
- -> VisitorAction
+fn common_visit<'func, A, M, F, CB>(info: &ExprInfo<'func, A, M, F>, f: &mut CB) -> VisitorAction
where
A: 'func + Architecture,
M: FunctionMutability,
@@ -162,60 +179,33 @@ where
use self::ExprInfo::*;
match *info {
- CmpE(ref op) | CmpNe(ref op) |
- CmpSlt(ref op) | CmpUlt(ref op) |
- CmpSle(ref op) | CmpUle(ref op) |
- CmpSge(ref op) | CmpUge(ref op) |
- CmpSgt(ref op) | CmpUgt(ref op) => {
+ CmpE(ref op) | CmpNe(ref op) | CmpSlt(ref op) | CmpUlt(ref op) | CmpSle(ref op)
+ | CmpUle(ref op) | CmpSge(ref op) | CmpUge(ref op) | CmpSgt(ref op) | CmpUgt(ref op) => {
visit!(f, &op.left());
visit!(f, &op.right());
}
- Adc(ref op) |
- Sbb(ref op) |
- Rlc(ref op) |
- Rrc(ref op) => {
+ Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => {
visit!(f, &op.left());
visit!(f, &op.right());
visit!(f, &op.carry());
}
- Add(ref op) |
- Sub(ref op) |
- And(ref op) |
- Or (ref op) |
- Xor(ref op) |
- Lsl(ref op) |
- Lsr(ref op) |
- Asr(ref op) |
- Rol(ref op) |
- Ror(ref op) |
- Mul(ref op) |
- MulsDp(ref op) |
- MuluDp(ref op) |
- Divu(ref op) |
- Divs(ref op) |
- Modu(ref op) |
- Mods(ref op) => {
+ Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
+ | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op) | MulsDp(ref op)
+ | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op) | Mods(ref op) => {
visit!(f, &op.left());
visit!(f, &op.right());
}
- DivuDp(ref op) |
- DivsDp(ref op) |
- ModuDp(ref op) |
- ModsDp(ref op) => {
+ DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => {
visit!(f, &op.high());
visit!(f, &op.low());
visit!(f, &op.right());
}
- Neg(ref op) |
- Not(ref op) |
- Sx(ref op) |
- Zx(ref op) |
- LowPart(ref op) |
- BoolToInt(ref op) => {
+ Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op)
+ | BoolToInt(ref op) => {
visit!(f, &op.operand());
}
@@ -235,7 +225,10 @@ where
M: FunctionMutability,
V: NonSSAVariant,
{
- pub(crate) unsafe fn info_from_op(&self, op: BNLowLevelILInstruction) -> ExprInfo<'func, A, M, NonSSA<V>> {
+ pub(crate) unsafe fn info_from_op(
+ &self,
+ op: BNLowLevelILInstruction,
+ ) -> ExprInfo<'func, A, M, NonSSA<V>> {
use binaryninjacore_sys::BNLowLevelILOperation::*;
match op.operation {
@@ -266,7 +259,7 @@ where
let info = self.info();
match f(self, &info) {
- VisitorAction::Descend => {},
+ VisitorAction::Descend => {}
action => return action,
};
@@ -287,13 +280,15 @@ where
A: 'func + Architecture,
M: FunctionMutability,
{
- pub(crate) unsafe fn info_from_op(&self, op: BNLowLevelILInstruction) -> ExprInfo<'func, A, M, SSA> {
+ pub(crate) unsafe fn info_from_op(
+ &self,
+ op: BNLowLevelILInstruction,
+ ) -> ExprInfo<'func, A, M, SSA> {
use binaryninjacore_sys::BNLowLevelILOperation::*;
match op.operation {
LLIL_LOAD_SSA => ExprInfo::Load(Operation::new(self.function, op)),
- LLIL_REG_SSA |
- LLIL_REG_SSA_PARTIAL => ExprInfo::Reg(Operation::new(self.function, op)),
+ LLIL_REG_SSA | LLIL_REG_SSA_PARTIAL => ExprInfo::Reg(Operation::new(self.function, op)),
LLIL_FLAG_SSA => ExprInfo::Flag(Operation::new(self.function, op)),
LLIL_FLAG_BIT_SSA => ExprInfo::FlagBit(Operation::new(self.function, op)),
_ => common_info(self.function, op),
@@ -316,7 +311,7 @@ where
let info = self.info();
match f(self, &info) {
- VisitorAction::Descend => {},
+ VisitorAction::Descend => {}
action => return action,
};
@@ -341,8 +336,6 @@ where
// TODO possible values
}
-
-
pub enum ExprInfo<'func, A, M, F>
where
A: 'func + Architecture,
@@ -362,7 +355,7 @@ where
Sub(Operation<'func, A, M, F, operation::BinaryOp>),
Sbb(Operation<'func, A, M, F, operation::BinaryOpCarry>),
And(Operation<'func, A, M, F, operation::BinaryOp>),
- Or (Operation<'func, A, M, F, operation::BinaryOp>),
+ Or(Operation<'func, A, M, F, operation::BinaryOp>),
Xor(Operation<'func, A, M, F, operation::BinaryOp>),
Lsl(Operation<'func, A, M, F, operation::BinaryOp>),
Lsr(Operation<'func, A, M, F, operation::BinaryOp>),
@@ -409,11 +402,9 @@ where
CmpUgt(Operation<'func, A, M, F, operation::Condition>),
//TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO
-
BoolToInt(Operation<'func, A, M, F, operation::UnaryOp>),
// TODO ADD_OVERFLOW
-
Unimpl(Operation<'func, A, M, F, operation::NoArgs>),
UnimplMem(Operation<'func, A, M, F, operation::UnimplMem>),
@@ -427,25 +418,21 @@ where
F: FunctionForm,
{
/// Returns the size of the result of this expression
- ///
+ ///
/// If the expression is malformed or is `Unimpl` there
/// is no meaningful size associated with the result.
pub fn size(&self) -> Option<usize> {
use self::ExprInfo::*;
match *self {
- Undef(..) |
- Unimpl(..) => None,
+ Undef(..) | Unimpl(..) => None,
- FlagCond(..) | FlagGroup(..) |
- CmpE(..) | CmpNe(..) |
- CmpSlt(..) | CmpUlt(..) |
- CmpSle(..) | CmpUle(..) |
- CmpSge(..) | CmpUge(..) |
- CmpSgt(..) | CmpUgt(..) => Some(0),
+ FlagCond(..) | FlagGroup(..) | CmpE(..) | CmpNe(..) | CmpSlt(..) | CmpUlt(..)
+ | CmpSle(..) | CmpUle(..) | CmpSge(..) | CmpUge(..) | CmpSgt(..) | CmpUgt(..) => {
+ Some(0)
+ }
_ => Some(self.raw_struct().size),
-
//TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO
}
}
@@ -455,13 +442,13 @@ where
}
/// Determines if the expressions represent the same operation
- ///
+ ///
/// It does not examine the operands for equality.
pub fn is_same_op_as(&self, other: &Self) -> bool {
use self::ExprInfo::*;
match (self, other) {
- (&Reg(..), &Reg(..)) => true,
+ (&Reg(..), &Reg(..)) => true,
_ => self.raw_struct().operation == other.raw_struct().operation,
}
}
@@ -470,11 +457,9 @@ where
use self::ExprInfo::*;
match *self {
- CmpE (ref op) | CmpNe (ref op) |
- CmpSlt(ref op) | CmpUlt(ref op) |
- CmpSle(ref op) | CmpUle(ref op) |
- CmpSge(ref op) | CmpUge(ref op) |
- CmpSgt(ref op) | CmpUgt(ref op) => Some(op),
+ CmpE(ref op) | CmpNe(ref op) | CmpSlt(ref op) | CmpUlt(ref op) | CmpSle(ref op)
+ | CmpUle(ref op) | CmpSge(ref op) | CmpUge(ref op) | CmpSgt(ref op)
+ | CmpUgt(ref op) => Some(op),
_ => None,
}
}
@@ -483,47 +468,32 @@ where
use self::ExprInfo::*;
match *self {
- Add(ref op) |
- Sub(ref op) |
- And(ref op) |
- Or (ref op) |
- Xor(ref op) |
- Lsl(ref op) |
- Lsr(ref op) |
- Asr(ref op) |
- Rol(ref op) |
- Ror(ref op) |
- Mul(ref op) |
- MulsDp(ref op) |
- MuluDp(ref op) |
- Divu(ref op) |
- Divs(ref op) |
- Modu(ref op) |
- Mods(ref op) => Some(op),
+ Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
+ | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op)
+ | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op)
+ | Mods(ref op) => Some(op),
_ => None,
}
}
- pub fn as_binary_op_carry(&self) -> Option<&Operation<'func, A, M, F, operation::BinaryOpCarry>> {
+ pub fn as_binary_op_carry(
+ &self,
+ ) -> Option<&Operation<'func, A, M, F, operation::BinaryOpCarry>> {
use self::ExprInfo::*;
match *self {
- Adc(ref op) |
- Sbb(ref op) |
- Rlc(ref op) |
- Rrc(ref op) => Some(op),
+ Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => Some(op),
_ => None,
}
}
- pub fn as_double_prec_div_op(&self) -> Option<&Operation<'func, A, M, F, operation::DoublePrecDivOp>> {
+ pub fn as_double_prec_div_op(
+ &self,
+ ) -> Option<&Operation<'func, A, M, F, operation::DoublePrecDivOp>> {
use self::ExprInfo::*;
match *self {
- DivuDp(ref op) |
- DivsDp(ref op) |
- ModuDp(ref op) |
- ModsDp(ref op) => Some(op),
+ DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => Some(op),
_ => None,
}
}
@@ -532,12 +502,8 @@ where
use self::ExprInfo::*;
match *self {
- Neg(ref op) |
- Not(ref op) |
- Sx(ref op) |
- Zx(ref op) |
- LowPart(ref op) |
- BoolToInt(ref op) => Some(op),
+ Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op)
+ | BoolToInt(ref op) => Some(op),
_ => None,
}
}
@@ -553,11 +519,9 @@ where
FlagCond(ref op) => &op.op,
FlagGroup(ref op) => &op.op,
- CmpE (ref op) | CmpNe (ref op) |
- CmpSlt(ref op) | CmpUlt(ref op) |
- CmpSle(ref op) | CmpUle(ref op) |
- CmpSge(ref op) | CmpUge(ref op) |
- CmpSgt(ref op) | CmpUgt(ref op) => &op.op,
+ CmpE(ref op) | CmpNe(ref op) | CmpSlt(ref op) | CmpUlt(ref op) | CmpSle(ref op)
+ | CmpUle(ref op) | CmpSge(ref op) | CmpUge(ref op) | CmpSgt(ref op)
+ | CmpUgt(ref op) => &op.op,
Load(ref op) => &op.op,
@@ -569,46 +533,21 @@ where
FlagBit(ref op) => &op.op,
- Const(ref op) |
- ConstPtr(ref op) => &op.op,
+ Const(ref op) | ConstPtr(ref op) => &op.op,
- Adc(ref op) |
- Sbb(ref op) |
- Rlc(ref op) |
- Rrc(ref op) => &op.op,
+ Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => &op.op,
- Add(ref op) |
- Sub(ref op) |
- And(ref op) |
- Or (ref op) |
- Xor(ref op) |
- Lsl(ref op) |
- Lsr(ref op) |
- Asr(ref op) |
- Rol(ref op) |
- Ror(ref op) |
- Mul(ref op) |
- MulsDp(ref op) |
- MuluDp(ref op) |
- Divu(ref op) |
- Divs(ref op) |
- Modu(ref op) |
- Mods(ref op) => &op.op,
+ Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
+ | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op)
+ | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op)
+ | Mods(ref op) => &op.op,
- DivuDp(ref op) |
- DivsDp(ref op) |
- ModuDp(ref op) |
- ModsDp(ref op) => &op.op,
+ DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => &op.op,
- Neg(ref op) |
- Not(ref op) |
- Sx(ref op) |
- Zx(ref op) |
- LowPart(ref op) |
- BoolToInt(ref op) => &op.op,
+ Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op)
+ | BoolToInt(ref op) => &op.op,
UnimplMem(ref op) => &op.op,
-
//TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO
}
}
@@ -618,23 +557,20 @@ impl<'func, A> ExprInfo<'func, A, Mutable, NonSSA<LiftedNonSSA>>
where
A: 'func + Architecture,
{
-
pub fn flag_write(&self) -> Option<A::FlagWrite> {
use self::ExprInfo::*;
match *self {
- Undef(ref op) => None,
+ Undef(ref _op) => None,
- Unimpl(ref op) => None,
+ Unimpl(ref _op) => None,
- FlagCond(ref op) => None,
- FlagGroup(ref op) => None,
+ FlagCond(ref _op) => None,
+ FlagGroup(ref _op) => None,
- CmpE (ref op) | CmpNe (ref op) |
- CmpSlt(ref op) | CmpUlt(ref op) |
- CmpSle(ref op) | CmpUle(ref op) |
- CmpSge(ref op) | CmpUge(ref op) |
- CmpSgt(ref op) | CmpUgt(ref op) => None,
+ CmpE(ref _op) | CmpNe(ref _op) | CmpSlt(ref _op) | CmpUlt(ref _op)
+ | CmpSle(ref _op) | CmpUle(ref _op) | CmpSge(ref _op) | CmpUge(ref _op)
+ | CmpSgt(ref _op) | CmpUgt(ref _op) => None,
Load(ref op) => op.flag_write(),
@@ -646,46 +582,21 @@ where
FlagBit(ref op) => op.flag_write(),
- Const(ref op) |
- ConstPtr(ref op) => op.flag_write(),
+ Const(ref op) | ConstPtr(ref op) => op.flag_write(),
- Adc(ref op) |
- Sbb(ref op) |
- Rlc(ref op) |
- Rrc(ref op) => op.flag_write(),
+ Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => op.flag_write(),
- Add(ref op) |
- Sub(ref op) |
- And(ref op) |
- Or (ref op) |
- Xor(ref op) |
- Lsl(ref op) |
- Lsr(ref op) |
- Asr(ref op) |
- Rol(ref op) |
- Ror(ref op) |
- Mul(ref op) |
- MulsDp(ref op) |
- MuluDp(ref op) |
- Divu(ref op) |
- Divs(ref op) |
- Modu(ref op) |
- Mods(ref op) => op.flag_write(),
+ Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
+ | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op)
+ | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op)
+ | Mods(ref op) => op.flag_write(),
- DivuDp(ref op) |
- DivsDp(ref op) |
- ModuDp(ref op) |
- ModsDp(ref op) => op.flag_write(),
+ DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => op.flag_write(),
- Neg(ref op) |
- Not(ref op) |
- Sx(ref op) |
- Zx(ref op) |
- LowPart(ref op) |
- BoolToInt(ref op) => op.flag_write(),
+ Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op)
+ | BoolToInt(ref op) => op.flag_write(),
UnimplMem(ref op) => op.flag_write(),
-
//TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO
}
}
@@ -708,15 +619,20 @@ where
FlagCond(..) => f.write_str("some_flag_cond"),
FlagGroup(..) => f.write_str("some_flag_group"),
- CmpE(ref op) | CmpNe(ref op) |
- CmpSlt(ref op) | CmpUlt(ref op) |
- CmpSle(ref op) | CmpUle(ref op) |
- CmpSge(ref op) | CmpUge(ref op) |
- CmpSgt(ref op) | CmpUgt(ref op) => {
+ CmpE(ref op) | CmpNe(ref op) | CmpSlt(ref op) | CmpUlt(ref op) | CmpSle(ref op)
+ | CmpUle(ref op) | CmpSge(ref op) | CmpUge(ref op) | CmpSgt(ref op)
+ | CmpUgt(ref op) => {
let left = op.left();
let right = op.right();
- write!(f, "{:?}({}, {:?}, {:?})", op.op.operation, op.size(), left, right)
+ write!(
+ f,
+ "{:?}({}, {:?}, {:?})",
+ op.op.operation,
+ op.size(),
+ left,
+ right
+ )
}
Load(ref op) => {
@@ -735,7 +651,7 @@ where
let size = match reg {
Register::Temp(_) => Some(size),
Register::ArchReg(ref r) if r.info().size() != size => Some(size),
- _ => None
+ _ => None,
};
match size {
@@ -748,68 +664,67 @@ where
FlagBit(ref _op) => write!(f, "flag_bit"), // TODO
- Const(ref op) |
- ConstPtr(ref op) => write!(f, "0x{:x}", op.value()),
+ Const(ref op) | ConstPtr(ref op) => write!(f, "0x{:x}", op.value()),
- Adc(ref op) |
- Sbb(ref op) |
- Rlc(ref op) |
- Rrc(ref op) => {
+ Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => {
let left = op.left();
let right = op.right();
let carry = op.carry();
- write!(f, "{:?}({}, {:?}, {:?}, carry: {:?})",
- op.op.operation, op.size(), left, right, carry)
+ write!(
+ f,
+ "{:?}({}, {:?}, {:?}, carry: {:?})",
+ op.op.operation,
+ op.size(),
+ left,
+ right,
+ carry
+ )
}
- Add(ref op) |
- Sub(ref op) |
- And(ref op) |
- Or (ref op) |
- Xor(ref op) |
- Lsl(ref op) |
- Lsr(ref op) |
- Asr(ref op) |
- Rol(ref op) |
- Ror(ref op) |
- Mul(ref op) |
- MulsDp(ref op) |
- MuluDp(ref op) |
- Divu(ref op) |
- Divs(ref op) |
- Modu(ref op) |
- Mods(ref op) => {
+ Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
+ | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op)
+ | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op)
+ | Mods(ref op) => {
let left = op.left();
let right = op.right();
- write!(f, "{:?}({}, {:?}, {:?})",
- op.op.operation, op.size(), left, right)
+ write!(
+ f,
+ "{:?}({}, {:?}, {:?})",
+ op.op.operation,
+ op.size(),
+ left,
+ right
+ )
}
- DivuDp(ref op) |
- DivsDp(ref op) |
- ModuDp(ref op) |
- ModsDp(ref op) => {
+ DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => {
let high = op.high();
let low = op.low();
let right = op.right();
- write!(f, "{:?}({}, {:?}:{:?},{:?})",
- op.op.operation, op.size(), high, low, right)
+ write!(
+ f,
+ "{:?}({}, {:?}:{:?},{:?})",
+ op.op.operation,
+ op.size(),
+ high,
+ low,
+ right
+ )
}
- Neg(ref op) |
- Not(ref op) |
- Sx(ref op) |
- Zx(ref op) |
- LowPart(ref op) |
- BoolToInt(ref op) => {
- write!(f, "{:?}({}, {:?})", op.op.operation, op.size(), op.operand())
- }
+ Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op)
+ | BoolToInt(ref op) => write!(
+ f,
+ "{:?}({}, {:?})",
+ op.op.operation,
+ op.size(),
+ op.operand()
+ ),
UnimplMem(ref op) => write!(f, "unimplemented_mem({:?})", op.mem_expr()),
-
//TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO
}
}
diff --git a/rust/src/llil/function.rs b/rust/src/llil/function.rs
index ac50e72c..adc39f13 100644
--- a/rust/src/llil/function.rs
+++ b/rust/src/llil/function.rs
@@ -1,6 +1,20 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use binaryninjacore_sys::BNFreeLowLevelILFunction;
use binaryninjacore_sys::BNLowLevelILFunction;
use binaryninjacore_sys::BNNewLowLevelILFunctionReference;
-use binaryninjacore_sys::BNFreeLowLevelILFunction;
use std::borrow::Borrow;
use std::marker::PhantomData;
@@ -19,7 +33,6 @@ pub trait FunctionMutability: 'static {}
impl FunctionMutability for Mutable {}
impl FunctionMutability for Finalized {}
-
#[derive(Copy, Clone, Debug)]
pub struct LiftedNonSSA;
#[derive(Copy, Clone, Debug)]
@@ -38,7 +51,6 @@ pub trait FunctionForm: 'static {}
impl FunctionForm for SSA {}
impl<V: NonSSAVariant> FunctionForm for NonSSA<V> {}
-
pub struct Function<A: Architecture, M: FunctionMutability, F: FunctionForm> {
pub(crate) borrower: A::Handle,
pub(crate) handle: *mut BNLowLevelILFunction,
@@ -68,7 +80,7 @@ impl<'func, A, M, F> Function<A, M, F>
where
A: 'func + Architecture,
M: FunctionMutability,
- F: FunctionForm
+ F: FunctionForm,
{
pub(crate) unsafe fn from_raw(borrower: A::Handle, handle: *mut BNLowLevelILFunction) -> Self {
debug_assert!(!handle.is_null());
@@ -87,8 +99,8 @@ where
}
pub fn instruction_at<L: Into<Location>>(&self, loc: L) -> Option<Instruction<A, M, F>> {
- use binaryninjacore_sys::BNLowLevelILGetInstructionStart;
use binaryninjacore_sys::BNGetLowLevelILInstructionCount;
+ use binaryninjacore_sys::BNLowLevelILGetInstructionStart;
let loc: Location = loc.into();
let arch_handle = loc.arch.unwrap_or_else(|| *self.arch().as_ref());
@@ -112,7 +124,7 @@ where
use binaryninjacore_sys::BNGetLowLevelILInstructionCount;
if instr_idx >= BNGetLowLevelILInstructionCount(self.handle) {
panic!("instruction index {} out of bounds", instr_idx);
- }
+ }
Instruction {
function: self,
@@ -127,7 +139,6 @@ where
BNGetLowLevelILInstructionCount(self.handle)
}
}
-
}
// LLIL basic blocks are not available until the function object
@@ -136,7 +147,7 @@ where
impl<'func, A, F> Function<A, Finalized, F>
where
A: 'func + Architecture,
- F: FunctionForm
+ F: FunctionForm,
{
pub fn basic_blocks(&self) -> Array<BasicBlock<LowLevelBlock<A, Finalized, F>>> {
use binaryninjacore_sys::BNGetLowLevelILBasicBlockList;
@@ -155,7 +166,7 @@ impl<'func, A, M, F> ToOwned for Function<A, M, F>
where
A: 'func + Architecture,
M: FunctionMutability,
- F: FunctionForm
+ F: FunctionForm,
{
type Owned = Ref<Self>;
@@ -164,12 +175,11 @@ where
}
}
-
unsafe impl<'func, A, M, F> RefCountable for Function<A, M, F>
where
A: 'func + Architecture,
M: FunctionMutability,
- F: FunctionForm
+ F: FunctionForm,
{
unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
Ref::new(Self {
diff --git a/rust/src/llil/instruction.rs b/rust/src/llil/instruction.rs
index 4d1554df..109e5ea7 100644
--- a/rust/src/llil/instruction.rs
+++ b/rust/src/llil/instruction.rs
@@ -1,12 +1,26 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
use binaryninjacore_sys::BNGetLowLevelILByIndex;
use binaryninjacore_sys::BNGetLowLevelILIndexForInstruction;
use binaryninjacore_sys::BNLowLevelILInstruction;
use std::marker::PhantomData;
-use super::*;
use super::operation;
use super::operation::Operation;
+use super::*;
use crate::architecture::Architecture;
@@ -20,8 +34,10 @@ where
pub(crate) instr_idx: usize,
}
-fn common_info<'func, A, M, F>(function: &'func Function<A, M, F>, op: BNLowLevelILInstruction)
- -> Option<InstrInfo<'func, A, M, F>>
+fn common_info<'func, A, M, F>(
+ function: &'func Function<A, M, F>,
+ op: BNLowLevelILInstruction,
+) -> Option<InstrInfo<'func, A, M, F>>
where
A: 'func + Architecture,
M: FunctionMutability,
@@ -54,8 +70,7 @@ macro_rules! visit {
}
}
-fn common_visit<'func, A, M, F, CB>(info: &InstrInfo<'func, A, M, F>, f: &mut CB)
- -> VisitorAction
+fn common_visit<'func, A, M, F, CB>(info: &InstrInfo<'func, A, M, F>, f: &mut CB) -> VisitorAction
where
A: 'func + Architecture,
M: FunctionMutability,
@@ -70,7 +85,7 @@ where
Ret(ref op) => visit!(f, &op.target()),
If(ref op) => visit!(f, &op.condition()),
Value(ref e, _) => visit!(f, e),
- _ => {},
+ _ => {}
};
VisitorAction::Sibling
@@ -85,7 +100,8 @@ where
pub fn info(&self) -> InstrInfo<'func, A, M, NonSSA<V>> {
use binaryninjacore_sys::BNLowLevelILOperation::*;
- let expr_idx = unsafe { BNGetLowLevelILIndexForInstruction(self.function.handle, self.instr_idx) };
+ let expr_idx =
+ unsafe { BNGetLowLevelILIndexForInstruction(self.function.handle, self.instr_idx) };
let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, expr_idx) };
match op.operation {
@@ -94,8 +110,9 @@ where
LLIL_SET_FLAG => InstrInfo::SetFlag(Operation::new(self.function, op)),
LLIL_STORE => InstrInfo::Store(Operation::new(self.function, op)),
LLIL_PUSH => InstrInfo::Push(Operation::new(self.function, op)),
- LLIL_CALL |
- LLIL_CALL_STACK_ADJUST => InstrInfo::Call(Operation::new(self.function, op)),
+ LLIL_CALL | LLIL_CALL_STACK_ADJUST => {
+ InstrInfo::Call(Operation::new(self.function, op))
+ }
LLIL_SYSCALL => InstrInfo::Syscall(Operation::new(self.function, op)),
_ => {
common_info(self.function, op).unwrap_or_else(|| {
@@ -118,7 +135,10 @@ where
pub fn visit_tree<F>(&self, f: &mut F) -> VisitorAction
where
- F: FnMut(&Expression<'func, A, M, NonSSA<V>, ValueExpr>, &ExprInfo<'func, A, M, NonSSA<V>>) -> VisitorAction,
+ F: FnMut(
+ &Expression<'func, A, M, NonSSA<V>, ValueExpr>,
+ &ExprInfo<'func, A, M, NonSSA<V>>,
+ ) -> VisitorAction,
{
use self::InstrInfo::*;
let info = self.info();
@@ -171,5 +191,8 @@ where
Trap(Operation<'func, A, M, F, operation::Trap>),
Undef(Operation<'func, A, M, F, operation::NoArgs>),
- Value(Expression<'func, A, M, F, ValueExpr>, ExprInfo<'func, A, M, F>),
+ Value(
+ Expression<'func, A, M, F, ValueExpr>,
+ ExprInfo<'func, A, M, F>,
+ ),
}
diff --git a/rust/src/llil/lifting.rs b/rust/src/llil/lifting.rs
index e50eaaf1..90c5b46a 100644
--- a/rust/src/llil/lifting.rs
+++ b/rust/src/llil/lifting.rs
@@ -1,23 +1,43 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
use std::marker::PhantomData;
use std::mem;
-use crate::architecture::Register as ArchReg;
-use crate::architecture::{FlagWrite, Flag, FlagClass, FlagGroup, FlagRole, FlagCondition};
use crate::architecture::Architecture;
-
+use crate::architecture::Register as ArchReg;
+use crate::architecture::{Flag, FlagClass, FlagCondition, FlagGroup, FlagRole, FlagWrite};
use super::*;
pub trait Liftable<'func, A: 'func + Architecture> {
type Result: ExpressionResultType;
- fn lift(il: &'func Function<A, Mutable, NonSSA<LiftedNonSSA>>, expr: Self)
- -> Expression<'func, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>;
+ fn lift(
+ il: &'func Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ expr: Self,
+ ) -> Expression<'func, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>;
}
-pub trait LiftableWithSize<'func, A: 'func + Architecture>: Liftable<'func, A, Result=ValueExpr> {
- fn lift_with_size(il: &'func Function<A, Mutable, NonSSA<LiftedNonSSA>>, expr: Self, size: usize)
- -> Expression<'func, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>;
+pub trait LiftableWithSize<'func, A: 'func + Architecture>:
+ Liftable<'func, A, Result = ValueExpr>
+{
+ fn lift_with_size(
+ il: &'func Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ expr: Self,
+ size: usize,
+ ) -> Expression<'func, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>;
}
use binaryninjacore_sys::BNRegisterOrConstant;
@@ -40,7 +60,7 @@ impl<R: ArchReg> RegisterOrConstant<R> {
constant: true,
reg: 0,
value: value,
- }
+ },
}
}
}
@@ -90,30 +110,57 @@ pub enum FlagWriteOp<R: ArchReg> {
TestBit(usize, RegisterOrConstant<R>, RegisterOrConstant<R>),
AddOverflow(usize, RegisterOrConstant<R>, RegisterOrConstant<R>),
- Adc(usize, RegisterOrConstant<R>, RegisterOrConstant<R>, RegisterOrConstant<R>),
- Sbb(usize, RegisterOrConstant<R>, RegisterOrConstant<R>, RegisterOrConstant<R>),
- Rlc(usize, RegisterOrConstant<R>, RegisterOrConstant<R>, RegisterOrConstant<R>),
- Rrc(usize, RegisterOrConstant<R>, RegisterOrConstant<R>, RegisterOrConstant<R>),
+ Adc(
+ usize,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ ),
+ Sbb(
+ usize,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ ),
+ Rlc(
+ usize,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ ),
+ Rrc(
+ usize,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ RegisterOrConstant<R>,
+ ),
Pop(usize),
-
// TODO: floating point stuff, llil comparison ops that set flags, intrinsics
}
impl<R: ArchReg> FlagWriteOp<R> {
- pub(crate) fn from_op<A>(arch: &A, size: usize, op: BNLowLevelILOperation, operands: &[BNRegisterOrConstant])
- -> Option<Self>
+ pub(crate) fn from_op<A>(
+ arch: &A,
+ size: usize,
+ op: BNLowLevelILOperation,
+ operands: &[BNRegisterOrConstant],
+ ) -> Option<Self>
where
- A: Architecture<Register=R>,
- R: ArchReg<InfoType=A::RegisterInfo>,
+ A: Architecture<Register = R>,
+ R: ArchReg<InfoType = A::RegisterInfo>,
{
- use binaryninjacore_sys::BNLowLevelILOperation::*;
use self::FlagWriteOp::*;
+ use binaryninjacore_sys::BNLowLevelILOperation::*;
- fn build_op<A, R>(arch: &A, size: usize, operand: &BNRegisterOrConstant) -> RegisterOrConstant<R>
+ fn build_op<A, R>(
+ arch: &A,
+ size: usize,
+ operand: &BNRegisterOrConstant,
+ ) -> RegisterOrConstant<R>
where
- A: Architecture<Register=R>,
- R: ArchReg<InfoType=A::RegisterInfo>,
+ A: Architecture<Register = R>,
+ R: ArchReg<InfoType = A::RegisterInfo>,
{
if operand.constant {
RegisterOrConstant::Constant(size, operand.value)
@@ -182,15 +229,15 @@ impl<R: ArchReg> FlagWriteOp<R> {
(3, LLIL_RLC) => op!(Rlc, 0, 1, 2),
(3, LLIL_RRC) => op!(Rrc, 0, 1, 2),
- (0, LLIL_POP) => op!(Pop, ),
+ (0, LLIL_POP) => op!(Pop,),
_ => return None,
})
}
pub(crate) fn size_and_op(&self) -> (usize, BNLowLevelILOperation) {
- use binaryninjacore_sys::BNLowLevelILOperation::*;
use self::FlagWriteOp::*;
+ use binaryninjacore_sys::BNLowLevelILOperation::*;
match *self {
SetReg(size, ..) => (size, LLIL_SET_REG),
@@ -252,54 +299,54 @@ impl<R: ArchReg> FlagWriteOp<R> {
let count = match *self {
Pop(_) => 0,
- SetReg(_, op0) |
- Load(_, op0) |
- Push(_, op0) |
- Neg(_, op0) |
- Not(_, op0) |
- Sx(_, op0) |
- Zx(_, op0) |
- LowPart(_, op0) |
- BoolToInt(_, op0) |
- FloatToInt(_, op0) => {
+ SetReg(_, op0)
+ | Load(_, op0)
+ | Push(_, op0)
+ | Neg(_, op0)
+ | Not(_, op0)
+ | Sx(_, op0)
+ | Zx(_, op0)
+ | LowPart(_, op0)
+ | BoolToInt(_, op0)
+ | FloatToInt(_, op0) => {
operands[0] = op0.into_api();
1
}
- SetRegSplit(_, op0, op1) |
- Sub(_, op0, op1) |
- Add(_, op0, op1) |
- Store(_, op0, op1) |
- And(_, op0, op1) |
- Or(_, op0, op1) |
- Xor(_, op0, op1) |
- Lsl(_, op0, op1) |
- Lsr(_, op0, op1) |
- Asr(_, op0, op1) |
- Rol(_, op0, op1) |
- Ror(_, op0, op1) |
- Mul(_, op0, op1) |
- MuluDp(_, op0, op1) |
- MulsDp(_, op0, op1) |
- Divu(_, op0, op1) |
- Divs(_, op0, op1) |
- Modu(_, op0, op1) |
- Mods(_, op0, op1) |
- DivuDp(_, op0, op1) |
- DivsDp(_, op0, op1) |
- ModuDp(_, op0, op1) |
- ModsDp(_, op0, op1) |
- TestBit(_, op0, op1) |
- AddOverflow(_, op0, op1) => {
+ SetRegSplit(_, op0, op1)
+ | Sub(_, op0, op1)
+ | Add(_, op0, op1)
+ | Store(_, op0, op1)
+ | And(_, op0, op1)
+ | Or(_, op0, op1)
+ | Xor(_, op0, op1)
+ | Lsl(_, op0, op1)
+ | Lsr(_, op0, op1)
+ | Asr(_, op0, op1)
+ | Rol(_, op0, op1)
+ | Ror(_, op0, op1)
+ | Mul(_, op0, op1)
+ | MuluDp(_, op0, op1)
+ | MulsDp(_, op0, op1)
+ | Divu(_, op0, op1)
+ | Divs(_, op0, op1)
+ | Modu(_, op0, op1)
+ | Mods(_, op0, op1)
+ | DivuDp(_, op0, op1)
+ | DivsDp(_, op0, op1)
+ | ModuDp(_, op0, op1)
+ | ModsDp(_, op0, op1)
+ | TestBit(_, op0, op1)
+ | AddOverflow(_, op0, op1) => {
operands[0] = op0.into_api();
operands[1] = op1.into_api();
2
}
- Adc(_, op0, op1, op2) |
- Sbb(_, op0, op1, op2) |
- Rlc(_, op0, op1, op2) |
- Rrc(_, op0, op1, op2) => {
+ Adc(_, op0, op1, op2)
+ | Sbb(_, op0, op1, op2)
+ | Rlc(_, op0, op1, op2)
+ | Rrc(_, op0, op1, op2) => {
operands[0] = op0.into_api();
operands[1] = op1.into_api();
operands[2] = op2.into_api();
@@ -311,19 +358,29 @@ impl<R: ArchReg> FlagWriteOp<R> {
}
}
-
-pub fn get_default_flag_write_llil<'func, A>(arch: &A, role: FlagRole, op: FlagWriteOp<A::Register>, il: &'func Lifter<A>)
- -> LiftedExpr<'func, A>
+pub fn get_default_flag_write_llil<'func, A>(
+ arch: &A,
+ role: FlagRole,
+ op: FlagWriteOp<A::Register>,
+ il: &'func Lifter<A>,
+) -> LiftedExpr<'func, A>
where
- A: 'func + Architecture
+ A: 'func + Architecture,
{
let (size, operation) = op.size_and_op();
let (count, operands) = op.api_operands();
let expr_idx = unsafe {
use binaryninjacore_sys::BNGetDefaultArchitectureFlagWriteLowLevelIL;
- BNGetDefaultArchitectureFlagWriteLowLevelIL(arch.as_ref().0, operation, size, role,
- operands.as_ptr() as *mut _, count, il.handle)
+ BNGetDefaultArchitectureFlagWriteLowLevelIL(
+ arch.as_ref().0,
+ operation,
+ size,
+ role,
+ operands.as_ptr() as *mut _,
+ count,
+ il.handle,
+ )
};
Expression {
@@ -333,10 +390,14 @@ where
}
}
-pub fn get_default_flag_cond_llil<'func, A>(arch: &A, cond: FlagCondition, class: Option<A::FlagClass>, il: &'func Lifter<A>)
- -> LiftedExpr<'func, A>
+pub fn get_default_flag_cond_llil<'func, A>(
+ arch: &A,
+ cond: FlagCondition,
+ class: Option<A::FlagClass>,
+ il: &'func Lifter<A>,
+) -> LiftedExpr<'func, A>
where
- A: 'func + Architecture
+ A: 'func + Architecture,
{
use binaryninjacore_sys::BNGetDefaultArchitectureFlagConditionLowLevelIL;
@@ -344,7 +405,8 @@ where
let class_id = class.map(|c| c.id()).unwrap_or(0);
unsafe {
- let expr_idx = BNGetDefaultArchitectureFlagConditionLowLevelIL(handle.0, cond, class_id, il.handle);
+ let expr_idx =
+ BNGetDefaultArchitectureFlagConditionLowLevelIL(handle.0, cond, class_id, il.handle);
Expression {
function: il,
@@ -402,13 +464,15 @@ prim_int_lifter!(u32);
prim_int_lifter!(u64);
impl<'a, R: ArchReg, A: 'a + Architecture> Liftable<'a, A> for Register<R>
- where R: Liftable<'a, A, Result=ValueExpr> + Into<Register<R>>
+where
+ R: Liftable<'a, A, Result = ValueExpr> + Into<Register<R>>,
{
type Result = ValueExpr;
- fn lift(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, reg: Self)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>
- {
+ fn lift(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ reg: Self,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result> {
match reg {
Register::ArchReg(r) => R::lift(il, r),
Register::Temp(t) => il.reg(il.arch().default_integer_size(), Register::Temp(t)),
@@ -417,11 +481,14 @@ impl<'a, R: ArchReg, A: 'a + Architecture> Liftable<'a, A> for Register<R>
}
impl<'a, R: ArchReg, A: 'a + Architecture> LiftableWithSize<'a, A> for Register<R>
- where R: LiftableWithSize<'a, A> + Into<Register<R>>
+where
+ R: LiftableWithSize<'a, A> + Into<Register<R>>,
{
- fn lift_with_size(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, reg: Self, size: usize)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
+ fn lift_with_size(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ reg: Self,
+ size: usize,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
match reg {
Register::ArchReg(r) => R::lift_with_size(il, r, size),
Register::Temp(t) => il.reg(size, Register::Temp(t)),
@@ -429,15 +496,16 @@ impl<'a, R: ArchReg, A: 'a + Architecture> LiftableWithSize<'a, A> for Register<
}
}
-
impl<'a, R: ArchReg, A: 'a + Architecture> Liftable<'a, A> for RegisterOrConstant<R>
- where R: LiftableWithSize<'a, A, Result=ValueExpr> + Into<Register<R>>
+where
+ R: LiftableWithSize<'a, A, Result = ValueExpr> + Into<Register<R>>,
{
type Result = ValueExpr;
- fn lift(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, reg: Self)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>
- {
+ fn lift(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ reg: Self,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result> {
match reg {
RegisterOrConstant::Register(size, r) => Register::<R>::lift_with_size(il, r, size),
RegisterOrConstant::Constant(size, value) => u64::lift_with_size(il, value, size),
@@ -446,11 +514,14 @@ impl<'a, R: ArchReg, A: 'a + Architecture> Liftable<'a, A> for RegisterOrConstan
}
impl<'a, R: ArchReg, A: 'a + Architecture> LiftableWithSize<'a, A> for RegisterOrConstant<R>
- where R: LiftableWithSize<'a, A> + Into<Register<R>>
+where
+ R: LiftableWithSize<'a, A> + Into<Register<R>>,
{
- fn lift_with_size(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, reg: Self, size: usize)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
+ fn lift_with_size(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ reg: Self,
+ size: usize,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
// TODO ensure requested size is compatible with size of this constant
match reg {
RegisterOrConstant::Register(_, r) => Register::<R>::lift_with_size(il, r, size),
@@ -459,7 +530,6 @@ impl<'a, R: ArchReg, A: 'a + Architecture> LiftableWithSize<'a, A> for RegisterO
}
}
-
impl<'a, A, R> Liftable<'a, A> for Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, R>
where
A: 'a + Architecture,
@@ -467,24 +537,33 @@ where
{
type Result = R;
- fn lift(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, expr: Self)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>
- {
+ fn lift(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ expr: Self,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result> {
debug_assert!(expr.function.handle == il.handle);
expr
}
}
-impl<'a, A: 'a + Architecture> LiftableWithSize<'a, A> for Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
- fn lift_with_size(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, expr: Self, _size: usize)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>
- {
+impl<'a, A: 'a + Architecture> LiftableWithSize<'a, A>
+ for Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
+{
+ fn lift_with_size(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ expr: Self,
+ _size: usize,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result> {
#[cfg(debug_assertions)]
{
if let Some(expr_size) = expr.info().size() {
if expr_size != _size {
- warn!("il @ {:x} attempted to lift {} byte expression as {} bytes",
- il.current_address(), expr_size, _size);
+ warn!(
+ "il @ {:x} attempted to lift {} byte expression as {} bytes",
+ il.current_address(),
+ expr_size,
+ _size
+ );
}
}
}
@@ -493,7 +572,6 @@ impl<'a, A: 'a + Architecture> LiftableWithSize<'a, A> for Expression<'a, A, Mut
}
}
-
impl<'func, A, R> Expression<'func, A, Mutable, NonSSA<LiftedNonSSA>, R>
where
A: 'func + Architecture,
@@ -502,9 +580,7 @@ where
pub fn with_source_operand(self, op: u32) -> Self {
use binaryninjacore_sys::BNLowLevelILSetExprSourceOperand;
- unsafe {
- BNLowLevelILSetExprSourceOperand(self.function.handle, self.expr_idx, op)
- }
+ unsafe { BNLowLevelILSetExprSourceOperand(self.function.handle, self.expr_idx, op) }
self
}
@@ -515,7 +591,6 @@ where
}
}
-
use binaryninjacore_sys::BNLowLevelILOperation;
pub struct ExpressionBuilder<'func, A, R>
where
@@ -548,7 +623,10 @@ where
self.into()
}
- pub fn with_source_operand(self, op: u32) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, R> {
+ pub fn with_source_operand(
+ self,
+ op: u32,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, R> {
let expr = self.into_expr();
expr.with_source_operand(op)
}
@@ -561,7 +639,8 @@ where
}
}
-impl<'a, A, R> Into<Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, R>> for ExpressionBuilder<'a, A, R>
+impl<'a, A, R> Into<Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, R>>
+ for ExpressionBuilder<'a, A, R>
where
A: 'a + Architecture,
R: ExpressionResultType,
@@ -570,9 +649,16 @@ where
use binaryninjacore_sys::BNLowLevelILAddExpr;
let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.function.handle,
- self.op, self.size, self.flags,
- self.op1, self.op2, self.op3, self.op4)
+ BNLowLevelILAddExpr(
+ self.function.handle,
+ self.op,
+ self.size,
+ self.flags,
+ self.op1,
+ self.op2,
+ self.op3,
+ self.op4,
+ )
};
Expression {
@@ -590,9 +676,10 @@ where
{
type Result = R;
- fn lift(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, expr: Self)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result>
- {
+ fn lift(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ expr: Self,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, Self::Result> {
debug_assert!(expr.function.handle == il.handle);
expr.into()
@@ -603,34 +690,36 @@ impl<'a, A> LiftableWithSize<'a, A> for ExpressionBuilder<'a, A, ValueExpr>
where
A: 'a + Architecture,
{
- fn lift_with_size(il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>, expr: Self, _size: usize)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
+ fn lift_with_size(
+ il: &'a Function<A, Mutable, NonSSA<LiftedNonSSA>>,
+ expr: Self,
+ _size: usize,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
#[cfg(debug_assertions)]
{
use binaryninjacore_sys::BNLowLevelILOperation::{LLIL_UNIMPL, LLIL_UNIMPL_MEM};
if expr.size != _size && ![LLIL_UNIMPL, LLIL_UNIMPL_MEM].contains(&expr.op) {
- warn!("il @ {:x} attempted to lift {} byte expression builder as {} bytes",
- il.current_address(), expr.size, _size);
+ warn!(
+ "il @ {:x} attempted to lift {} byte expression builder as {} bytes",
+ il.current_address(),
+ expr.size,
+ _size
+ );
}
}
Liftable::lift(il, expr)
}
}
-
macro_rules! no_arg_lifter {
($name:ident, $op:ident, $result:ty) => {
pub fn $name(&self) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, $result> {
- use binaryninjacore_sys::BNLowLevelILOperation::$op;
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::$op;
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, $op,
- 0, 0, 0, 0, 0, 0)
- };
+ let expr_idx = unsafe { BNLowLevelILAddExpr(self.handle, $op, 0, 0, 0, 0, 0, 0) };
Expression {
function: self,
@@ -638,13 +727,12 @@ macro_rules! no_arg_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
macro_rules! sized_no_arg_lifter {
($name:ident, $op:ident, $result:ty) => {
- pub fn $name(&self, size: usize) -> ExpressionBuilder<A, $result>
- {
+ pub fn $name(&self, size: usize) -> ExpressionBuilder<A, $result> {
use binaryninjacore_sys::BNLowLevelILOperation::$op;
ExpressionBuilder {
@@ -659,24 +747,25 @@ macro_rules! sized_no_arg_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
macro_rules! unsized_unary_op_lifter {
($name:ident, $op:ident, $result:ty) => {
- pub fn $name<'a, E>(&'a self, expr: E)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, $result>
+ pub fn $name<'a, E>(
+ &'a self,
+ expr: E,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, $result>
where
- E: Liftable<'a, A, Result=ValueExpr>
+ E: Liftable<'a, A, Result = ValueExpr>,
{
- use binaryninjacore_sys::BNLowLevelILOperation::$op;
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::$op;
let expr = E::lift(self, expr);
let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, $op, 0, 0,
- expr.expr_idx as u64, 0, 0, 0)
+ BNLowLevelILAddExpr(self.handle, $op, 0, 0, expr.expr_idx as u64, 0, 0, 0)
};
Expression {
@@ -685,15 +774,14 @@ macro_rules! unsized_unary_op_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
macro_rules! sized_unary_op_lifter {
($name:ident, $op:ident, $result:ty) => {
- pub fn $name<'a, E>(&'a self, size: usize, expr: E)
- -> ExpressionBuilder<'a, A, $result>
+ pub fn $name<'a, E>(&'a self, size: usize, expr: E) -> ExpressionBuilder<'a, A, $result>
where
- E: LiftableWithSize<'a, A>
+ E: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::$op;
@@ -711,15 +799,14 @@ macro_rules! sized_unary_op_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
macro_rules! size_changing_unary_op_lifter {
($name:ident, $op:ident, $result:ty) => {
- pub fn $name<'a, E>(&'a self, size: usize, expr: E)
- -> ExpressionBuilder<'a, A, $result>
+ pub fn $name<'a, E>(&'a self, size: usize, expr: E) -> ExpressionBuilder<'a, A, $result>
where
- E: LiftableWithSize<'a, A>
+ E: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::$op;
@@ -737,16 +824,20 @@ macro_rules! size_changing_unary_op_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
macro_rules! binary_op_lifter {
($name:ident, $op:ident) => {
- pub fn $name<'a, L, R>(&'a self, size: usize, left: L, right: R)
- -> ExpressionBuilder<'a, A, ValueExpr>
+ pub fn $name<'a, L, R>(
+ &'a self,
+ size: usize,
+ left: L,
+ right: R,
+ ) -> ExpressionBuilder<'a, A, ValueExpr>
where
L: LiftableWithSize<'a, A>,
- R: LiftableWithSize<'a, A>
+ R: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::$op;
@@ -765,13 +856,18 @@ macro_rules! binary_op_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
macro_rules! binary_op_carry_lifter {
($name:ident, $op:ident) => {
- pub fn $name<'a, L, R, C>(&'a self, size: usize, left: L, right: R, carry: C)
- -> ExpressionBuilder<'a, A, ValueExpr>
+ pub fn $name<'a, L, R, C>(
+ &'a self,
+ size: usize,
+ left: L,
+ right: R,
+ carry: C,
+ ) -> ExpressionBuilder<'a, A, ValueExpr>
where
L: LiftableWithSize<'a, A>,
R: LiftableWithSize<'a, A>,
@@ -795,21 +891,21 @@ macro_rules! binary_op_carry_lifter {
_ty: PhantomData,
}
}
- }
+ };
}
impl<A> Function<A, Mutable, NonSSA<LiftedNonSSA>>
where
A: Architecture,
{
- pub fn expression<'a, E: Liftable<'a, A>>(&'a self, expr: E)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, E::Result>
- {
+ pub fn expression<'a, E: Liftable<'a, A>>(
+ &'a self,
+ expr: E,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, E::Result> {
E::lift(self, expr)
}
- pub fn instruction<'a, E: Liftable<'a, A>>(&'a self, expr: E)
- {
+ pub fn instruction<'a, E: Liftable<'a, A>>(&'a self, expr: E) {
let expr = self.expression(expr);
unsafe {
@@ -818,35 +914,35 @@ where
}
}
-
pub unsafe fn replace_expression<'a, E: Liftable<'a, A>>(
&'a self,
replaced_expr_index: usize,
- replacement: E)
- {
- unsafe {
- use binaryninjacore_sys::BNReplaceLowLevelILExpr;
- use binaryninjacore_sys::BNGetLowLevelILExprCount;
-
- if replaced_expr_index >= BNGetLowLevelILExprCount(self.handle) {
- panic!("bad expr idx used: {} exceeds function bounds", replaced_expr_index);
- }
+ replacement: E,
+ ) {
+ use binaryninjacore_sys::BNGetLowLevelILExprCount;
+ use binaryninjacore_sys::BNReplaceLowLevelILExpr;
- let expr = self.expression(replacement);
- BNReplaceLowLevelILExpr(self.handle, replaced_expr_index, expr.expr_idx);
+ if replaced_expr_index >= BNGetLowLevelILExprCount(self.handle) {
+ panic!(
+ "bad expr idx used: {} exceeds function bounds",
+ replaced_expr_index
+ );
}
+
+ let expr = self.expression(replacement);
+ BNReplaceLowLevelILExpr(self.handle, replaced_expr_index, expr.expr_idx);
}
- pub fn const_int(&self, size: usize, val: u64)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST;
+ pub fn const_int(
+ &self,
+ size: usize,
+ val: u64,
+ ) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST;
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_CONST, size, 0,
- val, 0, 0, 0)
- };
+ let expr_idx =
+ unsafe { BNLowLevelILAddExpr(self.handle, LLIL_CONST, size, 0, val, 0, 0, 0) };
Expression {
function: self,
@@ -855,16 +951,16 @@ where
}
}
- pub fn const_ptr_sized(&self, size: usize, val: u64)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST_PTR;
+ pub fn const_ptr_sized(
+ &self,
+ size: usize,
+ val: u64,
+ ) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST_PTR;
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_CONST_PTR, size, 0,
- val, 0, 0, 0)
- };
+ let expr_idx =
+ unsafe { BNLowLevelILAddExpr(self.handle, LLIL_CONST_PTR, size, 0, val, 0, 0, 0) };
Expression {
function: self,
@@ -873,22 +969,15 @@ where
}
}
- pub fn const_ptr(&self, val: u64)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
+ pub fn const_ptr(&self, val: u64) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
self.const_ptr_sized(self.arch().address_size(), val)
}
- pub fn trap(&self, val: u64)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_TRAP;
+ pub fn trap(&self, val: u64) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_TRAP;
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_TRAP, 0, 0,
- val, 0, 0, 0)
- };
+ let expr_idx = unsafe { BNLowLevelILAddExpr(self.handle, LLIL_TRAP, 0, 0, val, 0, 0, 0) };
Expression {
function: self,
@@ -910,19 +999,26 @@ where
unsized_unary_op_lifter!(jump, LLIL_JUMP, VoidExpr);
// JumpTo TODO
- pub fn if_expr<'a: 'b, 'b, C>(&'a self, cond: C, t: &'b Label, f: &'b Label)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr>
- where
- C: Liftable<'b, A, Result=ValueExpr>,
+ pub fn if_expr<'a: 'b, 'b, C>(
+ &'a self,
+ cond: C,
+ t: &'b Label,
+ f: &'b Label,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr>
+ where
+ C: Liftable<'b, A, Result = ValueExpr>,
{
use binaryninjacore_sys::BNLowLevelILIf;
let cond = C::lift(self, cond);
let expr_idx = unsafe {
- BNLowLevelILIf(self.handle, cond.expr_idx as u64,
- &t.0 as *const _ as *mut _,
- &f.0 as *const _ as *mut _)
+ BNLowLevelILIf(
+ self.handle,
+ cond.expr_idx as u64,
+ &t.0 as *const _ as *mut _,
+ &f.0 as *const _ as *mut _,
+ )
};
Expression {
@@ -932,14 +1028,13 @@ where
}
}
- pub fn goto<'a: 'b, 'b>(&'a self, l: &'b Label)
- -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr>
- {
+ pub fn goto<'a: 'b, 'b>(
+ &'a self,
+ l: &'b Label,
+ ) -> Expression<'a, A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr> {
use binaryninjacore_sys::BNLowLevelILGoto;
- let expr_idx = unsafe {
- BNLowLevelILGoto(self.handle, &l.0 as *const _ as *mut _)
- };
+ let expr_idx = unsafe { BNLowLevelILGoto(self.handle, &l.0 as *const _ as *mut _) };
Expression {
function: self,
@@ -948,11 +1043,13 @@ where
}
}
- pub fn reg<R: Into<Register<A::Register>>>(&self, size: usize, reg: R)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG;
+ pub fn reg<R: Into<Register<A::Register>>>(
+ &self,
+ size: usize,
+ reg: R,
+ ) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG;
// TODO verify valid id
let reg = match reg.into() {
@@ -960,10 +1057,8 @@ where
Register::Temp(r) => 0x8000_0000 | r,
};
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_REG, size, 0,
- reg as u64, 0, 0, 0)
- };
+ let expr_idx =
+ unsafe { BNLowLevelILAddExpr(self.handle, LLIL_REG, size, 0, reg as u64, 0, 0, 0) };
Expression {
function: self,
@@ -972,11 +1067,15 @@ where
}
}
- pub fn set_reg<'a, R, E>(&'a self, size: usize, dest_reg: R, expr: E)
- -> ExpressionBuilder<'a, A, VoidExpr>
+ pub fn set_reg<'a, R, E>(
+ &'a self,
+ size: usize,
+ dest_reg: R,
+ expr: E,
+ ) -> ExpressionBuilder<'a, A, VoidExpr>
where
R: Into<Register<A::Register>>,
- E: LiftableWithSize<'a, A>
+ E: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::LLIL_SET_REG;
@@ -1001,12 +1100,17 @@ where
}
}
- pub fn set_reg_split<'a, H, L, E>(&'a self, size: usize, hi_reg: H, lo_reg: L, expr: E)
- -> ExpressionBuilder<'a, A, VoidExpr>
+ pub fn set_reg_split<'a, H, L, E>(
+ &'a self,
+ size: usize,
+ hi_reg: H,
+ lo_reg: L,
+ expr: E,
+ ) -> ExpressionBuilder<'a, A, VoidExpr>
where
H: Into<Register<A::Register>>,
L: Into<Register<A::Register>>,
- E: LiftableWithSize<'a, A>
+ E: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::LLIL_SET_REG_SPLIT;
@@ -1037,17 +1141,13 @@ where
}
}
- pub fn flag(&self, flag: A::Flag)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG;
+ pub fn flag(&self, flag: A::Flag) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG;
// TODO verify valid id
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_FLAG, 0, 0,
- flag.id() as u64, 0, 0, 0)
- };
+ let expr_idx =
+ unsafe { BNLowLevelILAddExpr(self.handle, LLIL_FLAG, 0, 0, flag.id() as u64, 0, 0, 0) };
Expression {
function: self,
@@ -1056,17 +1156,16 @@ where
}
}
- pub fn flag_cond(&self, cond: FlagCondition)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_COND;
+ pub fn flag_cond(
+ &self,
+ cond: FlagCondition,
+ ) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_COND;
// TODO verify valid id
- let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_FLAG_COND, 0, 0,
- cond as u64, 0, 0, 0)
- };
+ let expr_idx =
+ unsafe { BNLowLevelILAddExpr(self.handle, LLIL_FLAG_COND, 0, 0, cond as u64, 0, 0, 0) };
Expression {
function: self,
@@ -1075,16 +1174,25 @@ where
}
}
- pub fn flag_group(&self, group: A::FlagGroup)
- -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr>
- {
- use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_GROUP;
+ pub fn flag_group(
+ &self,
+ group: A::FlagGroup,
+ ) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> {
use binaryninjacore_sys::BNLowLevelILAddExpr;
+ use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_GROUP;
// TODO verify valid id
let expr_idx = unsafe {
- BNLowLevelILAddExpr(self.handle, LLIL_FLAG_GROUP, 0, 0,
- group.id() as u64, 0, 0, 0)
+ BNLowLevelILAddExpr(
+ self.handle,
+ LLIL_FLAG_GROUP,
+ 0,
+ 0,
+ group.id() as u64,
+ 0,
+ 0,
+ 0,
+ )
};
Expression {
@@ -1094,10 +1202,13 @@ where
}
}
- pub fn set_flag<'a, E>(&'a self, dest_flag: A::Flag, expr: E)
- -> ExpressionBuilder<'a, A, VoidExpr>
+ pub fn set_flag<'a, E>(
+ &'a self,
+ dest_flag: A::Flag,
+ expr: E,
+ ) -> ExpressionBuilder<'a, A, VoidExpr>
where
- E: LiftableWithSize<'a, A>
+ E: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::LLIL_SET_FLAG;
@@ -1123,10 +1234,9 @@ where
FlagBit(usize, Flag<A>, u64),
*/
- pub fn load<'a, E>(&'a self, size: usize, source_mem: E)
- -> ExpressionBuilder<'a, A, ValueExpr>
+ pub fn load<'a, E>(&'a self, size: usize, source_mem: E) -> ExpressionBuilder<'a, A, ValueExpr>
where
- E: Liftable<'a, A, Result=ValueExpr>
+ E: Liftable<'a, A, Result = ValueExpr>,
{
use binaryninjacore_sys::BNLowLevelILOperation::LLIL_LOAD;
@@ -1145,11 +1255,15 @@ where
}
}
- pub fn store<'a, D, V>(&'a self, size: usize, dest_mem: D, value: V)
- -> ExpressionBuilder<'a, A, VoidExpr>
+ pub fn store<'a, D, V>(
+ &'a self,
+ size: usize,
+ dest_mem: D,
+ value: V,
+ ) -> ExpressionBuilder<'a, A, VoidExpr>
where
- D: Liftable<'a, A, Result=ValueExpr>,
- V: LiftableWithSize<'a, A>
+ D: Liftable<'a, A, Result = ValueExpr>,
+ V: LiftableWithSize<'a, A>,
{
use binaryninjacore_sys::BNLowLevelILOperation::LLIL_STORE;
@@ -1206,7 +1320,6 @@ where
binary_op_carry_lifter!(adc, LLIL_ADC);
binary_op_carry_lifter!(sbb, LLIL_SBB);
-
/*
DivsDp(usize, Expr, Expr, Expr, Option<A::FlagWrite>),
DivuDp(usize, Expr, Expr, Expr, Option<A::FlagWrite>),
@@ -1233,9 +1346,7 @@ where
pub fn current_address(&self) -> u64 {
use binaryninjacore_sys::BNLowLevelILGetCurrentAddress;
- unsafe {
- BNLowLevelILGetCurrentAddress(self.handle)
- }
+ unsafe { BNLowLevelILGetCurrentAddress(self.handle) }
}
pub fn set_current_address<L: Into<Location>>(&self, loc: L) {
@@ -1244,7 +1355,9 @@ where
let loc: Location = loc.into();
let arch = loc.arch.unwrap_or_else(|| *self.arch().as_ref());
- unsafe { BNLowLevelILSetCurrentAddress(self.handle, arch.0, loc.addr); }
+ unsafe {
+ BNLowLevelILSetCurrentAddress(self.handle, arch.0, loc.addr);
+ }
}
pub fn label_for_address<L: Into<Location>>(&self, loc: L) -> Option<&Label> {
@@ -1253,9 +1366,7 @@ where
let loc: Location = loc.into();
let arch = loc.arch.unwrap_or_else(|| *self.arch().as_ref());
- let res = unsafe {
- BNGetLowLevelILLabelForAddress(self.handle, arch.0, loc.addr)
- };
+ let res = unsafe { BNGetLowLevelILLabelForAddress(self.handle, arch.0, loc.addr) };
if res.is_null() {
None
@@ -1282,11 +1393,10 @@ impl Label {
use binaryninjacore_sys::BNLowLevelILInitLabel;
unsafe {
- let mut res = Label(mem::uninitialized());
+ // This is one instance where it'd be easy to use mem::MaybeUninit, but *shrug* this is easier
+ let mut res = Label(mem::zeroed());
BNLowLevelILInitLabel(&mut res.0 as *mut _);
res
}
}
}
-
-
diff --git a/rust/src/llil/mod.rs b/rust/src/llil/mod.rs
index c3b1b350..198d8373 100644
--- a/rust/src/llil/mod.rs
+++ b/rust/src/llil/mod.rs
@@ -1,28 +1,44 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
use std::fmt;
-// TODO provide some way to forbid emitting register reads for certain registers
+// TODO : provide some way to forbid emitting register reads for certain registers
// also writing for certain registers (e.g. zero register must prohibit il.set_reg and il.reg
// (replace with nop or const(0) respectively)
// requirements on load/store memory address sizes?
// can reg/set_reg be used with sizes that differ from what is in BNRegisterInfo?
-use crate::architecture::Register as ArchReg;
use crate::architecture::Architecture;
+use crate::architecture::Register as ArchReg;
use crate::function::Location;
+mod block;
+mod expression;
mod function;
mod instruction;
-mod expression;
mod lifting;
-mod block;
pub mod operation;
+pub use self::expression::*;
pub use self::function::*;
pub use self::instruction::*;
-pub use self::expression::*;
-pub use self::lifting::{Liftable, LiftableWithSize, Label, ExpressionBuilder, FlagWriteOp, RegisterOrConstant};
-pub use self::lifting::get_default_flag_write_llil;
pub use self::lifting::get_default_flag_cond_llil;
+pub use self::lifting::get_default_flag_write_llil;
+pub use self::lifting::{
+ ExpressionBuilder, FlagWriteOp, Label, Liftable, LiftableWithSize, RegisterOrConstant,
+};
pub use self::block::Block as LowLevelBlock;
pub use self::block::BlockIter as LowLevelBlockIter;
@@ -60,14 +76,13 @@ impl<R: ArchReg> fmt::Debug for Register<R> {
#[derive(Copy, Clone, Debug)]
pub enum SSARegister<R: ArchReg> {
Full(Register<R>, u32), // no such thing as partial access to a temp register, I think
- Partial(R, u32, R), // partial accesses only possible for arch registers, I think
+ Partial(R, u32, R), // partial accesses only possible for arch registers, I think
}
impl<R: ArchReg> SSARegister<R> {
pub fn version(&self) -> u32 {
match *self {
- SSARegister::Full(_, ver) |
- SSARegister::Partial(_, ver, _) => ver
+ SSARegister::Full(_, ver) | SSARegister::Partial(_, ver, _) => ver,
}
}
}
@@ -77,4 +92,3 @@ pub enum VisitorAction {
Sibling,
Halt,
}
-
diff --git a/rust/src/llil/operation.rs b/rust/src/llil/operation.rs
index 81d72d57..55d384e9 100644
--- a/rust/src/llil/operation.rs
+++ b/rust/src/llil/operation.rs
@@ -1,3 +1,17 @@
+// Copyright 2021 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
use binaryninjacore_sys::BNLowLevelILInstruction;
use std::marker::PhantomData;
@@ -46,7 +60,7 @@ where
pub fn flag_write(&self) -> Option<A::FlagWrite> {
match self.op.flags {
0 => None,
- id => self.function.arch().flag_write_from_id(id)
+ id => self.function.arch().flag_write_from_id(id),
}
}
}
@@ -54,8 +68,6 @@ where
// LLIL_NOP, LLIL_NORET, LLIL_BP, LLIL_UNDEF, LLIL_UNIMPL
pub struct NoArgs;
-
-
// LLIL_POP
pub struct Pop;
@@ -70,15 +82,9 @@ where
}
}
-
-
-
// LLIL_SYSCALL, LLIL_SYSCALL_SSA
pub struct Syscall;
-
-
-
// LLIL_SET_REG, LLIL_SET_REG_SSA, LLIL_SET_REG_PARTIAL_SSA
pub struct SetReg;
@@ -98,14 +104,18 @@ where
if raw_id >= 0x8000_0000 {
Register::Temp(raw_id & 0x7fff_ffff)
} else {
- self.function.arch().register_from_id(raw_id)
- .map(Register::ArchReg)
- .unwrap_or_else(|| {
- error!("got garbage register from LLIL_SET_REG @ 0x{:x}",
- self.op.address);
+ self.function
+ .arch()
+ .register_from_id(raw_id)
+ .map(Register::ArchReg)
+ .unwrap_or_else(|| {
+ error!(
+ "got garbage register from LLIL_SET_REG @ 0x{:x}",
+ self.op.address
+ );
- Register::Temp(0)
- })
+ Register::Temp(0)
+ })
}
}
@@ -118,7 +128,6 @@ where
}
}
-
// LLIL_SET_REG_SPLIT, LLIL_SET_REG_SPLIT_SSA
pub struct SetRegSplit;
@@ -138,14 +147,18 @@ where
if raw_id >= 0x8000_0000 {
Register::Temp(raw_id & 0x7fff_ffff)
} else {
- self.function.arch().register_from_id(raw_id)
- .map(Register::ArchReg)
- .unwrap_or_else(|| {
- error!("got garbage register from LLIL_SET_REG_SPLIT @ 0x{:x}",
- self.op.address);
+ self.function
+ .arch()
+ .register_from_id(raw_id)
+ .map(Register::ArchReg)
+ .unwrap_or_else(|| {
+ error!(
+ "got garbage register from LLIL_SET_REG_SPLIT @ 0x{:x}",
+ self.op.address
+ );
- Register::Temp(0)
- })
+ Register::Temp(0)
+ })
}
}
@@ -155,14 +168,18 @@ where
if raw_id >= 0x8000_0000 {
Register::Temp(raw_id & 0x7fff_ffff)
} else {
- self.function.arch().register_from_id(raw_id)
- .map(Register::ArchReg)
- .unwrap_or_else(|| {
- error!("got garbage register from LLIL_SET_REG_SPLIT @ 0x{:x}",
- self.op.address);
+ self.function
+ .arch()
+ .register_from_id(raw_id)
+ .map(Register::ArchReg)
+ .unwrap_or_else(|| {
+ error!(
+ "got garbage register from LLIL_SET_REG_SPLIT @ 0x{:x}",
+ self.op.address
+ );
- Register::Temp(0)
- })
+ Register::Temp(0)
+ })
}
}
@@ -175,9 +192,6 @@ where
}
}
-
-
-
// LLIL_SET_FLAG, LLIL_SET_FLAG_SSA
pub struct SetFlag;
@@ -196,7 +210,6 @@ where
}
}
-
// LLIL_LOAD, LLIL_LOAD_SSA
pub struct Load;
@@ -219,8 +232,6 @@ where
}
}
-
-
// LLIL_STORE, LLIL_STORE_SSA
pub struct Store;
@@ -251,8 +262,6 @@ where
}
}
-
-
// LLIL_REG, LLIL_REG_SSA, LLIL_REG_SSA_PARTIAL
pub struct Reg;
@@ -272,31 +281,28 @@ where
if raw_id >= 0x8000_0000 {
Register::Temp(raw_id & 0x7fff_ffff)
} else {
- self.function.arch().register_from_id(raw_id)
- .map(Register::ArchReg)
- .unwrap_or_else(|| {
- error!("got garbage register from LLIL_REG @ 0x{:x}",
- self.op.address);
+ self.function
+ .arch()
+ .register_from_id(raw_id)
+ .map(Register::ArchReg)
+ .unwrap_or_else(|| {
+ error!(
+ "got garbage register from LLIL_REG @ 0x{:x}",
+ self.op.address
+ );
- Register::Temp(0)
- })
+ Register::Temp(0)
+ })
}
}
}
-
-
// LLIL_FLAG, LLIL_FLAG_SSA
pub struct Flag;
-
-
-
// LLIL_FLAG_BIT, LLIL_FLAG_BIT_SSA
pub struct FlagBit;
-
-
// LLIL_JUMP
pub struct Jump;
@@ -315,8 +321,6 @@ where
}
}
-
-
// LLIL_JUMP_TO
pub struct JumpTo;
@@ -336,8 +340,6 @@ where
// TODO target list
}
-
-
// LLIL_CALL, LLIL_CALL_SSA
pub struct Call;
@@ -366,8 +368,6 @@ where
}
}
-
-
// LLIL_RET
pub struct Ret;
@@ -386,8 +386,6 @@ where
}
}
-
-
// LLIL_IF
pub struct If;
@@ -420,8 +418,6 @@ where
}
}
-
-
// LLIL_GOTO
pub struct Goto;
@@ -439,13 +435,9 @@ where
}
}
-
-
// LLIL_FLAG_COND
pub struct FlagCond;
-
-
// LLIL_FLAG_GROUP
pub struct FlagGroup;
@@ -460,8 +452,6 @@ where
}
}
-
-
// LLIL_TRAP
pub struct Trap;
@@ -476,23 +466,15 @@ where
}
}
-
-
// LLIL_REG_PHI
pub struct RegPhi;
-
-
// LLIL_FLAG_PHI
pub struct FlagPhi;
-
-
// LLIL_MEM_PHI
pub struct MemPhi;
-
-
// LLIL_CONST, LLIL_CONST_PTR
pub struct Const;
@@ -517,8 +499,10 @@ where
};
if !is_safe {
- error!("il expr @ {:x} contains constant 0x{:x} as {} byte value (doesn't fit!)",
- self.op.address, self.op.operands[0], self.op.size);
+ error!(
+ "il expr @ {:x} contains constant 0x{:x} as {} byte value (doesn't fit!)",
+ self.op.address, self.op.operands[0], self.op.size
+ );
}
}
@@ -533,8 +517,6 @@ where
}
}
-
-
// LLIL_ADD, LLIL_SUB, LLIL_AND, LLIL_OR
// LLIL_XOR, LLIL_LSL, LLIL_LSR, LLIL_ASR
// LLIL_ROL, LLIL_ROR, LLIL_MUL, LLIL_MULU_DP,
@@ -569,8 +551,6 @@ where
}
}
-
-
// LLIL_ADC, LLIL_SBB, LLIL_RLC, LLIL_RRC
pub struct BinaryOpCarry;
@@ -609,8 +589,6 @@ where
}
}
-
-
// LLIL_DIVS_DP, LLIL_DIVU_DP, LLIL_MODU_DP, LLIL_MODS_DP
pub struct DoublePrecDivOp;
@@ -649,8 +627,6 @@ where
}
}
-
-
// LLIL_PUSH, LLIL_NEG, LLIL_NOT, LLIL_SX,
// LLIL_ZX, LLIL_LOW_PART, LLIL_BOOL_TO_INT, LLIL_UNIMPL_MEM
pub struct UnaryOp;
@@ -674,8 +650,6 @@ where
}
}
-
-
// LLIL_CMP_X
pub struct Condition;
@@ -706,7 +680,6 @@ where
}
}
-
// LLIL_UNIMPL_MEM
pub struct UnimplMem;