From a77b7ddc28706da689727a82f5a67ae1e9c61693 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 9 Feb 2018 17:17:53 -0500 Subject: Add instructions for tracking freed register stack slots --- binaryninjaapi.h | 10 ++++++++ binaryninjacore.h | 6 +++++ lowlevelilinstruction.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++ lowlevelilinstruction.h | 27 ++++++++++++++++++++ mediumlevelilinstruction.cpp | 21 ++++++++++++++++ mediumlevelilinstruction.h | 12 +++++++++ python/lowlevelil.py | 4 +++ python/mediumlevelil.py | 2 ++ 8 files changed, 141 insertions(+) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 27ac4dc1..91162af7 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2579,10 +2579,17 @@ namespace BinaryNinja const ILSourceLocation& loc = ILSourceLocation()); ExprId RegisterStackPop(size_t size, uint32_t regStack, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + ExprId RegisterStackFreeReg(uint32_t reg, const ILSourceLocation& loc = ILSourceLocation()); + ExprId RegisterStackFreeTopRelative(uint32_t regStack, ExprId entry, + const ILSourceLocation& loc = ILSourceLocation()); ExprId RegisterStackTopRelativeSSA(size_t size, const SSARegisterStack& regStack, ExprId entry, const SSARegister& top, const ILSourceLocation& loc = ILSourceLocation()); ExprId RegisterStackAbsoluteSSA(size_t size, const SSARegisterStack& regStack, uint32_t reg, const ILSourceLocation& loc = ILSourceLocation()); + ExprId RegisterStackFreeTopRelativeSSA(uint32_t regStack, size_t destVersion, size_t srcVersion, + ExprId entry, const SSARegister& top, const ILSourceLocation& loc = ILSourceLocation()); + ExprId RegisterStackFreeAbsoluteSSA(uint32_t regStack, size_t destVersion, size_t srcVersion, + uint32_t reg, const ILSourceLocation& loc = ILSourceLocation()); ExprId Const(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation()); ExprId ConstPointer(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatConstRaw(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation()); @@ -3020,6 +3027,9 @@ namespace BinaryNinja const std::vector& params, const ILSourceLocation& loc = ILSourceLocation()); ExprId IntrinsicSSA(const std::vector& outputs, uint32_t intrinsic, const std::vector& params, const ILSourceLocation& loc = ILSourceLocation()); + ExprId FreeVarSlot(const Variable& var, const ILSourceLocation& loc = ILSourceLocation()); + ExprId FreeVarSlotSSA(const Variable& var, size_t newVersion, size_t prevVersion, + const ILSourceLocation& loc = ILSourceLocation()); ExprId Undefined(const ILSourceLocation& loc = ILSourceLocation()); ExprId Unimplemented(const ILSourceLocation& loc = ILSourceLocation()); ExprId UnimplementedMemoryRef(size_t size, ExprId target, diff --git a/binaryninjacore.h b/binaryninjacore.h index f3457dea..fa7a818a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -291,6 +291,8 @@ extern "C" LLIL_REG_SPLIT, // Not valid in SSA form (see LLIL_REG_SPLIT_SSA) LLIL_REG_STACK_REL, // Not valid in SSA form (see LLIL_REG_STACK_REL_SSA) LLIL_REG_STACK_POP, // Not valid in SSA form (expanded) + LLIL_REG_STACK_FREE_REG, // Not valid in SSA form (see LLIL_REG_STACK_FREE_REL_SSA, LLIL_REG_STACK_FREE_ABS_SSA) + LLIL_REG_STACK_FREE_REL, // Not valid in SSA from (see LLIL_REG_STACK_FREE_REL_SSA) LLIL_CONST, LLIL_CONST_PTR, LLIL_FLOAT_CONST, @@ -394,6 +396,8 @@ extern "C" LLIL_REG_SPLIT_SSA, LLIL_REG_STACK_REL_SSA, LLIL_REG_STACK_ABS_SSA, + LLIL_REG_STACK_FREE_REL_SSA, + LLIL_REG_STACK_FREE_ABS_SSA, LLIL_SET_FLAG_SSA, LLIL_FLAG_SSA, LLIL_FLAG_BIT_SSA, @@ -865,6 +869,7 @@ extern "C" MLIL_SYSCALL, // Not valid in SSA form (see MLIL_SYSCALL_SSA) MLIL_SYSCALL_UNTYPED, // Not valid in SSA form (see MLIL_SYSCALL_UNTYPED_SSA) MLIL_INTRINSIC, // Not valid in SSA form (see MLIL_INTRINSIC_SSA) + MLIL_FREE_VAR_SLOT, // Not valid in SSA from (see MLIL_FREE_VAR_SLOT_SSA) MLIL_BP, MLIL_TRAP, MLIL_UNDEF, @@ -917,6 +922,7 @@ extern "C" MLIL_STORE_SSA, MLIL_STORE_STRUCT_SSA, MLIL_INTRINSIC_SSA, + MLIL_FREE_VAR_SLOT_SSA, MLIL_VAR_PHI, MLIL_MEM_PHI }; diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index 71a645e6..8fb87a9e 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -129,9 +129,16 @@ unordered_map> {LLIL_REG_SPLIT_SSA, {HighSSARegisterLowLevelOperandUsage, LowSSARegisterLowLevelOperandUsage}}, {LLIL_REG_STACK_REL, {SourceRegisterStackLowLevelOperandUsage, SourceExprLowLevelOperandUsage}}, {LLIL_REG_STACK_POP, {SourceRegisterStackLowLevelOperandUsage}}, + {LLIL_REG_STACK_FREE_REG, {DestRegisterLowLevelOperandUsage}}, + {LLIL_REG_STACK_FREE_REL, {DestRegisterStackLowLevelOperandUsage, DestExprLowLevelOperandUsage}}, {LLIL_REG_STACK_REL_SSA, {SourceSSARegisterStackLowLevelOperandUsage, TopSSARegisterLowLevelOperandUsage, SourceExprLowLevelOperandUsage}}, {LLIL_REG_STACK_ABS_SSA, {SourceSSARegisterStackLowLevelOperandUsage, SourceRegisterLowLevelOperandUsage}}, + {LLIL_REG_STACK_FREE_REL_SSA, {DestSSARegisterStackLowLevelOperandUsage, + PartialSSARegisterStackSourceLowLevelOperandUsage, DestExprLowLevelOperandUsage, + TopSSARegisterLowLevelOperandUsage}}, + {LLIL_REG_STACK_FREE_ABS_SSA, {DestSSARegisterStackLowLevelOperandUsage, + PartialSSARegisterStackSourceLowLevelOperandUsage, DestRegisterLowLevelOperandUsage}}, {LLIL_FLAG, {SourceFlagLowLevelOperandUsage}}, {LLIL_FLAG_BIT, {SourceFlagLowLevelOperandUsage, BitIndexLowLevelOperandUsage}}, {LLIL_FLAG_SSA, {SourceSSAFlagLowLevelOperandUsage}}, @@ -1763,9 +1770,15 @@ void LowLevelILInstruction::VisitExprs(const std::function().VisitExprs(func); break; + case LLIL_REG_STACK_FREE_REL: + GetDestExpr().VisitExprs(func); + break; case LLIL_REG_STACK_REL_SSA: GetSourceExpr().VisitExprs(func); break; + case LLIL_REG_STACK_FREE_REL_SSA: + GetDestExpr().VisitExprs(func); + break; case LLIL_LOAD: GetSourceExpr().VisitExprs(func); break; @@ -1986,6 +1999,11 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, subExprHandler(GetSourceExpr()), *this); case LLIL_REG_STACK_POP: return dest->RegisterStackPop(size, GetSourceRegisterStack(), flags, *this); + case LLIL_REG_STACK_FREE_REG: + return dest->RegisterStackFreeReg(GetDestRegister(), *this); + case LLIL_REG_STACK_FREE_REL: + return dest->RegisterStackFreeTopRelative(GetDestRegisterStack(), + subExprHandler(GetDestExpr()), *this); case LLIL_REG_STACK_REL_SSA: return dest->RegisterStackTopRelativeSSA(size, GetSourceSSARegisterStack(), subExprHandler(GetSourceExpr()), @@ -1993,6 +2011,17 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, case LLIL_REG_STACK_ABS_SSA: return dest->RegisterStackAbsoluteSSA(size, GetSourceSSARegisterStack(), GetSourceRegister(), *this); + case LLIL_REG_STACK_FREE_REL_SSA: + return dest->RegisterStackFreeTopRelativeSSA(GetDestSSARegisterStack().regStack, + GetDestSSARegisterStack().version, + GetSourceSSARegisterStack().version, + subExprHandler(GetDestExpr()), + GetTopSSARegister(), *this); + case LLIL_REG_STACK_FREE_ABS_SSA: + return dest->RegisterStackFreeAbsoluteSSA(GetDestSSARegisterStack().regStack, + GetDestSSARegisterStack().version, + GetSourceSSARegisterStack().version, + GetDestRegister(), *this); case LLIL_FLAG: return dest->Flag(GetSourceFlag(), *this); case LLIL_FLAG_SSA: @@ -2788,6 +2817,18 @@ ExprId LowLevelILFunction::RegisterStackPop(size_t size, uint32_t regStack, uint } +ExprId LowLevelILFunction::RegisterStackFreeReg(uint32_t reg, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_REG_STACK_FREE_REG, loc, 0, 0, reg); +} + + +ExprId LowLevelILFunction::RegisterStackFreeTopRelative(uint32_t regStack, ExprId entry, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_REG_STACK_FREE_REG, loc, 0, 0, regStack, entry); +} + + ExprId LowLevelILFunction::RegisterStackTopRelativeSSA(size_t size, const SSARegisterStack& regStack, ExprId entry, const SSARegister& top, const ILSourceLocation& loc) { @@ -2803,6 +2844,24 @@ ExprId LowLevelILFunction::RegisterStackAbsoluteSSA(size_t size, const SSARegist } +ExprId LowLevelILFunction::RegisterStackFreeTopRelativeSSA(uint32_t regStack, + size_t destVersion, size_t srcVersion, ExprId entry, const SSARegister& top, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_REG_STACK_FREE_REL_SSA, loc, 0, 0, + AddExprWithLocation(LLIL_REG_STACK_DEST_SSA, loc, 0, 0, regStack, destVersion, srcVersion), + entry, AddExprWithLocation(LLIL_REG_SSA, loc, 0, 0, top.reg, top.version)); +} + + +ExprId LowLevelILFunction::RegisterStackFreeAbsoluteSSA(uint32_t regStack, + size_t destVersion, size_t srcVersion, uint32_t reg, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_REG_STACK_FREE_ABS_SSA, loc, 0, 0, + AddExprWithLocation(LLIL_REG_STACK_DEST_SSA, loc, 0, 0, regStack, destVersion, srcVersion), reg); +} + + ExprId LowLevelILFunction::Const(size_t size, uint64_t val, const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_CONST, loc, size, 0, val); diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index 3cd1c8f4..675baa3c 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -1013,6 +1013,15 @@ namespace BinaryNinja { uint32_t GetSourceRegisterStack() const { return GetRawOperandAsRegister(0); } }; + template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase + { + uint32_t GetDestRegister() const { return GetRawOperandAsRegister(0); } + }; + template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase + { + uint32_t GetDestRegisterStack() const { return GetRawOperandAsRegister(0); } + LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } + }; template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase { SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsSSARegisterStack(0); } @@ -1027,6 +1036,24 @@ namespace BinaryNinja uint32_t GetSourceRegister() const { return GetRawOperandAsRegister(2); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; + template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase + { + SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterStack(0); } + SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsPartialSSARegisterStackSource(0); } + LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } + SSARegister GetTopSSARegister() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSARegister(0); } + void SetDestSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } + void SetSourceSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(2, version); } + void SetTopSSAVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(1, version); } + }; + template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase + { + SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterStack(0); } + SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsPartialSSARegisterStackSource(0); } + uint32_t GetDestRegister() const { return GetRawOperandAsRegister(1); } + void SetDestSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } + void SetSourceSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(2, version); } + }; template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase { uint32_t GetSourceFlag() const { return GetRawOperandAsRegister(0); } diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index e281a4c3..586eb470 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -150,6 +150,8 @@ unordered_map> ParameterExprsMediumLevelOperandUsage}}, {MLIL_INTRINSIC_SSA, {OutputSSAVariablesMediumLevelOperandUsage, IntrinsicMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}}, + {MLIL_FREE_VAR_SLOT, {DestVariableMediumLevelOperandUsage}}, + {MLIL_FREE_VAR_SLOT_SSA, {DestSSAVariableMediumLevelOperandUsage, PartialSSAVariableSourceMediumLevelOperandUsage}}, {MLIL_TRAP, {VectorMediumLevelOperandUsage}}, {MLIL_VAR_PHI, {DestSSAVariableMediumLevelOperandUsage, SourceSSAVariablesMediumLevelOperandUsages}}, {MLIL_MEM_PHI, {DestMemoryVersionMediumLevelOperandUsage, SourceMemoryVersionsMediumLevelOperandUsage}}, @@ -1653,6 +1655,12 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest, params.push_back(subExprHandler(i)); return dest->IntrinsicSSA(GetOutputSSAVariables(), GetIntrinsic(), params, *this); + case MLIL_FREE_VAR_SLOT: + return dest->FreeVarSlot(GetDestVariable(), *this); + case MLIL_FREE_VAR_SLOT_SSA: + return dest->FreeVarSlotSSA(GetDestSSAVariable().var, + GetDestSSAVariable().version, + GetSourceSSAVariable().version, *this); case MLIL_UNDEF: return dest->Undefined(*this); case MLIL_UNIMPL: @@ -2648,6 +2656,19 @@ ExprId MediumLevelILFunction::IntrinsicSSA(const vector& outputs, u } +ExprId MediumLevelILFunction::FreeVarSlot(const Variable& var, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_FREE_VAR_SLOT, loc, 0, var.ToIdentifier()); +} + + +ExprId MediumLevelILFunction::FreeVarSlotSSA(const Variable& var, size_t newVersion, size_t prevVersion, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_FREE_VAR_SLOT_SSA, loc, 0, var.ToIdentifier(), newVersion, prevVersion); +} + + ExprId MediumLevelILFunction::Undefined(const ILSourceLocation& loc) { return AddExprWithLocation(MLIL_UNDEF, loc, 0); diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h index cdda87f5..a0c4fd9b 100644 --- a/mediumlevelilinstruction.h +++ b/mediumlevelilinstruction.h @@ -922,6 +922,18 @@ namespace BinaryNinja void SetOutputSSAVariables(const std::vector& vars) { UpdateRawOperandAsSSAVariableList(0, vars); } }; + template <> struct MediumLevelILInstructionAccessor: public MediumLevelILInstructionBase + { + Variable GetDestVariable() const { return GetRawOperandAsVariable(0); } + }; + template <> struct MediumLevelILInstructionAccessor: public MediumLevelILInstructionBase + { + SSAVariable GetDestSSAVariable() const { return GetRawOperandAsSSAVariable(0); } + SSAVariable GetSourceSSAVariable() const { return GetRawOperandAsPartialSSAVariableSource(0); } + void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } + void SetSourceSSAVersion(size_t version) { UpdateRawOperand(2, version); } + }; + template <> struct MediumLevelILInstructionAccessor: public MediumLevelILInstructionBase { int64_t GetVector() const { return GetRawOperandAsInteger(0); } diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 8a132478..e64e20fd 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -219,6 +219,8 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_REG_SPLIT: [("hi", "reg"), ("lo", "reg")], LowLevelILOperation.LLIL_REG_STACK_REL: [("stack", "reg_stack"), ("src", "expr")], LowLevelILOperation.LLIL_REG_STACK_POP: [("stack", "reg_stack")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REG: [("dest", "reg")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REL: [("stack", "reg_stack"), ("dest", "expr")], LowLevelILOperation.LLIL_CONST: [("constant", "int")], LowLevelILOperation.LLIL_CONST_PTR: [("constant", "int")], LowLevelILOperation.LLIL_FLOAT_CONST: [("constant", "float")], @@ -319,6 +321,8 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_REG_SPLIT_SSA: [("hi", "reg_ssa"), ("lo", "reg_ssa")], LowLevelILOperation.LLIL_REG_STACK_REL_SSA: [("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")], LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: [("stack", "reg_stack_ssa"), ("src", "reg")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REL_SSA: [("stack", "expr"), ("dest", "expr"), ("top", "expr")], + LowLevelILOperation.LLIL_REG_STACK_FREE_ABS_SSA: [("stack", "expr"), ("dest", "reg")], LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag_ssa"), ("src", "expr")], LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag_ssa")], LowLevelILOperation.LLIL_FLAG_BIT_SSA: [("src", "flag_ssa"), ("bit", "int")], diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index a842c3c4..caf19e8e 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -152,6 +152,8 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], MediumLevelILOperation.MLIL_INTRINSIC: [("output", "var_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], MediumLevelILOperation.MLIL_INTRINSIC_SSA: [("output", "var_ssa_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], + MediumLevelILOperation.MLIL_FREE_VAR_SLOT: [("dest", "var")], + MediumLevelILOperation.MLIL_FREE_VAR_SLOT_SSA: [("prev", "var_ssa_dest_and_src")], MediumLevelILOperation.MLIL_UNDEF: [], MediumLevelILOperation.MLIL_UNIMPL: [], MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")], -- cgit v1.3.1