diff options
| author | KyleMiles <krm504@nyu.edu> | 2021-01-21 18:35:20 +0000 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2021-01-21 19:07:07 +0000 |
| commit | 2fcacc55d5466a7d17bdc0b3ce988772aa6d0653 (patch) | |
| tree | 9d0f2ba19117843575936f2b93e0b6a578a84dc8 /rust/src/llil | |
| parent | a0da07c5c2860a5bd69921d38e438bbc1d43912f (diff) | |
cargo fmt and all my changes
Diffstat (limited to 'rust/src/llil')
| -rw-r--r-- | rust/src/llil/block.rs | 24 | ||||
| -rw-r--r-- | rust/src/llil/expression.rs | 391 | ||||
| -rw-r--r-- | rust/src/llil/function.rs | 32 | ||||
| -rw-r--r-- | rust/src/llil/instruction.rs | 45 | ||||
| -rw-r--r-- | rust/src/llil/lifting.rs | 638 | ||||
| -rw-r--r-- | rust/src/llil/mod.rs | 36 | ||||
| -rw-r--r-- | rust/src/llil/operation.rs | 153 |
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; |
