summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h5
-rw-r--r--binaryninjacore.h3
-rw-r--r--highlevelilinstruction.cpp75
-rw-r--r--highlevelilinstruction.h18
-rw-r--r--python/highlevelil.py3
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")],