diff options
| -rw-r--r-- | binaryninjaapi.h | 5 | ||||
| -rw-r--r-- | binaryninjacore.h | 3 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 75 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 18 | ||||
| -rw-r--r-- | python/highlevelil.py | 3 |
5 files changed, 102 insertions, 2 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index ea74a466..4339ad6f 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -4066,6 +4066,11 @@ __attribute__ ((format (printf, 1, 2))) ExprId NoReturn(const ILSourceLocation& loc = ILSourceLocation()); ExprId Goto(size_t target, const ILSourceLocation& loc = ILSourceLocation()); ExprId Label(size_t target, const ILSourceLocation& loc = ILSourceLocation()); + ExprId VarDeclare(const Variable& var, const ILSourceLocation& loc = ILSourceLocation()); + ExprId VarInit(size_t size, const Variable& dest, ExprId src, + const ILSourceLocation& loc = ILSourceLocation()); + ExprId VarInitSSA(size_t size, const SSAVariable& dest, ExprId src, + const ILSourceLocation& loc = ILSourceLocation()); ExprId Assign(size_t size, ExprId dest, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId AssignUnpack(const std::vector<ExprId>& output, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); diff --git a/binaryninjacore.h b/binaryninjacore.h index 4e0fde4e..3ee4cc69 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1065,6 +1065,8 @@ extern "C" HLIL_GOTO, HLIL_LABEL, + HLIL_VAR_DECLARE, + HLIL_VAR_INIT, HLIL_ASSIGN, HLIL_ASSIGN_UNPACK, HLIL_VAR, @@ -1157,6 +1159,7 @@ extern "C" HLIL_FCMP_UO, // The following instructions are only used in SSA form + HLIL_VAR_INIT_SSA, HLIL_ASSIGN_MEM_SSA, HLIL_ASSIGN_UNPACK_MEM_SSA, HLIL_VAR_SSA, diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 65b51ac4..609b7f77 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -37,6 +37,7 @@ unordered_map<HighLevelILOperandUsage, HighLevelILOperandType> HighLevelILInstructionBase::operandTypeForUsage = { {SourceExprHighLevelOperandUsage, ExprHighLevelOperand}, {VariableHighLevelOperandUsage, VariableHighLevelOperand}, + {DestVariableHighLevelOperandUsage, VariableHighLevelOperand}, {SSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperand}, {DestSSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperand}, {DestExprHighLevelOperandUsage, ExprHighLevelOperand}, @@ -95,6 +96,9 @@ unordered_map<BNHighLevelILOperation, vector<HighLevelILOperandUsage>> {HLIL_RET, {SourceExprsHighLevelOperandUsage}}, {HLIL_GOTO, {TargetHighLevelOperandUsage}}, {HLIL_LABEL, {TargetHighLevelOperandUsage}}, + {HLIL_VAR_DECLARE, {VariableHighLevelOperandUsage}}, + {HLIL_VAR_INIT, {DestVariableHighLevelOperandUsage, SourceExprHighLevelOperandUsage}}, + {HLIL_VAR_INIT_SSA, {DestSSAVariableHighLevelOperandUsage, SourceExprHighLevelOperandUsage}}, {HLIL_ASSIGN, {DestExprHighLevelOperandUsage, SourceExprHighLevelOperandUsage}}, {HLIL_ASSIGN_UNPACK, {DestExprsHighLevelOperandUsage, SourceExprHighLevelOperandUsage}}, {HLIL_ASSIGN_MEM_SSA, {DestExprHighLevelOperandUsage, DestMemoryVersionHighLevelOperandUsage, @@ -912,6 +916,12 @@ void HighLevelILInstruction::VisitExprs(const std::function<bool(const HighLevel for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) toProcess.push(i->exprIndex); break; + case HLIL_VAR_INIT: + toProcess.push(cur.GetSourceExpr<HLIL_VAR_INIT>().exprIndex); + break; + case HLIL_VAR_INIT_SSA: + toProcess.push(cur.GetSourceExpr<HLIL_VAR_INIT_SSA>().exprIndex); + break; case HLIL_ASSIGN: toProcess.push(cur.GetSourceExpr<HLIL_ASSIGN>().exprIndex); toProcess.push(cur.GetDestExpr<HLIL_ASSIGN>().exprIndex); @@ -1111,8 +1121,8 @@ ExprId HighLevelILInstruction::CopyTo(HighLevelILFunction* dest, return dest->While(subExprHandler(GetConditionExpr<HLIL_WHILE>()), subExprHandler(GetLoopExpr<HLIL_WHILE>()), *this); case HLIL_DO_WHILE: - return dest->DoWhile(subExprHandler(GetLoopExpr<HLIL_WHILE>()), - subExprHandler(GetConditionExpr<HLIL_WHILE>()), *this); + return dest->DoWhile(subExprHandler(GetLoopExpr<HLIL_DO_WHILE>()), + subExprHandler(GetConditionExpr<HLIL_DO_WHILE>()), *this); case HLIL_FOR: return dest->For(subExprHandler(GetInitExpr<HLIL_FOR>()), subExprHandler(GetConditionExpr<HLIL_FOR>()), subExprHandler(GetUpdateExpr<HLIL_FOR>()), @@ -1130,6 +1140,18 @@ ExprId HighLevelILInstruction::CopyTo(HighLevelILFunction* dest, return dest->Break(*this); case HLIL_CONTINUE: return dest->Continue(*this); + case HLIL_GOTO: + return dest->Goto(GetTarget<HLIL_GOTO>(), *this); + case HLIL_LABEL: + return dest->Label(GetTarget<HLIL_LABEL>(), *this); + case HLIL_VAR_DECLARE: + return dest->VarDeclare(GetVariable<HLIL_VAR_DECLARE>(), *this); + case HLIL_VAR_INIT: + return dest->VarInit(size, GetDestVariable<HLIL_VAR_INIT>(), + subExprHandler(GetSourceExpr<HLIL_VAR_INIT>()), *this); + case HLIL_VAR_INIT_SSA: + return dest->VarInitSSA(size, GetDestSSAVariable<HLIL_VAR_INIT_SSA>(), + subExprHandler(GetSourceExpr<HLIL_VAR_INIT_SSA>()), *this); case HLIL_ASSIGN: return dest->Assign(size, subExprHandler(GetDestExpr<HLIL_ASSIGN>()), subExprHandler(GetSourceExpr<HLIL_ASSIGN>()), *this); @@ -1409,6 +1431,28 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons return GetTarget<HLIL_GOTO>() < other.GetTarget<HLIL_GOTO>(); case HLIL_LABEL: return GetTarget<HLIL_LABEL>() < other.GetTarget<HLIL_LABEL>(); + case HLIL_VAR_DECLARE: + return GetVariable<HLIL_VAR_DECLARE>() < other.GetVariable<HLIL_VAR_DECLARE>(); + case HLIL_VAR_INIT: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetDestVariable<HLIL_VAR_INIT>() < other.GetDestVariable<HLIL_VAR_INIT>()) + return true; + if (other.GetDestVariable<HLIL_VAR_INIT>() < GetDestVariable<HLIL_VAR_INIT>()) + return false; + return GetSourceExpr<HLIL_VAR_INIT>() < other.GetSourceExpr<HLIL_VAR_INIT>(); + case HLIL_VAR_INIT_SSA: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetDestSSAVariable<HLIL_VAR_INIT_SSA>() < other.GetDestSSAVariable<HLIL_VAR_INIT_SSA>()) + return true; + if (other.GetDestSSAVariable<HLIL_VAR_INIT_SSA>() < GetDestSSAVariable<HLIL_VAR_INIT_SSA>()) + return false; + return GetSourceExpr<HLIL_VAR_INIT_SSA>() < other.GetSourceExpr<HLIL_VAR_INIT_SSA>(); case HLIL_ASSIGN: if (size < other.size) return true; @@ -1821,6 +1865,15 @@ Variable HighLevelILInstruction::GetVariable() const } +Variable HighLevelILInstruction::GetDestVariable() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(DestVariableHighLevelOperandUsage, operandIndex)) + return GetRawOperandAsVariable(operandIndex); + throw HighLevelILInstructionAccessException(); +} + + SSAVariable HighLevelILInstruction::GetSSAVariable() const { size_t operandIndex; @@ -2203,6 +2256,24 @@ ExprId HighLevelILFunction::Label(size_t target, const ILSourceLocation& loc) } +ExprId HighLevelILFunction::VarDeclare(const Variable& var, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_VAR_DECLARE, loc, 0, var.ToIdentifier()); +} + + +ExprId HighLevelILFunction::VarInit(size_t size, const Variable& dest, ExprId src, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_VAR_INIT, loc, size, dest.ToIdentifier(), src); +} + + +ExprId HighLevelILFunction::VarInitSSA(size_t size, const SSAVariable& dest, ExprId src, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_VAR_INIT_SSA, loc, size, dest.var.ToIdentifier(), dest.version, src); +} + + ExprId HighLevelILFunction::Assign(size_t size, ExprId dest, ExprId src, const ILSourceLocation& loc) { return AddExprWithLocation(HLIL_ASSIGN, loc, size, dest, src); diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index cfc917e8..967bafec 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -68,6 +68,7 @@ namespace BinaryNinja { SourceExprHighLevelOperandUsage, VariableHighLevelOperandUsage, + DestVariableHighLevelOperandUsage, SSAVariableHighLevelOperandUsage, DestSSAVariableHighLevelOperandUsage, DestExprHighLevelOperandUsage, @@ -374,6 +375,7 @@ namespace BinaryNinja // Templated accessors for instruction operands, use these for efficient access to a known instruction template <BNHighLevelILOperation N> HighLevelILInstruction GetSourceExpr() const { return As<N>().GetSourceExpr(); } template <BNHighLevelILOperation N> Variable GetVariable() const { return As<N>().GetVariable(); } + template <BNHighLevelILOperation N> Variable GetDestVariable() const { return As<N>().GetDestVariable(); } template <BNHighLevelILOperation N> SSAVariable GetSSAVariable() const { return As<N>().GetSSAVariable(); } template <BNHighLevelILOperation N> SSAVariable GetDestSSAVariable() const { return As<N>().GetDestSSAVariable(); } template <BNHighLevelILOperation N> HighLevelILInstruction GetDestExpr() const { return As<N>().GetDestExpr(); } @@ -428,6 +430,7 @@ namespace BinaryNinja // on type mismatch. These are slower than the templated versions above. HighLevelILInstruction GetSourceExpr() const; Variable GetVariable() const; + Variable GetDestVariable() const; SSAVariable GetSSAVariable() const; SSAVariable GetDestSSAVariable() const; HighLevelILInstruction GetDestExpr() const; @@ -598,6 +601,21 @@ namespace BinaryNinja void SetSourceExprs(const std::vector<ExprId>& exprs) { UpdateRawOperandAsExprList(0, exprs); } }; + template <> struct HighLevelILInstructionAccessor<HLIL_VAR_DECLARE>: public HighLevelILInstructionBase + { + Variable GetVariable() const { return GetRawOperandAsVariable(0); } + }; + template <> struct HighLevelILInstructionAccessor<HLIL_VAR_INIT>: public HighLevelILInstructionBase + { + Variable GetDestVariable() const { return GetRawOperandAsVariable(0); } + HighLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } + }; + template <> struct HighLevelILInstructionAccessor<HLIL_VAR_INIT_SSA>: public HighLevelILInstructionBase + { + SSAVariable GetDestSSAVariable() const { return GetRawOperandAsSSAVariable(0); } + void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } + HighLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } + }; template <> struct HighLevelILInstructionAccessor<HLIL_ASSIGN>: public HighLevelILInstructionBase { HighLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } diff --git a/python/highlevelil.py b/python/highlevelil.py index 505b2b97..b31bc0cc 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -94,6 +94,9 @@ class HighLevelILInstruction(object): HighLevelILOperation.HLIL_NORET: [], HighLevelILOperation.HLIL_GOTO: [("target", "int")], HighLevelILOperation.HLIL_LABEL: [("target", "int")], + HighLevelILOperation.HLIL_VAR_DECLARE: [("var", "var")], + HighLevelILOperation.HLIL_VAR_INIT: [("dest", "var"), ("src", "expr")], + HighLevelILOperation.HLIL_VAR_INIT_SSA: [("dest", "var_ssa"), ("src", "expr")], HighLevelILOperation.HLIL_ASSIGN: [("dest", "expr"), ("src", "expr")], HighLevelILOperation.HLIL_ASSIGN_UNPACK: [("dest", "expr_list"), ("src", "expr")], HighLevelILOperation.HLIL_ASSIGN_MEM_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src", "expr"), ("src_memory", "int")], |
