diff options
| author | Rusty Wagner <rusty@vector35.com> | 2019-08-03 22:40:57 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2020-04-17 14:20:37 -0400 |
| commit | 620dd96217a49803fe04c6bc286291ddd857dcba (patch) | |
| tree | c416e88ecd9ac0d15e1864bbd17a6eb70548965f | |
| parent | c9845e5a200228f20809336d9e9afee45e776d19 (diff) | |
Expand support for HLIL switch/case and data flow access
| -rw-r--r-- | binaryninjaapi.h | 3 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 508 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 16 | ||||
| -rw-r--r-- | lowlevelilinstruction.cpp | 4 | ||||
| -rw-r--r-- | lowlevelilinstruction.h | 3 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 4 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 3 | ||||
| -rw-r--r-- | python/function.py | 10 | ||||
| -rw-r--r-- | python/highlevelil.py | 32 |
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): """ |
