summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2019-08-03 22:40:57 -0400
committerRusty Wagner <rusty@vector35.com>2020-04-17 14:20:37 -0400
commit620dd96217a49803fe04c6bc286291ddd857dcba (patch)
treec416e88ecd9ac0d15e1864bbd17a6eb70548965f
parentc9845e5a200228f20809336d9e9afee45e776d19 (diff)
Expand support for HLIL switch/case and data flow access
-rw-r--r--binaryninjaapi.h3
-rw-r--r--highlevelilinstruction.cpp508
-rw-r--r--highlevelilinstruction.h16
-rw-r--r--lowlevelilinstruction.cpp4
-rw-r--r--lowlevelilinstruction.h3
-rw-r--r--mediumlevelilinstruction.cpp4
-rw-r--r--mediumlevelilinstruction.h3
-rw-r--r--python/function.py10
-rw-r--r--python/highlevelil.py32
9 files changed, 565 insertions, 18 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index eba63058..323431c9 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -4057,7 +4057,8 @@ __attribute__ ((format (printf, 1, 2)))
const ILSourceLocation& loc = ILSourceLocation());
ExprId Switch(ExprId condition, ExprId defaultExpr, const std::vector<ExprId>& cases,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId Case(ExprId condition, ExprId expr, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId Case(const std::vector<ExprId>& condition, ExprId expr,
+ const ILSourceLocation& loc = ILSourceLocation());
ExprId Break(const ILSourceLocation& loc = ILSourceLocation());
ExprId Continue(const ILSourceLocation& loc = ILSourceLocation());
ExprId Jump(ExprId dest, const ILSourceLocation& loc = ILSourceLocation());
diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp
index 801f5ec1..1468fa78 100644
--- a/highlevelilinstruction.cpp
+++ b/highlevelilinstruction.cpp
@@ -63,6 +63,7 @@ unordered_map<HighLevelILOperandUsage, HighLevelILOperandType>
{DestExprsHighLevelOperandUsage, ExprListHighLevelOperand},
{BlockExprsHighLevelOperandUsage, ExprListHighLevelOperand},
{CasesHighLevelOperandUsage, ExprListHighLevelOperand},
+ {ValueExprsHighLevelOperandUsage, ExprListHighLevelOperand},
{SourceSSAVariablesHighLevelOperandUsage, SSAVariableListHighLevelOperand},
{SourceMemoryVersionHighLevelOperandUsage, IndexHighLevelOperand},
{SourceMemoryVersionsHighLevelOperandUsage, IndexListHighLevelOperand},
@@ -88,7 +89,7 @@ unordered_map<BNHighLevelILOperation, vector<HighLevelILOperandUsage>>
UpdateExprHighLevelOperandUsage, LoopExprHighLevelOperandUsage}},
{HLIL_SWITCH, {ConditionExprHighLevelOperandUsage, DefaultExprHighLevelOperandUsage,
CasesHighLevelOperandUsage}},
- {HLIL_CASE, {ConditionExprHighLevelOperandUsage, TrueExprHighLevelOperandUsage}},
+ {HLIL_CASE, {ValueExprsHighLevelOperandUsage, TrueExprHighLevelOperandUsage}},
{HLIL_JUMP, {DestExprHighLevelOperandUsage}},
{HLIL_RET, {SourceExprsHighLevelOperandUsage}},
{HLIL_GOTO, {TargetHighLevelOperandUsage}},
@@ -778,6 +779,30 @@ void HighLevelILInstructionBase::UpdateRawOperandAsSSAVariableList(size_t operan
}
+RegisterValue HighLevelILInstructionBase::GetValue() const
+{
+ if (!HasMediumLevelIL())
+ return RegisterValue();
+ return GetMediumLevelILSSAForm().GetValue();
+}
+
+
+PossibleValueSet HighLevelILInstructionBase::GetPossibleValues(const set<BNDataFlowQueryOption>& options) const
+{
+ if (!HasMediumLevelIL())
+ return PossibleValueSet();
+ return GetMediumLevelILSSAForm().GetPossibleValues(options);
+}
+
+
+Confidence<Ref<Type>> HighLevelILInstructionBase::GetType() const
+{
+ if (!HasMediumLevelIL())
+ return nullptr;
+ return GetMediumLevelILSSAForm().GetType();
+}
+
+
size_t HighLevelILInstructionBase::GetMediumLevelILExprIndex() const
{
return function->GetMediumLevelILExprIndex(exprIndex);
@@ -882,7 +907,9 @@ void HighLevelILInstruction::VisitExprs(const std::function<bool(const HighLevel
break;
case HLIL_CASE:
toProcess.push(cur.GetTrueExpr<HLIL_CASE>().exprIndex);
- toProcess.push(cur.GetConditionExpr<HLIL_CASE>().exprIndex);
+ exprs = cur.GetValueExprs<HLIL_CASE>();
+ for (auto i = exprs.rbegin(); i != exprs.rend(); ++i)
+ toProcess.push(i->exprIndex);
break;
case HLIL_ASSIGN:
toProcess.push(cur.GetSourceExpr<HLIL_ASSIGN>().exprIndex);
@@ -1095,8 +1122,9 @@ ExprId HighLevelILInstruction::CopyTo(HighLevelILFunction* dest,
return dest->Switch(subExprHandler(GetConditionExpr<HLIL_SWITCH>()),
subExprHandler(GetDefaultExpr<HLIL_SWITCH>()), params, *this);
case HLIL_CASE:
- return dest->Case(subExprHandler(GetConditionExpr<HLIL_CASE>()),
- subExprHandler(GetTrueExpr<HLIL_CASE>()), *this);
+ for (auto& i : GetValueExprs<HLIL_CASE>())
+ params.push_back(subExprHandler(i));
+ return dest->Case(params, subExprHandler(GetTrueExpr<HLIL_CASE>()), *this);
case HLIL_BREAK:
return dest->Break(*this);
case HLIL_CONTINUE:
@@ -1289,6 +1317,465 @@ ExprId HighLevelILInstruction::CopyTo(HighLevelILFunction* dest,
}
+static bool CompareExprList(const HighLevelILInstructionList& a, const HighLevelILInstructionList& b)
+{
+ if (a.size() < b.size())
+ return true;
+ if (a.size() > b.size())
+ return false;
+ auto i = a.begin();
+ auto j = b.begin();
+ for (; i != a.end(); ++i, ++j)
+ {
+ if (*i < *j)
+ return true;
+ if (*j < *i)
+ return false;
+ }
+ return false;
+}
+
+
+bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) const
+{
+ if (operation < other.operation)
+ return true;
+ if (operation > other.operation)
+ return false;
+
+ switch (operation)
+ {
+ case HLIL_BLOCK:
+ return CompareExprList(GetBlockExprs<HLIL_BLOCK>(), other.GetBlockExprs<HLIL_BLOCK>());
+ case HLIL_IF:
+ if (GetConditionExpr<HLIL_IF>() < other.GetConditionExpr<HLIL_IF>())
+ return true;
+ if (other.GetConditionExpr<HLIL_IF>() < GetConditionExpr<HLIL_IF>())
+ return false;
+ if (GetTrueExpr<HLIL_IF>() < other.GetTrueExpr<HLIL_IF>())
+ return true;
+ if (other.GetTrueExpr<HLIL_IF>() < GetTrueExpr<HLIL_IF>())
+ return false;
+ return GetFalseExpr<HLIL_IF>() < other.GetFalseExpr<HLIL_IF>();
+ case HLIL_WHILE:
+ if (GetConditionExpr<HLIL_WHILE>() < other.GetConditionExpr<HLIL_WHILE>())
+ return true;
+ if (other.GetConditionExpr<HLIL_WHILE>() < GetConditionExpr<HLIL_WHILE>())
+ return false;
+ return GetLoopExpr<HLIL_WHILE>() < other.GetLoopExpr<HLIL_WHILE>();
+ case HLIL_DO_WHILE:
+ if (GetLoopExpr<HLIL_DO_WHILE>() < other.GetLoopExpr<HLIL_DO_WHILE>())
+ return true;
+ if (other.GetLoopExpr<HLIL_DO_WHILE>() < GetLoopExpr<HLIL_DO_WHILE>())
+ return false;
+ return GetConditionExpr<HLIL_DO_WHILE>() < other.GetConditionExpr<HLIL_DO_WHILE>();
+ case HLIL_FOR:
+ if (GetInitExpr<HLIL_FOR>() < other.GetInitExpr<HLIL_FOR>())
+ return true;
+ if (other.GetInitExpr<HLIL_FOR>() < GetInitExpr<HLIL_FOR>())
+ return false;
+ if (GetConditionExpr<HLIL_FOR>() < other.GetConditionExpr<HLIL_FOR>())
+ return true;
+ if (other.GetConditionExpr<HLIL_FOR>() < GetConditionExpr<HLIL_FOR>())
+ return false;
+ if (GetUpdateExpr<HLIL_FOR>() < other.GetUpdateExpr<HLIL_FOR>())
+ return true;
+ if (other.GetUpdateExpr<HLIL_FOR>() < GetUpdateExpr<HLIL_FOR>())
+ return false;
+ return GetLoopExpr<HLIL_FOR>() < other.GetLoopExpr<HLIL_FOR>();
+ case HLIL_SWITCH:
+ if (GetConditionExpr<HLIL_SWITCH>() < other.GetConditionExpr<HLIL_SWITCH>())
+ return true;
+ if (other.GetConditionExpr<HLIL_SWITCH>() < GetConditionExpr<HLIL_SWITCH>())
+ return false;
+ if (GetDefaultExpr<HLIL_SWITCH>() < other.GetDefaultExpr<HLIL_SWITCH>())
+ return true;
+ if (other.GetDefaultExpr<HLIL_SWITCH>() < GetDefaultExpr<HLIL_SWITCH>())
+ return false;
+ return CompareExprList(GetCases<HLIL_SWITCH>(), other.GetCases<HLIL_SWITCH>());
+ case HLIL_CASE:
+ if (GetTrueExpr<HLIL_CASE>() < other.GetTrueExpr<HLIL_CASE>())
+ return true;
+ if (other.GetTrueExpr<HLIL_CASE>() < GetTrueExpr<HLIL_CASE>())
+ return false;
+ return CompareExprList(GetValueExprs<HLIL_CASE>(), other.GetValueExprs<HLIL_CASE>());
+ case HLIL_JUMP:
+ return GetDestExpr<HLIL_JUMP>() < other.GetDestExpr<HLIL_JUMP>();
+ case HLIL_RET:
+ return CompareExprList(GetSourceExprs<HLIL_RET>(), other.GetSourceExprs<HLIL_RET>());
+ case HLIL_GOTO:
+ return GetTarget<HLIL_GOTO>() < other.GetTarget<HLIL_GOTO>();
+ case HLIL_LABEL:
+ return GetTarget<HLIL_LABEL>() < other.GetTarget<HLIL_LABEL>();
+ case HLIL_ASSIGN:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetDestExpr<HLIL_ASSIGN>() < other.GetDestExpr<HLIL_ASSIGN>())
+ return true;
+ if (other.GetDestExpr<HLIL_ASSIGN>() < GetDestExpr<HLIL_ASSIGN>())
+ return false;
+ return GetSourceExpr<HLIL_ASSIGN>() < other.GetSourceExpr<HLIL_ASSIGN>();
+ case HLIL_ASSIGN_UNPACK:
+ if (GetSourceExpr<HLIL_ASSIGN_UNPACK>() < other.GetSourceExpr<HLIL_ASSIGN_UNPACK>())
+ return true;
+ if (other.GetSourceExpr<HLIL_ASSIGN_UNPACK>() < GetSourceExpr<HLIL_ASSIGN_UNPACK>())
+ return false;
+ return CompareExprList(GetDestExprs<HLIL_ASSIGN_UNPACK>(), other.GetDestExprs<HLIL_ASSIGN_UNPACK>());
+ case HLIL_ASSIGN_MEM_SSA:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetDestExpr<HLIL_ASSIGN_MEM_SSA>() < other.GetDestExpr<HLIL_ASSIGN_MEM_SSA>())
+ return true;
+ if (other.GetDestExpr<HLIL_ASSIGN_MEM_SSA>() < GetDestExpr<HLIL_ASSIGN_MEM_SSA>())
+ return false;
+ if (GetDestMemoryVersion<HLIL_ASSIGN_MEM_SSA>() < other.GetDestMemoryVersion<HLIL_ASSIGN_MEM_SSA>())
+ return true;
+ if (other.GetDestMemoryVersion<HLIL_ASSIGN_MEM_SSA>() < GetDestMemoryVersion<HLIL_ASSIGN_MEM_SSA>())
+ return false;
+ if (GetSourceExpr<HLIL_ASSIGN_MEM_SSA>() < other.GetSourceExpr<HLIL_ASSIGN_MEM_SSA>())
+ return true;
+ if (other.GetSourceExpr<HLIL_ASSIGN_MEM_SSA>() < GetSourceExpr<HLIL_ASSIGN_MEM_SSA>())
+ return false;
+ return GetSourceMemoryVersion<HLIL_ASSIGN_MEM_SSA>() < other.GetSourceMemoryVersion<HLIL_ASSIGN_MEM_SSA>();
+ case HLIL_ASSIGN_UNPACK_MEM_SSA:
+ if (GetDestMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>() < other.GetDestMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>())
+ return true;
+ if (other.GetDestMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>() < GetDestMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>())
+ return false;
+ if (GetSourceExpr<HLIL_ASSIGN_UNPACK_MEM_SSA>() < other.GetSourceExpr<HLIL_ASSIGN_UNPACK_MEM_SSA>())
+ return true;
+ if (other.GetSourceExpr<HLIL_ASSIGN_UNPACK_MEM_SSA>() < GetSourceExpr<HLIL_ASSIGN_UNPACK_MEM_SSA>())
+ return false;
+ if (GetSourceMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>() < other.GetSourceMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>())
+ return true;
+ if (other.GetSourceMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>() < GetSourceMemoryVersion<HLIL_ASSIGN_UNPACK_MEM_SSA>())
+ return false;
+ return CompareExprList(GetDestExprs<HLIL_ASSIGN_UNPACK_MEM_SSA>(), other.GetDestExprs<HLIL_ASSIGN_UNPACK_MEM_SSA>());
+ case HLIL_VAR:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ return GetVariable<HLIL_VAR>() < other.GetVariable<HLIL_VAR>();
+ case HLIL_VAR_SSA:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ return GetSSAVariable<HLIL_VAR_SSA>() < other.GetSSAVariable<HLIL_VAR_SSA>();
+ case HLIL_STRUCT_FIELD:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetSourceExpr<HLIL_STRUCT_FIELD>() < other.GetSourceExpr<HLIL_STRUCT_FIELD>())
+ return true;
+ if (other.GetSourceExpr<HLIL_STRUCT_FIELD>() < GetSourceExpr<HLIL_STRUCT_FIELD>())
+ return false;
+ return GetOffset<HLIL_STRUCT_FIELD>() < other.GetOffset<HLIL_STRUCT_FIELD>();
+ case HLIL_ARRAY_INDEX:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetSourceExpr<HLIL_ARRAY_INDEX>() < other.GetSourceExpr<HLIL_ARRAY_INDEX>())
+ return true;
+ if (other.GetSourceExpr<HLIL_ARRAY_INDEX>() < GetSourceExpr<HLIL_ARRAY_INDEX>())
+ return false;
+ return GetIndexExpr<HLIL_ARRAY_INDEX>() < other.GetIndexExpr<HLIL_ARRAY_INDEX>();
+ case HLIL_ARRAY_INDEX_SSA:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetSourceExpr<HLIL_ARRAY_INDEX_SSA>() < other.GetSourceExpr<HLIL_ARRAY_INDEX_SSA>())
+ return true;
+ if (other.GetSourceExpr<HLIL_ARRAY_INDEX_SSA>() < GetSourceExpr<HLIL_ARRAY_INDEX_SSA>())
+ return false;
+ if (GetIndexExpr<HLIL_ARRAY_INDEX_SSA>() < other.GetIndexExpr<HLIL_ARRAY_INDEX_SSA>())
+ return true;
+ if (other.GetIndexExpr<HLIL_ARRAY_INDEX_SSA>() < GetIndexExpr<HLIL_ARRAY_INDEX_SSA>())
+ return false;
+ return GetSourceMemoryVersion<HLIL_ARRAY_INDEX_SSA>() < other.GetSourceMemoryVersion<HLIL_ARRAY_INDEX_SSA>();
+ case HLIL_SPLIT:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetHighExpr<HLIL_SPLIT>() < other.GetHighExpr<HLIL_SPLIT>())
+ return true;
+ if (other.GetHighExpr<HLIL_SPLIT>() < GetHighExpr<HLIL_SPLIT>())
+ return false;
+ return GetLowExpr<HLIL_SPLIT>() < other.GetLowExpr<HLIL_SPLIT>();
+ case HLIL_DEREF_FIELD:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetSourceExpr<HLIL_DEREF_FIELD>() < other.GetSourceExpr<HLIL_DEREF_FIELD>())
+ return true;
+ if (other.GetSourceExpr<HLIL_DEREF_FIELD>() < GetSourceExpr<HLIL_DEREF_FIELD>())
+ return false;
+ return GetOffset<HLIL_DEREF_FIELD>() < other.GetOffset<HLIL_DEREF_FIELD>();
+ case HLIL_DEREF_SSA:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetSourceExpr<HLIL_DEREF_SSA>() < other.GetSourceExpr<HLIL_DEREF_SSA>())
+ return true;
+ if (other.GetSourceExpr<HLIL_DEREF_SSA>() < GetSourceExpr<HLIL_DEREF_SSA>())
+ return false;
+ return GetSourceMemoryVersion<HLIL_DEREF_SSA>() < other.GetSourceMemoryVersion<HLIL_DEREF_SSA>();
+ case HLIL_DEREF_FIELD_SSA:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (GetSourceExpr<HLIL_DEREF_FIELD_SSA>() < other.GetSourceExpr<HLIL_DEREF_FIELD_SSA>())
+ return true;
+ if (other.GetSourceExpr<HLIL_DEREF_FIELD_SSA>() < GetSourceExpr<HLIL_DEREF_FIELD_SSA>())
+ return false;
+ if (GetOffset<HLIL_DEREF_FIELD_SSA>() < other.GetOffset<HLIL_DEREF_FIELD_SSA>())
+ return true;
+ if (other.GetOffset<HLIL_DEREF_FIELD_SSA>() < GetOffset<HLIL_DEREF_FIELD_SSA>())
+ return false;
+ return GetSourceMemoryVersion<HLIL_DEREF_FIELD_SSA>() < other.GetSourceMemoryVersion<HLIL_DEREF_FIELD_SSA>();
+ case HLIL_ADDRESS_OF:
+ return GetSourceExpr<HLIL_ADDRESS_OF>() < other.GetSourceExpr<HLIL_ADDRESS_OF>();
+ case HLIL_EXTERN_PTR:
+ if (GetConstant<HLIL_EXTERN_PTR>() < other.GetConstant<HLIL_EXTERN_PTR>())
+ return true;
+ if (other.GetConstant<HLIL_EXTERN_PTR>() < GetConstant<HLIL_EXTERN_PTR>())
+ return false;
+ return GetOffset<HLIL_EXTERN_PTR>() < other.GetOffset<HLIL_EXTERN_PTR>();
+ case HLIL_CALL:
+ if (GetDestExpr<HLIL_CALL>() < other.GetDestExpr<HLIL_CALL>())
+ return true;
+ if (other.GetDestExpr<HLIL_CALL>() < GetDestExpr<HLIL_CALL>())
+ return false;
+ return CompareExprList(GetParameterExprs<HLIL_CALL>(), other.GetParameterExprs<HLIL_CALL>());
+ case HLIL_SYSCALL:
+ return CompareExprList(GetParameterExprs<HLIL_SYSCALL>(), other.GetParameterExprs<HLIL_SYSCALL>());
+ case HLIL_TAILCALL:
+ if (GetDestExpr<HLIL_TAILCALL>() < other.GetDestExpr<HLIL_TAILCALL>())
+ return true;
+ if (other.GetDestExpr<HLIL_TAILCALL>() < GetDestExpr<HLIL_TAILCALL>())
+ return false;
+ return CompareExprList(GetParameterExprs<HLIL_TAILCALL>(), other.GetParameterExprs<HLIL_TAILCALL>());
+ case HLIL_INTRINSIC:
+ if (GetIntrinsic<HLIL_INTRINSIC>() < other.GetIntrinsic<HLIL_INTRINSIC>())
+ return true;
+ if (other.GetIntrinsic<HLIL_INTRINSIC>() < GetIntrinsic<HLIL_INTRINSIC>())
+ return false;
+ return CompareExprList(GetParameterExprs<HLIL_INTRINSIC>(), other.GetParameterExprs<HLIL_INTRINSIC>());
+ case HLIL_CALL_SSA:
+ if (GetDestExpr<HLIL_CALL_SSA>() < other.GetDestExpr<HLIL_CALL_SSA>())
+ return true;
+ if (other.GetDestExpr<HLIL_CALL_SSA>() < GetDestExpr<HLIL_CALL_SSA>())
+ return false;
+ if (GetDestMemoryVersion<HLIL_CALL_SSA>() < other.GetDestMemoryVersion<HLIL_CALL_SSA>())
+ return true;
+ if (other.GetDestMemoryVersion<HLIL_CALL_SSA>() < GetDestMemoryVersion<HLIL_CALL_SSA>())
+ return false;
+ if (GetSourceMemoryVersion<HLIL_CALL_SSA>() < other.GetSourceMemoryVersion<HLIL_CALL_SSA>())
+ return true;
+ if (other.GetSourceMemoryVersion<HLIL_CALL_SSA>() < GetSourceMemoryVersion<HLIL_CALL_SSA>())
+ return false;
+ return CompareExprList(GetParameterExprs<HLIL_CALL_SSA>(), other.GetParameterExprs<HLIL_CALL_SSA>());
+ case HLIL_SYSCALL_SSA:
+ if (GetDestMemoryVersion<HLIL_SYSCALL_SSA>() < other.GetDestMemoryVersion<HLIL_SYSCALL_SSA>())
+ return true;
+ if (other.GetDestMemoryVersion<HLIL_SYSCALL_SSA>() < GetDestMemoryVersion<HLIL_SYSCALL_SSA>())
+ return false;
+ if (GetSourceMemoryVersion<HLIL_SYSCALL_SSA>() < other.GetSourceMemoryVersion<HLIL_SYSCALL_SSA>())
+ return true;
+ if (other.GetSourceMemoryVersion<HLIL_SYSCALL_SSA>() < GetSourceMemoryVersion<HLIL_SYSCALL_SSA>())
+ return false;
+ return CompareExprList(GetParameterExprs<HLIL_SYSCALL_SSA>(), other.GetParameterExprs<HLIL_SYSCALL_SSA>());
+ case HLIL_INTRINSIC_SSA:
+ if (GetIntrinsic<HLIL_INTRINSIC_SSA>() < other.GetIntrinsic<HLIL_INTRINSIC_SSA>())
+ return true;
+ if (other.GetIntrinsic<HLIL_INTRINSIC_SSA>() < GetIntrinsic<HLIL_INTRINSIC_SSA>())
+ return false;
+ if (GetDestMemoryVersion<HLIL_INTRINSIC_SSA>() < other.GetDestMemoryVersion<HLIL_INTRINSIC_SSA>())
+ return true;
+ if (other.GetDestMemoryVersion<HLIL_INTRINSIC_SSA>() < GetDestMemoryVersion<HLIL_INTRINSIC_SSA>())
+ return false;
+ if (GetSourceMemoryVersion<HLIL_INTRINSIC_SSA>() < other.GetSourceMemoryVersion<HLIL_INTRINSIC_SSA>())
+ return true;
+ if (other.GetSourceMemoryVersion<HLIL_INTRINSIC_SSA>() < GetSourceMemoryVersion<HLIL_INTRINSIC_SSA>())
+ return false;
+ return CompareExprList(GetParameterExprs<HLIL_INTRINSIC_SSA>(), other.GetParameterExprs<HLIL_INTRINSIC_SSA>());
+ case HLIL_TRAP:
+ return GetVector<HLIL_TRAP>() < other.GetVector<HLIL_TRAP>();
+ case HLIL_ADD:
+ case HLIL_SUB:
+ case HLIL_AND:
+ case HLIL_OR:
+ case HLIL_XOR:
+ case HLIL_LSL:
+ case HLIL_LSR:
+ case HLIL_ASR:
+ case HLIL_ROL:
+ case HLIL_ROR:
+ case HLIL_MUL:
+ case HLIL_MULU_DP:
+ case HLIL_MULS_DP:
+ case HLIL_DIVU:
+ case HLIL_DIVS:
+ case HLIL_MODU:
+ case HLIL_MODS:
+ case HLIL_DIVU_DP:
+ case HLIL_DIVS_DP:
+ case HLIL_MODU_DP:
+ case HLIL_MODS_DP:
+ case HLIL_CMP_E:
+ case HLIL_CMP_NE:
+ case HLIL_CMP_SLT:
+ case HLIL_CMP_ULT:
+ case HLIL_CMP_SLE:
+ case HLIL_CMP_ULE:
+ case HLIL_CMP_SGE:
+ case HLIL_CMP_UGE:
+ case HLIL_CMP_SGT:
+ case HLIL_CMP_UGT:
+ case HLIL_TEST_BIT:
+ case HLIL_ADD_OVERFLOW:
+ case HLIL_FADD:
+ case HLIL_FSUB:
+ case HLIL_FMUL:
+ case HLIL_FDIV:
+ case HLIL_FCMP_E:
+ case HLIL_FCMP_NE:
+ case HLIL_FCMP_LT:
+ case HLIL_FCMP_LE:
+ case HLIL_FCMP_GE:
+ case HLIL_FCMP_GT:
+ case HLIL_FCMP_O:
+ case HLIL_FCMP_UO:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (AsTwoOperand().GetLeftExpr() < other.AsTwoOperand().GetLeftExpr())
+ return true;
+ if (other.AsTwoOperand().GetLeftExpr() < AsTwoOperand().GetLeftExpr())
+ return false;
+ return AsTwoOperand().GetRightExpr() < other.AsTwoOperand().GetRightExpr();
+ case HLIL_ADC:
+ case HLIL_SBB:
+ case HLIL_RLC:
+ case HLIL_RRC:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ if (AsTwoOperandWithCarry().GetLeftExpr() < other.AsTwoOperandWithCarry().GetLeftExpr())
+ return true;
+ if (other.AsTwoOperandWithCarry().GetLeftExpr() < AsTwoOperandWithCarry().GetLeftExpr())
+ return false;
+ if (AsTwoOperandWithCarry().GetRightExpr() < other.AsTwoOperandWithCarry().GetRightExpr())
+ return true;
+ if (other.AsTwoOperandWithCarry().GetRightExpr() < AsTwoOperandWithCarry().GetRightExpr())
+ return false;
+ return AsTwoOperandWithCarry().GetCarryExpr() < other.AsTwoOperandWithCarry().GetCarryExpr();
+ case HLIL_CONST:
+ case HLIL_CONST_PTR:
+ case HLIL_FLOAT_CONST:
+ case HLIL_IMPORT:
+ return AsConstant().GetConstant() < other.AsConstant().GetConstant();
+ case HLIL_DEREF:
+ case HLIL_NEG:
+ case HLIL_NOT:
+ case HLIL_SX:
+ case HLIL_ZX:
+ case HLIL_LOW_PART:
+ case HLIL_BOOL_TO_INT:
+ case HLIL_UNIMPL_MEM:
+ case HLIL_FSQRT:
+ case HLIL_FNEG:
+ case HLIL_FABS:
+ case HLIL_FLOAT_TO_INT:
+ case HLIL_INT_TO_FLOAT:
+ case HLIL_FLOAT_CONV:
+ case HLIL_ROUND_TO_INT:
+ case HLIL_FLOOR:
+ case HLIL_CEIL:
+ case HLIL_FTRUNC:
+ if (size < other.size)
+ return true;
+ if (size > other.size)
+ return false;
+ return AsOneOperand().GetSourceExpr() < other.AsOneOperand().GetSourceExpr();
+ case HLIL_VAR_PHI:
+ {
+ if (GetDestSSAVariable<HLIL_VAR_PHI>() < other.GetDestSSAVariable<HLIL_VAR_PHI>())
+ return true;
+ if (other.GetDestSSAVariable<HLIL_VAR_PHI>() < GetDestSSAVariable<HLIL_VAR_PHI>())
+ return false;
+ HighLevelILSSAVariableList list = GetSourceSSAVariables<HLIL_VAR_PHI>();
+ HighLevelILSSAVariableList otherList = other.GetSourceSSAVariables<HLIL_VAR_PHI>();
+ if (list.size() < otherList.size())
+ return true;
+ if (list.size() > otherList.size())
+ return false;
+ auto i = list.begin();
+ auto j = otherList.begin();
+ for (; i != list.end(); ++i, ++j)
+ {
+ if (*i < *j)
+ return true;
+ if (*j < *i)
+ return false;
+ }
+ return false;
+ }
+ case HLIL_MEM_PHI:
+ {
+ if (GetDestMemoryVersion<HLIL_MEM_PHI>() < other.GetDestMemoryVersion<HLIL_MEM_PHI>())
+ return true;
+ if (other.GetDestMemoryVersion<HLIL_MEM_PHI>() < GetDestMemoryVersion<HLIL_MEM_PHI>())
+ return false;
+ HighLevelILIndexList list = GetSourceMemoryVersions<HLIL_MEM_PHI>();
+ HighLevelILIndexList otherList = other.GetSourceMemoryVersions<HLIL_MEM_PHI>();
+ if (list.size() < otherList.size())
+ return true;
+ if (list.size() > otherList.size())
+ return false;
+ auto i = list.begin();
+ auto j = otherList.begin();
+ for (; i != list.end(); ++i, ++j)
+ {
+ if (*i < *j)
+ return true;
+ if (*j < *i)
+ return false;
+ }
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
+
+bool HighLevelILInstruction::operator==(const HighLevelILInstruction& other) const
+{
+ return !((*this < other) || (other < *this));
+}
+
+
+bool HighLevelILInstruction::operator!=(const HighLevelILInstruction& other) const
+{
+ return !(*this == other);
+}
+
+
bool HighLevelILInstruction::GetOperandIndexForUsage(HighLevelILOperandUsage usage, size_t& operandIndex) const
{
auto operationIter = HighLevelILInstructionBase::operationOperandIndex.find(operation);
@@ -1554,6 +2041,15 @@ HighLevelILInstructionList HighLevelILInstruction::GetCases() const
}
+HighLevelILInstructionList HighLevelILInstruction::GetValueExprs() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ValueExprsHighLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExprList(operandIndex);
+ throw HighLevelILInstructionAccessException();
+}
+
+
HighLevelILSSAVariableList HighLevelILInstruction::GetSourceSSAVariables() const
{
size_t operandIndex;
@@ -1636,9 +2132,9 @@ ExprId HighLevelILFunction::Switch(ExprId condition, ExprId defaultExpr, const s
}
-ExprId HighLevelILFunction::Case(ExprId condition, ExprId expr, const ILSourceLocation& loc)
+ExprId HighLevelILFunction::Case(const std::vector<ExprId>& values, ExprId expr, const ILSourceLocation& loc)
{
- return AddExprWithLocation(HLIL_CASE, loc, 0, condition, expr);
+ return AddExprWithLocation(HLIL_CASE, loc, 0, values.size(), AddOperandList(values), expr);
}
diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h
index 9dc6a604..6c249d94 100644
--- a/highlevelilinstruction.h
+++ b/highlevelilinstruction.h
@@ -94,6 +94,7 @@ namespace BinaryNinja
DestExprsHighLevelOperandUsage,
BlockExprsHighLevelOperandUsage,
CasesHighLevelOperandUsage,
+ ValueExprsHighLevelOperandUsage,
SourceSSAVariablesHighLevelOperandUsage,
SourceMemoryVersionHighLevelOperandUsage,
SourceMemoryVersionsHighLevelOperandUsage,
@@ -293,6 +294,11 @@ namespace BinaryNinja
void UpdateRawOperandAsExprList(size_t operandIndex, const std::vector<HighLevelILInstruction>& exprs);
void UpdateRawOperandAsExprList(size_t operandIndex, const std::vector<size_t>& exprs);
+ RegisterValue GetValue() const;
+ PossibleValueSet GetPossibleValues(const std::set<BNDataFlowQueryOption>& options =
+ std::set<BNDataFlowQueryOption>()) const;
+ Confidence<Ref<Type>> GetType() const;
+
size_t GetMediumLevelILExprIndex() const;
bool HasMediumLevelIL() const;
MediumLevelILInstruction GetMediumLevelIL() const;
@@ -360,6 +366,10 @@ namespace BinaryNinja
ExprId CopyTo(HighLevelILFunction* dest,
const std::function<ExprId(const HighLevelILInstruction& subExpr)>& subExprHandler) const;
+ bool operator<(const HighLevelILInstruction& other) const;
+ bool operator==(const HighLevelILInstruction& other) const;
+ bool operator!=(const HighLevelILInstruction& other) const;
+
// 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(); }
@@ -389,6 +399,7 @@ namespace BinaryNinja
template <BNHighLevelILOperation N> HighLevelILInstructionList GetDestExprs() const { return As<N>().GetDestExprs(); }
template <BNHighLevelILOperation N> HighLevelILInstructionList GetBlockExprs() const { return As<N>().GetBlockExprs(); }
template <BNHighLevelILOperation N> HighLevelILInstructionList GetCases() const { return As<N>().GetCases(); }
+ template <BNHighLevelILOperation N> HighLevelILInstructionList GetValueExprs() const { return As<N>().GetValueExprs(); }
template <BNHighLevelILOperation N> HighLevelILSSAVariableList GetSourceSSAVariables() const { return As<N>().GetSourceSSAVariables(); }
template <BNHighLevelILOperation N> size_t GetSourceMemoryVersion() const { return As<N>().GetSourceMemoryVersion(); }
template <BNHighLevelILOperation N> HighLevelILIndexList GetSourceMemoryVersions() const { return As<N>().GetSourceMemoryVersions(); }
@@ -441,6 +452,7 @@ namespace BinaryNinja
HighLevelILInstructionList GetDestExprs() const;
HighLevelILInstructionList GetBlockExprs() const;
HighLevelILInstructionList GetCases() const;
+ HighLevelILInstructionList GetValueExprs() const;
HighLevelILSSAVariableList GetSourceSSAVariables() const;
size_t GetSourceMemoryVersion() const;
HighLevelILIndexList GetSourceMemoryVersions() const;
@@ -565,8 +577,8 @@ namespace BinaryNinja
};
template <> struct HighLevelILInstructionAccessor<HLIL_CASE>: public HighLevelILInstructionBase
{
- HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(0); }
- HighLevelILInstruction GetTrueExpr() const { return GetRawOperandAsExpr(1); }
+ HighLevelILInstructionList GetValueExprs() const { return GetRawOperandAsExprList(0); }
+ HighLevelILInstruction GetTrueExpr() const { return GetRawOperandAsExpr(2); }
};
template <> struct HighLevelILInstructionAccessor<HLIL_GOTO>: public HighLevelILInstructionBase
{
diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp
index 18c9e769..f55d15f0 100644
--- a/lowlevelilinstruction.cpp
+++ b/lowlevelilinstruction.cpp
@@ -1613,9 +1613,9 @@ RegisterValue LowLevelILInstructionBase::GetValue() const
}
-PossibleValueSet LowLevelILInstructionBase::GetPossibleValues() const
+PossibleValueSet LowLevelILInstructionBase::GetPossibleValues(const set<BNDataFlowQueryOption>& options) const
{
- return function->GetPossibleExprValues(*(const LowLevelILInstruction*)this);
+ return function->GetPossibleExprValues(*(const LowLevelILInstruction*)this, options);
}
diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h
index b4c863b0..0fcc36eb 100644
--- a/lowlevelilinstruction.h
+++ b/lowlevelilinstruction.h
@@ -619,7 +619,8 @@ namespace BinaryNinja
void UpdateRawOperandAsSSARegisterOrFlagList(size_t operandIndex, const std::vector<SSARegisterOrFlag>& outputs);
RegisterValue GetValue() const;
- PossibleValueSet GetPossibleValues() const;
+ PossibleValueSet GetPossibleValues(const std::set<BNDataFlowQueryOption>& options =
+ std::set<BNDataFlowQueryOption>()) const;
RegisterValue GetRegisterValue(uint32_t reg);
RegisterValue GetRegisterValueAfter(uint32_t reg);
diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp
index 388d8b9f..28380704 100644
--- a/mediumlevelilinstruction.cpp
+++ b/mediumlevelilinstruction.cpp
@@ -1070,9 +1070,9 @@ RegisterValue MediumLevelILInstructionBase::GetValue() const
}
-PossibleValueSet MediumLevelILInstructionBase::GetPossibleValues() const
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleValues(const set<BNDataFlowQueryOption>& options) const
{
- return function->GetPossibleExprValues(*(const MediumLevelILInstruction*)this);
+ return function->GetPossibleExprValues(*(const MediumLevelILInstruction*)this, options);
}
diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h
index 98506896..b0cfb139 100644
--- a/mediumlevelilinstruction.h
+++ b/mediumlevelilinstruction.h
@@ -396,7 +396,8 @@ namespace BinaryNinja
void UpdateRawOperandAsExprList(size_t operandIndex, const std::vector<size_t>& exprs);
RegisterValue GetValue() const;
- PossibleValueSet GetPossibleValues() const;
+ PossibleValueSet GetPossibleValues(const std::set<BNDataFlowQueryOption>& options =
+ std::set<BNDataFlowQueryOption>()) const;
Confidence<Ref<Type>> GetType() const;
size_t GetSSAVarVersion(const Variable& var);
diff --git a/python/function.py b/python/function.py
index dfb83e34..97f832d1 100644
--- a/python/function.py
+++ b/python/function.py
@@ -278,10 +278,16 @@ class ValueRange(object):
class PossibleValueSet(object):
- def __init__(self, arch, value):
+ def __init__(self, arch = None, value = None):
+ if value is None:
+ self._type = RegisterValueType.UndeterminedValue
+ return
self._type = RegisterValueType(value.state)
if value.state == RegisterValueType.EntryValue:
- self._reg = arch.get_reg_name(value.value)
+ if arch is None:
+ self._reg = value.value
+ else:
+ self._reg = arch.get_reg_name(value.value)
elif value.state == RegisterValueType.ConstantValue:
self._value = value.value
elif value.state == RegisterValueType.ConstantPointerValue:
diff --git a/python/highlevelil.py b/python/highlevelil.py
index a5d0b661..feac146b 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -85,7 +85,7 @@ class HighLevelILInstruction(object):
HighLevelILOperation.HLIL_DO_WHILE: [("body", "expr"), ("condition", "expr")],
HighLevelILOperation.HLIL_FOR: [("init", "expr"), ("condition", "expr"), ("update", "expr"), ("body", "expr")],
HighLevelILOperation.HLIL_SWITCH: [("condition", "expr"), ("default", "expr"), ("cases", "expr_list")],
- HighLevelILOperation.HLIL_CASE: [("condition", "expr"), ("body", "expr")],
+ HighLevelILOperation.HLIL_CASE: [("values", "expr_list"), ("body", "expr")],
HighLevelILOperation.HLIL_BREAK: [],
HighLevelILOperation.HLIL_CONTINUE: [],
HighLevelILOperation.HLIL_JUMP: [("dest", "expr")],
@@ -448,6 +448,36 @@ class HighLevelILInstruction(object):
"""IL basic block object containing this expression (read-only) (only available on finalized functions)"""
return HighLevelILBasicBlock(self._function.source_function.view, core.BNGetHighLevelILBasicBlockForInstruction(self._function.handle, self._instr_index), self._function)
+ @property
+ def value(self):
+ """Value of expression if constant or a known value (read-only)"""
+ mlil = self.mlil
+ if mlil is None:
+ return function.RegisterValue()
+ return mlil.value
+
+ @property
+ def possible_values(self):
+ """Possible values of expression using path-sensitive static data flow analysis (read-only)"""
+ mlil = self.mlil
+ if mlil is None:
+ return function.PossibleValueSet()
+ return mlil.possible_values
+
+ @property
+ def expr_type(self):
+ """Type of expression"""
+ mlil = self.mlil
+ if mlil is None:
+ return None
+ return mlil.expr_type
+
+ def get_possible_values(self, options = []):
+ mlil = self.mlil
+ if mlil is None:
+ return function.RegisterValue()
+ return mlil.get_possible_values(options)
+
class HighLevelILExpr(object):
"""