summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-05-05 17:57:06 -0400
committerRusty Wagner <rusty@vector35.com>2017-05-05 17:57:06 -0400
commit7bc394fc4490920bac688234f5c4c23901ab84c7 (patch)
tree8ec639282eedc2bfebdb71e3fae1360963a70b01
parent7cc163fa72b3ea342a9b061ae8988887edbf198f (diff)
Adding carry flag operand to IL instructions that need it
-rw-r--r--binaryninjaapi.h9
-rw-r--r--lowlevelil.cpp29
-rw-r--r--python/lowlevelil.py36
3 files changed, 46 insertions, 28 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 068653b3..b5ca60b4 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2119,9 +2119,9 @@ namespace BinaryNinja
ExprId Flag(uint32_t reg);
ExprId FlagBit(size_t size, uint32_t flag, uint32_t bitIndex);
ExprId Add(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
- ExprId AddCarry(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
+ ExprId AddCarry(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags = 0);
ExprId Sub(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
- ExprId SubBorrow(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
+ ExprId SubBorrow(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags = 0);
ExprId And(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
ExprId Or(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
ExprId Xor(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
@@ -2129,9 +2129,9 @@ namespace BinaryNinja
ExprId LogicalShiftRight(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
ExprId ArithShiftRight(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
ExprId RotateLeft(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
- ExprId RotateLeftCarry(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
+ ExprId RotateLeftCarry(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags = 0);
ExprId RotateRight(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
- ExprId RotateRightCarry(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
+ ExprId RotateRightCarry(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags = 0);
ExprId Mult(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
ExprId MultDoublePrecUnsigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
ExprId MultDoublePrecSigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0);
@@ -2182,6 +2182,7 @@ namespace BinaryNinja
ExprId GetExprForRegisterOrConstant(const BNRegisterOrConstant& operand, size_t size);
ExprId GetNegExprForRegisterOrConstant(const BNRegisterOrConstant& operand, size_t size);
+ ExprId GetExprForFlagOrConstant(const BNRegisterOrConstant& operand);
ExprId GetExprForRegisterOrConstantOperation(BNLowLevelILOperation op, size_t size,
BNRegisterOrConstant* operands, size_t operandCount);
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index 875f0083..ffb447ab 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -170,9 +170,9 @@ ExprId LowLevelILFunction::Add(size_t size, ExprId a, ExprId b, uint32_t flags)
}
-ExprId LowLevelILFunction::AddCarry(size_t size, ExprId a, ExprId b, uint32_t flags)
+ExprId LowLevelILFunction::AddCarry(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags)
{
- return AddExpr(LLIL_ADC, size, flags, a, b);
+ return AddExpr(LLIL_ADC, size, flags, a, b, carry);
}
@@ -182,9 +182,9 @@ ExprId LowLevelILFunction::Sub(size_t size, ExprId a, ExprId b, uint32_t flags)
}
-ExprId LowLevelILFunction::SubBorrow(size_t size, ExprId a, ExprId b, uint32_t flags)
+ExprId LowLevelILFunction::SubBorrow(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags)
{
- return AddExpr(LLIL_SBB, size, flags, a, b);
+ return AddExpr(LLIL_SBB, size, flags, a, b, carry);
}
@@ -230,9 +230,9 @@ ExprId LowLevelILFunction::RotateLeft(size_t size, ExprId a, ExprId b, uint32_t
}
-ExprId LowLevelILFunction::RotateLeftCarry(size_t size, ExprId a, ExprId b, uint32_t flags)
+ExprId LowLevelILFunction::RotateLeftCarry(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags)
{
- return AddExpr(LLIL_RLC, size, flags, a, b);
+ return AddExpr(LLIL_RLC, size, flags, a, b, carry);
}
@@ -242,9 +242,9 @@ ExprId LowLevelILFunction::RotateRight(size_t size, ExprId a, ExprId b, uint32_t
}
-ExprId LowLevelILFunction::RotateRightCarry(size_t size, ExprId a, ExprId b, uint32_t flags)
+ExprId LowLevelILFunction::RotateRightCarry(size_t size, ExprId a, ExprId b, ExprId carry, uint32_t flags)
{
- return AddExpr(LLIL_RRC, size, flags, a, b);
+ return AddExpr(LLIL_RRC, size, flags, a, b, carry);
}
@@ -550,6 +550,14 @@ ExprId LowLevelILFunction::GetNegExprForRegisterOrConstant(const BNRegisterOrCon
}
+ExprId LowLevelILFunction::GetExprForFlagOrConstant(const BNRegisterOrConstant& operand)
+{
+ if (operand.constant)
+ return AddExpr(LLIL_CONST, 0, 0, operand.value);
+ return AddExpr(LLIL_FLAG, 0, 0, operand.reg);
+}
+
+
ExprId LowLevelILFunction::GetExprForRegisterOrConstantOperation(BNLowLevelILOperation op, size_t size,
BNRegisterOrConstant* operands, size_t operandCount)
{
@@ -564,6 +572,11 @@ ExprId LowLevelILFunction::GetExprForRegisterOrConstantOperation(BNLowLevelILOpe
}
if (operandCount == 3)
{
+ if ((op == LLIL_ADC) || (op == LLIL_SBB) || (op == LLIL_RLC) || (op == LLIL_RRC))
+ {
+ return AddExpr(op, size, 0, GetExprForRegisterOrConstant(operands[0], size),
+ GetExprForRegisterOrConstant(operands[1], size), GetExprForFlagOrConstant(operands[2]));
+ }
return AddExpr(op, size, 0, GetExprForRegisterOrConstant(operands[0], size),
GetExprForRegisterOrConstant(operands[1], size), GetExprForRegisterOrConstant(operands[2], size));
}
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index fd713b44..cb4c9b69 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -125,9 +125,9 @@ class LowLevelILInstruction(object):
LowLevelILOperation.LLIL_FLAG: [("src", "flag")],
LowLevelILOperation.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")],
LowLevelILOperation.LLIL_ADD: [("left", "expr"), ("right", "expr")],
- LowLevelILOperation.LLIL_ADC: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_ADC: [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_SUB: [("left", "expr"), ("right", "expr")],
- LowLevelILOperation.LLIL_SBB: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_SBB: [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_AND: [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_OR: [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_XOR: [("left", "expr"), ("right", "expr")],
@@ -135,9 +135,9 @@ class LowLevelILInstruction(object):
LowLevelILOperation.LLIL_LSR: [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_ASR: [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_ROL: [("left", "expr"), ("right", "expr")],
- LowLevelILOperation.LLIL_RLC: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_RLC: [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_ROR: [("left", "expr"), ("right", "expr")],
- LowLevelILOperation.LLIL_RRC: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_RRC: [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_MUL: [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MULU_DP: [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")],
@@ -809,7 +809,7 @@ class LowLevelILFunction(object):
"""
return self.expr(LowLevelILOperation.LLIL_ADD, a.index, b.index, size=size, flags=flags)
- def add_carry(self, size, a, b, flags=None):
+ def add_carry(self, size, a, b, carry, flags=None):
"""
``add_carry`` adds with carry expression ``a`` to expression ``b`` potentially setting flags ``flags`` and
returning an expression of ``size`` bytes.
@@ -817,11 +817,12 @@ class LowLevelILFunction(object):
:param int size: the size of the result in bytes
:param LowLevelILExpr a: LHS expression
:param LowLevelILExpr b: RHS expression
+ :param LowLevelILExpr carry: Carry flag expression
:param str flags: flags to set
- :return: The expression ``adc.<size>{<flags>}(a, b)``
+ :return: The expression ``adc.<size>{<flags>}(a, b, carry)``
:rtype: LowLevelILExpr
"""
- return self.expr(LowLevelILOperation.LLIL_ADC, a.index, b.index, size=size, flags=flags)
+ return self.expr(LowLevelILOperation.LLIL_ADC, a.index, b.index, carry.index, size=size, flags=flags)
def sub(self, size, a, b, flags=None):
"""
@@ -837,7 +838,7 @@ class LowLevelILFunction(object):
"""
return self.expr(LowLevelILOperation.LLIL_SUB, a.index, b.index, size=size, flags=flags)
- def sub_borrow(self, size, a, b, flags=None):
+ def sub_borrow(self, size, a, b, carry, flags=None):
"""
``sub_borrow`` subtracts with borrow expression ``b`` from expression ``a`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
@@ -845,11 +846,12 @@ class LowLevelILFunction(object):
:param int size: the size of the result in bytes
:param LowLevelILExpr a: LHS expression
:param LowLevelILExpr b: RHS expression
+ :param LowLevelILExpr carry: Carry flag expression
:param str flags: flags to set
- :return: The expression ``sbc.<size>{<flags>}(a, b)``
+ :return: The expression ``sbb.<size>{<flags>}(a, b, carry)``
:rtype: LowLevelILExpr
"""
- return self.expr(LowLevelILOperation.LLIL_SBB, a.index, b.index, size=size, flags=flags)
+ return self.expr(LowLevelILOperation.LLIL_SBB, a.index, b.index, carry.index, size=size, flags=flags)
def and_expr(self, size, a, b, flags=None):
"""
@@ -949,7 +951,7 @@ class LowLevelILFunction(object):
"""
return self.expr(LowLevelILOperation.LLIL_ROL, a.index, b.index, size=size, flags=flags)
- def rotate_left_carry(self, size, a, b, flags=None):
+ def rotate_left_carry(self, size, a, b, carry, flags=None):
"""
``rotate_left_carry`` bitwise rotates left with carry expression ``a`` by expression ``b`` potentially setting
flags ``flags`` and returning an expression of ``size`` bytes.
@@ -957,11 +959,12 @@ class LowLevelILFunction(object):
:param int size: the size of the result in bytes
:param LowLevelILExpr a: LHS expression
:param LowLevelILExpr b: RHS expression
+ :param LowLevelILExpr carry: Carry flag expression
:param str flags: optional, flags to set
- :return: The expression ``rcl.<size>{<flags>}(a, b)``
+ :return: The expression ``rlc.<size>{<flags>}(a, b, carry)``
:rtype: LowLevelILExpr
"""
- return self.expr(LowLevelILOperation.LLIL_RLC, a.index, b.index, size=size, flags=flags)
+ return self.expr(LowLevelILOperation.LLIL_RLC, a.index, b.index, carry.index, size=size, flags=flags)
def rotate_right(self, size, a, b, flags=None):
"""
@@ -977,7 +980,7 @@ class LowLevelILFunction(object):
"""
return self.expr(LowLevelILOperation.LLIL_ROR, a.index, b.index, size=size, flags=flags)
- def rotate_right_carry(self, size, a, b, flags=None):
+ def rotate_right_carry(self, size, a, b, carry, flags=None):
"""
``rotate_right_carry`` bitwise rotates right with carry expression ``a`` by expression ``b`` potentially setting
flags ``flags`` and returning an expression of ``size`` bytes.
@@ -985,11 +988,12 @@ class LowLevelILFunction(object):
:param int size: the size of the result in bytes
:param LowLevelILExpr a: LHS expression
:param LowLevelILExpr b: RHS expression
+ :param LowLevelILExpr carry: Carry flag expression
:param str flags: optional, flags to set
- :return: The expression ``rcr.<size>{<flags>}(a, b)``
+ :return: The expression ``rrc.<size>{<flags>}(a, b, carry)``
:rtype: LowLevelILExpr
"""
- return self.expr(LowLevelILOperation.LLIL_RRC, a.index, b.index, size=size, flags=flags)
+ return self.expr(LowLevelILOperation.LLIL_RRC, a.index, b.index, carry.index, size=size, flags=flags)
def mult(self, size, a, b, flags=None):
"""