From 620dd96217a49803fe04c6bc286291ddd857dcba Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Sat, 3 Aug 2019 22:40:57 -0400 Subject: Expand support for HLIL switch/case and data flow access --- highlevelilinstruction.cpp | 508 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 502 insertions(+), 6 deletions(-) (limited to 'highlevelilinstruction.cpp') diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 801f5ec1..1468fa78 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -63,6 +63,7 @@ unordered_map {DestExprsHighLevelOperandUsage, ExprListHighLevelOperand}, {BlockExprsHighLevelOperandUsage, ExprListHighLevelOperand}, {CasesHighLevelOperandUsage, ExprListHighLevelOperand}, + {ValueExprsHighLevelOperandUsage, ExprListHighLevelOperand}, {SourceSSAVariablesHighLevelOperandUsage, SSAVariableListHighLevelOperand}, {SourceMemoryVersionHighLevelOperandUsage, IndexHighLevelOperand}, {SourceMemoryVersionsHighLevelOperandUsage, IndexListHighLevelOperand}, @@ -88,7 +89,7 @@ unordered_map> 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& options) const +{ + if (!HasMediumLevelIL()) + return PossibleValueSet(); + return GetMediumLevelILSSAForm().GetPossibleValues(options); +} + + +Confidence> 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().exprIndex); - toProcess.push(cur.GetConditionExpr().exprIndex); + exprs = cur.GetValueExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); break; case HLIL_ASSIGN: toProcess.push(cur.GetSourceExpr().exprIndex); @@ -1095,8 +1122,9 @@ ExprId HighLevelILInstruction::CopyTo(HighLevelILFunction* dest, return dest->Switch(subExprHandler(GetConditionExpr()), subExprHandler(GetDefaultExpr()), params, *this); case HLIL_CASE: - return dest->Case(subExprHandler(GetConditionExpr()), - subExprHandler(GetTrueExpr()), *this); + for (auto& i : GetValueExprs()) + params.push_back(subExprHandler(i)); + return dest->Case(params, subExprHandler(GetTrueExpr()), *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(), other.GetBlockExprs()); + case HLIL_IF: + if (GetConditionExpr() < other.GetConditionExpr()) + return true; + if (other.GetConditionExpr() < GetConditionExpr()) + return false; + if (GetTrueExpr() < other.GetTrueExpr()) + return true; + if (other.GetTrueExpr() < GetTrueExpr()) + return false; + return GetFalseExpr() < other.GetFalseExpr(); + case HLIL_WHILE: + if (GetConditionExpr() < other.GetConditionExpr()) + return true; + if (other.GetConditionExpr() < GetConditionExpr()) + return false; + return GetLoopExpr() < other.GetLoopExpr(); + case HLIL_DO_WHILE: + if (GetLoopExpr() < other.GetLoopExpr()) + return true; + if (other.GetLoopExpr() < GetLoopExpr()) + return false; + return GetConditionExpr() < other.GetConditionExpr(); + case HLIL_FOR: + if (GetInitExpr() < other.GetInitExpr()) + return true; + if (other.GetInitExpr() < GetInitExpr()) + return false; + if (GetConditionExpr() < other.GetConditionExpr()) + return true; + if (other.GetConditionExpr() < GetConditionExpr()) + return false; + if (GetUpdateExpr() < other.GetUpdateExpr()) + return true; + if (other.GetUpdateExpr() < GetUpdateExpr()) + return false; + return GetLoopExpr() < other.GetLoopExpr(); + case HLIL_SWITCH: + if (GetConditionExpr() < other.GetConditionExpr()) + return true; + if (other.GetConditionExpr() < GetConditionExpr()) + return false; + if (GetDefaultExpr() < other.GetDefaultExpr()) + return true; + if (other.GetDefaultExpr() < GetDefaultExpr()) + return false; + return CompareExprList(GetCases(), other.GetCases()); + case HLIL_CASE: + if (GetTrueExpr() < other.GetTrueExpr()) + return true; + if (other.GetTrueExpr() < GetTrueExpr()) + return false; + return CompareExprList(GetValueExprs(), other.GetValueExprs()); + case HLIL_JUMP: + return GetDestExpr() < other.GetDestExpr(); + case HLIL_RET: + return CompareExprList(GetSourceExprs(), other.GetSourceExprs()); + case HLIL_GOTO: + return GetTarget() < other.GetTarget(); + case HLIL_LABEL: + return GetTarget() < other.GetTarget(); + case HLIL_ASSIGN: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetDestExpr() < other.GetDestExpr()) + return true; + if (other.GetDestExpr() < GetDestExpr()) + return false; + return GetSourceExpr() < other.GetSourceExpr(); + case HLIL_ASSIGN_UNPACK: + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + return CompareExprList(GetDestExprs(), other.GetDestExprs()); + case HLIL_ASSIGN_MEM_SSA: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetDestExpr() < other.GetDestExpr()) + return true; + if (other.GetDestExpr() < GetDestExpr()) + return false; + if (GetDestMemoryVersion() < other.GetDestMemoryVersion()) + return true; + if (other.GetDestMemoryVersion() < GetDestMemoryVersion()) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + return GetSourceMemoryVersion() < other.GetSourceMemoryVersion(); + case HLIL_ASSIGN_UNPACK_MEM_SSA: + if (GetDestMemoryVersion() < other.GetDestMemoryVersion()) + return true; + if (other.GetDestMemoryVersion() < GetDestMemoryVersion()) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + if (GetSourceMemoryVersion() < other.GetSourceMemoryVersion()) + return true; + if (other.GetSourceMemoryVersion() < GetSourceMemoryVersion()) + return false; + return CompareExprList(GetDestExprs(), other.GetDestExprs()); + case HLIL_VAR: + if (size < other.size) + return true; + if (size > other.size) + return false; + return GetVariable() < other.GetVariable(); + case HLIL_VAR_SSA: + if (size < other.size) + return true; + if (size > other.size) + return false; + return GetSSAVariable() < other.GetSSAVariable(); + case HLIL_STRUCT_FIELD: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + return GetOffset() < other.GetOffset(); + case HLIL_ARRAY_INDEX: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + return GetIndexExpr() < other.GetIndexExpr(); + case HLIL_ARRAY_INDEX_SSA: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + if (GetIndexExpr() < other.GetIndexExpr()) + return true; + if (other.GetIndexExpr() < GetIndexExpr()) + return false; + return GetSourceMemoryVersion() < other.GetSourceMemoryVersion(); + case HLIL_SPLIT: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetHighExpr() < other.GetHighExpr()) + return true; + if (other.GetHighExpr() < GetHighExpr()) + return false; + return GetLowExpr() < other.GetLowExpr(); + case HLIL_DEREF_FIELD: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + return GetOffset() < other.GetOffset(); + case HLIL_DEREF_SSA: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + return GetSourceMemoryVersion() < other.GetSourceMemoryVersion(); + case HLIL_DEREF_FIELD_SSA: + if (size < other.size) + return true; + if (size > other.size) + return false; + if (GetSourceExpr() < other.GetSourceExpr()) + return true; + if (other.GetSourceExpr() < GetSourceExpr()) + return false; + if (GetOffset() < other.GetOffset()) + return true; + if (other.GetOffset() < GetOffset()) + return false; + return GetSourceMemoryVersion() < other.GetSourceMemoryVersion(); + case HLIL_ADDRESS_OF: + return GetSourceExpr() < other.GetSourceExpr(); + case HLIL_EXTERN_PTR: + if (GetConstant() < other.GetConstant()) + return true; + if (other.GetConstant() < GetConstant()) + return false; + return GetOffset() < other.GetOffset(); + case HLIL_CALL: + if (GetDestExpr() < other.GetDestExpr()) + return true; + if (other.GetDestExpr() < GetDestExpr()) + return false; + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_SYSCALL: + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_TAILCALL: + if (GetDestExpr() < other.GetDestExpr()) + return true; + if (other.GetDestExpr() < GetDestExpr()) + return false; + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_INTRINSIC: + if (GetIntrinsic() < other.GetIntrinsic()) + return true; + if (other.GetIntrinsic() < GetIntrinsic()) + return false; + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_CALL_SSA: + if (GetDestExpr() < other.GetDestExpr()) + return true; + if (other.GetDestExpr() < GetDestExpr()) + return false; + if (GetDestMemoryVersion() < other.GetDestMemoryVersion()) + return true; + if (other.GetDestMemoryVersion() < GetDestMemoryVersion()) + return false; + if (GetSourceMemoryVersion() < other.GetSourceMemoryVersion()) + return true; + if (other.GetSourceMemoryVersion() < GetSourceMemoryVersion()) + return false; + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_SYSCALL_SSA: + if (GetDestMemoryVersion() < other.GetDestMemoryVersion()) + return true; + if (other.GetDestMemoryVersion() < GetDestMemoryVersion()) + return false; + if (GetSourceMemoryVersion() < other.GetSourceMemoryVersion()) + return true; + if (other.GetSourceMemoryVersion() < GetSourceMemoryVersion()) + return false; + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_INTRINSIC_SSA: + if (GetIntrinsic() < other.GetIntrinsic()) + return true; + if (other.GetIntrinsic() < GetIntrinsic()) + return false; + if (GetDestMemoryVersion() < other.GetDestMemoryVersion()) + return true; + if (other.GetDestMemoryVersion() < GetDestMemoryVersion()) + return false; + if (GetSourceMemoryVersion() < other.GetSourceMemoryVersion()) + return true; + if (other.GetSourceMemoryVersion() < GetSourceMemoryVersion()) + return false; + return CompareExprList(GetParameterExprs(), other.GetParameterExprs()); + case HLIL_TRAP: + return GetVector() < other.GetVector(); + 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() < other.GetDestSSAVariable()) + return true; + if (other.GetDestSSAVariable() < GetDestSSAVariable()) + return false; + HighLevelILSSAVariableList list = GetSourceSSAVariables(); + HighLevelILSSAVariableList otherList = other.GetSourceSSAVariables(); + 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() < other.GetDestMemoryVersion()) + return true; + if (other.GetDestMemoryVersion() < GetDestMemoryVersion()) + return false; + HighLevelILIndexList list = GetSourceMemoryVersions(); + HighLevelILIndexList otherList = other.GetSourceMemoryVersions(); + 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& 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); } -- cgit v1.3.1