diff options
| -rw-r--r-- | binaryninjaapi.h | 28 | ||||
| -rw-r--r-- | binaryninjacore.h | 42 | ||||
| -rw-r--r-- | highlevelil.cpp | 144 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 196 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 46 | ||||
| -rw-r--r-- | linearviewobject.cpp | 7 | ||||
| -rw-r--r-- | python/highlevelil.py | 149 | ||||
| -rw-r--r-- | python/lineardisassembly.py | 6 |
8 files changed, 584 insertions, 34 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 4339ad6f..91fe0d63 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -4052,9 +4052,15 @@ __attribute__ ((format (printf, 1, 2))) ExprId If(ExprId condition, ExprId trueExpr, ExprId falseExpr, const ILSourceLocation& loc = ILSourceLocation()); ExprId While(ExprId condition, ExprId loopExpr, const ILSourceLocation& loc = ILSourceLocation()); + ExprId WhileSSA(ExprId conditionPhi, ExprId condition, ExprId loopExpr, + const ILSourceLocation& loc = ILSourceLocation()); ExprId DoWhile(ExprId loopExpr, ExprId condition, const ILSourceLocation& loc = ILSourceLocation()); + ExprId DoWhileSSA(ExprId loopExpr, ExprId conditionPhi, ExprId condition, + const ILSourceLocation& loc = ILSourceLocation()); ExprId For(ExprId initExpr, ExprId condition, ExprId updateExpr, ExprId loopExpr, const ILSourceLocation& loc = ILSourceLocation()); + ExprId ForSSA(ExprId initExpr, ExprId conditionPhi, ExprId condition, ExprId updateExpr, + ExprId loopExpr, const ILSourceLocation& loc = ILSourceLocation()); ExprId Switch(ExprId condition, ExprId defaultExpr, const std::vector<ExprId>& cases, const ILSourceLocation& loc = ILSourceLocation()); ExprId Case(const std::vector<ExprId>& condition, ExprId expr, @@ -4227,9 +4233,10 @@ __attribute__ ((format (printf, 1, 2))) ExprId AddSSAVariableList(const std::vector<SSAVariable>& vars); BNHighLevelILInstruction GetRawExpr(size_t i) const; + BNHighLevelILInstruction GetRawNonASTExpr(size_t i) const; HighLevelILInstruction operator[](size_t i); HighLevelILInstruction GetInstruction(size_t i); - HighLevelILInstruction GetExpr(size_t i); + HighLevelILInstruction GetExpr(size_t i, bool asFullAst = true); size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionForExpr(size_t expr) const; size_t GetInstructionCount() const; @@ -4238,6 +4245,24 @@ __attribute__ ((format (printf, 1, 2))) std::vector<Ref<BasicBlock>> GetBasicBlocks() const; Ref<BasicBlock> GetBasicBlockForInstruction(size_t i) const; + Ref<HighLevelILFunction> GetSSAForm() const; + Ref<HighLevelILFunction> GetNonSSAForm() const; + size_t GetSSAInstructionIndex(size_t instr) const; + size_t GetNonSSAInstructionIndex(size_t instr) const; + size_t GetSSAExprIndex(size_t instr) const; + size_t GetNonSSAExprIndex(size_t instr) const; + + size_t GetSSAVarDefinition(const SSAVariable& var) const; + size_t GetSSAMemoryDefinition(size_t version) const; + std::set<size_t> GetSSAVarUses(const SSAVariable& var) const; + std::set<size_t> GetSSAMemoryUses(size_t version) const; + bool IsSSAVarLive(const SSAVariable& var) const; + + std::set<size_t> GetVariableDefinitions(const Variable& var) const; + std::set<size_t> GetVariableUses(const Variable& var) const; + size_t GetSSAVarVersionAtInstruction(const Variable& var, size_t instr) const; + size_t GetSSAMemoryVersionAtInstruction(size_t instr) const; + Ref<MediumLevelILFunction> GetMediumLevelIL() const; size_t GetMediumLevelILExprIndex(size_t expr) const; @@ -5249,6 +5274,7 @@ __attribute__ ((format (printf, 1, 2))) static Ref<LinearViewObject> CreateMappedMediumLevelIL(BinaryView* view, DisassemblySettings* settings); static Ref<LinearViewObject> CreateMappedMediumLevelILSSAForm(BinaryView* view, DisassemblySettings* settings); static Ref<LinearViewObject> CreateHighLevelIL(BinaryView* view, DisassemblySettings* settings); + static Ref<LinearViewObject> CreateHighLevelILSSAForm(BinaryView* view, DisassemblySettings* settings); }; class LinearViewCursor: public CoreRefCountObject<BNLinearViewCursor, diff --git a/binaryninjacore.h b/binaryninjacore.h index 3ee4cc69..ea718dbe 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -517,7 +517,8 @@ extern "C" MediumLevelILSSAFormFunctionGraph = 5, MappedMediumLevelILFunctionGraph = 6, MappedMediumLevelILSSAFormFunctionGraph = 7, - HighLevelILFunctionGraph = 8 + HighLevelILFunctionGraph = 8, + HighLevelILSSAFormFunctionGraph = 9 }; enum BNDisassemblyOption @@ -1159,6 +1160,9 @@ extern "C" HLIL_FCMP_UO, // The following instructions are only used in SSA form + HLIL_WHILE_SSA, + HLIL_DO_WHILE_SSA, + HLIL_FOR_SSA, HLIL_VAR_INIT_SSA, HLIL_ASSIGN_MEM_SSA, HLIL_ASSIGN_UNPACK_MEM_SSA, @@ -3137,6 +3141,8 @@ __attribute__ ((format (printf, 1, 2))) BNDisassemblySettings* settings); BINARYNINJACOREAPI BNLinearViewObject* BNCreateLinearViewHighLevelIL(BNBinaryView* view, BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNLinearViewObject* BNCreateLinearViewHighLevelILSSAForm(BNBinaryView* view, + BNDisassemblySettings* settings); BINARYNINJACOREAPI BNLinearViewObject* BNNewLinearViewObjectReference(BNLinearViewObject* obj); BINARYNINJACOREAPI void BNFreeLinearViewObject(BNLinearViewObject* obj); BINARYNINJACOREAPI BNLinearViewObject* BNGetFirstLinearViewObjectChild(BNLinearViewObject* obj); @@ -3719,9 +3725,6 @@ __attribute__ ((format (printf, 1, 2))) BNMediumLevelILFunction* func, size_t instr, size_t* count); BINARYNINJACOREAPI void BNFreeILBranchDependenceList(BNILBranchInstructionAndDependence* branches); - BINARYNINJACOREAPI BNBasicBlock** BNGetHighLevelILBasicBlockList(BNHighLevelILFunction* func, size_t* count); - BINARYNINJACOREAPI BNBasicBlock* BNGetHighLevelILBasicBlockForInstruction(BNHighLevelILFunction* func, size_t i); - BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILForMediumLevelIL(BNMediumLevelILFunction* func); BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); @@ -3748,7 +3751,7 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI uint64_t* BNHighLevelILGetOperandList(BNHighLevelILFunction* func, size_t expr, size_t operand, size_t* count); BINARYNINJACOREAPI void BNHighLevelILFreeOperandList(uint64_t* operands); - BINARYNINJACOREAPI BNHighLevelILInstruction BNGetHighLevelILByIndex(BNHighLevelILFunction* func, size_t i); + BINARYNINJACOREAPI BNHighLevelILInstruction BNGetHighLevelILByIndex(BNHighLevelILFunction* func, size_t i, bool asFullAst); BINARYNINJACOREAPI size_t BNGetHighLevelILIndexForInstruction(BNHighLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetHighLevelILInstructionForExpr(BNHighLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetHighLevelILInstructionCount(BNHighLevelILFunction* func); @@ -3765,6 +3768,35 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI BNTypeWithConfidence BNGetHighLevelILExprType(BNHighLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNBasicBlock** BNGetHighLevelILBasicBlockList(BNHighLevelILFunction* func, size_t* count); + BINARYNINJACOREAPI BNBasicBlock* BNGetHighLevelILBasicBlockForInstruction(BNHighLevelILFunction* func, size_t i); + + BINARYNINJACOREAPI BNHighLevelILFunction* BNGetHighLevelILSSAForm(BNHighLevelILFunction* func); + BINARYNINJACOREAPI BNHighLevelILFunction* BNGetHighLevelILNonSSAForm(BNHighLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetHighLevelILSSAInstructionIndex(BNHighLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetHighLevelILNonSSAInstructionIndex(BNHighLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetHighLevelILSSAExprIndex(BNHighLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI size_t BNGetHighLevelILNonSSAExprIndex(BNHighLevelILFunction* func, size_t expr); + + BINARYNINJACOREAPI size_t BNGetHighLevelILSSAVarDefinition(BNHighLevelILFunction* func, + const BNVariable* var, size_t version); + BINARYNINJACOREAPI size_t BNGetHighLevelILSSAMemoryDefinition(BNHighLevelILFunction* func, size_t version); + BINARYNINJACOREAPI size_t* BNGetHighLevelILSSAVarUses(BNHighLevelILFunction* func, const BNVariable* var, + size_t version, size_t* count); + BINARYNINJACOREAPI size_t* BNGetHighLevelILSSAMemoryUses(BNHighLevelILFunction* func, + size_t version, size_t* count); + BINARYNINJACOREAPI bool BNIsHighLevelILSSAVarLive(BNHighLevelILFunction* func, + const BNVariable* var, size_t version); + + BINARYNINJACOREAPI size_t* BNGetHighLevelILVariableDefinitions(BNHighLevelILFunction* func, + const BNVariable* var, size_t* count); + BINARYNINJACOREAPI size_t* BNGetHighLevelILVariableUses(BNHighLevelILFunction* func, + const BNVariable* var, size_t* count); + BINARYNINJACOREAPI size_t BNGetHighLevelILSSAVarVersionAtILInstruction(BNHighLevelILFunction* func, + const BNVariable* var, size_t instr); + BINARYNINJACOREAPI size_t BNGetHighLevelILSSAMemoryVersionAtILInstruction(BNHighLevelILFunction* func, + size_t instr); + // Type Libraries BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibrary(BNArchitecture* arch, const char* name); BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibraryReference(BNTypeLibrary* lib); diff --git a/highlevelil.cpp b/highlevelil.cpp index a3c9e5b2..f97b11d3 100644 --- a/highlevelil.cpp +++ b/highlevelil.cpp @@ -162,7 +162,13 @@ ExprId HighLevelILFunction::AddSSAVariableList(const vector<SSAVariable>& vars) BNHighLevelILInstruction HighLevelILFunction::GetRawExpr(size_t i) const { - return BNGetHighLevelILByIndex(m_object, i); + return BNGetHighLevelILByIndex(m_object, i, true); +} + + +BNHighLevelILInstruction HighLevelILFunction::GetRawNonASTExpr(size_t i) const +{ + return BNGetHighLevelILByIndex(m_object, i, false); } @@ -175,13 +181,15 @@ HighLevelILInstruction HighLevelILFunction::operator[](size_t i) HighLevelILInstruction HighLevelILFunction::GetInstruction(size_t i) { size_t expr = GetIndexForInstruction(i); - return HighLevelILInstruction(this, GetRawExpr(expr), expr); + return HighLevelILInstruction(this, GetRawNonASTExpr(expr), expr, false, i); } -HighLevelILInstruction HighLevelILFunction::GetExpr(size_t i) +HighLevelILInstruction HighLevelILFunction::GetExpr(size_t i, bool asFullAst) { - return HighLevelILInstruction(this, GetRawExpr(i), i); + if (asFullAst) + return HighLevelILInstruction(this, GetRawExpr(i), i, true, GetInstructionForExpr(i)); + return HighLevelILInstruction(this, GetRawNonASTExpr(i), i, false, GetInstructionForExpr(i)); } @@ -233,6 +241,134 @@ Ref<BasicBlock> HighLevelILFunction::GetBasicBlockForInstruction(size_t i) const } +Ref<HighLevelILFunction> HighLevelILFunction::GetSSAForm() const +{ + BNHighLevelILFunction* func = BNGetHighLevelILSSAForm(m_object); + if (!func) + return nullptr; + return new HighLevelILFunction(func); +} + + +Ref<HighLevelILFunction> HighLevelILFunction::GetNonSSAForm() const +{ + BNHighLevelILFunction* func = BNGetHighLevelILNonSSAForm(m_object); + if (!func) + return nullptr; + return new HighLevelILFunction(func); +} + + +size_t HighLevelILFunction::GetSSAInstructionIndex(size_t instr) const +{ + return BNGetHighLevelILSSAInstructionIndex(m_object, instr); +} + + +size_t HighLevelILFunction::GetNonSSAInstructionIndex(size_t instr) const +{ + return BNGetHighLevelILNonSSAInstructionIndex(m_object, instr); +} + + +size_t HighLevelILFunction::GetSSAExprIndex(size_t expr) const +{ + return BNGetHighLevelILSSAExprIndex(m_object, expr); +} + + +size_t HighLevelILFunction::GetNonSSAExprIndex(size_t expr) const +{ + return BNGetHighLevelILNonSSAExprIndex(m_object, expr); +} + + +size_t HighLevelILFunction::GetSSAVarDefinition(const SSAVariable& var) const +{ + return BNGetHighLevelILSSAVarDefinition(m_object, &var.var, var.version); +} + + +size_t HighLevelILFunction::GetSSAMemoryDefinition(size_t version) const +{ + return BNGetHighLevelILSSAMemoryDefinition(m_object, version); +} + + +set<size_t> HighLevelILFunction::GetSSAVarUses(const SSAVariable& var) const +{ + size_t count; + size_t* instrs = BNGetHighLevelILSSAVarUses(m_object, &var.var, var.version, &count); + + set<size_t> result; + for (size_t i = 0; i < count; i++) + result.insert(instrs[i]); + + BNFreeILInstructionList(instrs); + return result; +} + + +set<size_t> HighLevelILFunction::GetSSAMemoryUses(size_t version) const +{ + size_t count; + size_t* instrs = BNGetHighLevelILSSAMemoryUses(m_object, version, &count); + + set<size_t> result; + for (size_t i = 0; i < count; i++) + result.insert(instrs[i]); + + BNFreeILInstructionList(instrs); + return result; +} + + +bool HighLevelILFunction::IsSSAVarLive(const SSAVariable& var) const +{ + return BNIsHighLevelILSSAVarLive(m_object, &var.var, var.version); +} + + +set<size_t> HighLevelILFunction::GetVariableDefinitions(const Variable& var) const +{ + size_t count; + size_t* instrs = BNGetHighLevelILVariableDefinitions(m_object, &var, &count); + + set<size_t> result; + for (size_t i = 0; i < count; i++) + result.insert(instrs[i]); + + BNFreeILInstructionList(instrs); + return result; +} + + +set<size_t> HighLevelILFunction::GetVariableUses(const Variable& var) const +{ + size_t count; + size_t* instrs = BNGetHighLevelILVariableUses(m_object, &var, &count); + + set<size_t> result; + for (size_t i = 0; i < count; i++) + result.insert(instrs[i]); + + BNFreeILInstructionList(instrs); + return result; +} + + +size_t HighLevelILFunction::GetSSAVarVersionAtInstruction(const Variable& var, size_t instr) const +{ + return BNGetHighLevelILSSAVarVersionAtILInstruction(m_object, &var, instr); +} + + +size_t HighLevelILFunction::GetSSAMemoryVersionAtInstruction(size_t instr) const +{ + return BNGetHighLevelILSSAMemoryVersionAtILInstruction(m_object, instr); +} + + Ref<MediumLevelILFunction> HighLevelILFunction::GetMediumLevelIL() const { BNMediumLevelILFunction* result = BNGetMediumLevelILForHighLevelILFunction(m_object); diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 609b7f77..610c9e63 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -46,6 +46,7 @@ unordered_map<HighLevelILOperandUsage, HighLevelILOperandType> {CarryExprHighLevelOperandUsage, ExprHighLevelOperand}, {IndexExprHighLevelOperandUsage, ExprHighLevelOperand}, {ConditionExprHighLevelOperandUsage, ExprHighLevelOperand}, + {ConditionPhiExprHighLevelOperandUsage, ExprHighLevelOperand}, {TrueExprHighLevelOperandUsage, ExprHighLevelOperand}, {FalseExprHighLevelOperandUsage, ExprHighLevelOperand}, {LoopExprHighLevelOperandUsage, ExprHighLevelOperand}, @@ -86,9 +87,16 @@ unordered_map<BNHighLevelILOperation, vector<HighLevelILOperandUsage>> {HLIL_IF, {ConditionExprHighLevelOperandUsage, TrueExprHighLevelOperandUsage, FalseExprHighLevelOperandUsage}}, {HLIL_WHILE, {ConditionExprHighLevelOperandUsage, LoopExprHighLevelOperandUsage}}, + {HLIL_WHILE_SSA, {ConditionPhiExprHighLevelOperandUsage, + ConditionExprHighLevelOperandUsage, LoopExprHighLevelOperandUsage}}, {HLIL_DO_WHILE, {LoopExprHighLevelOperandUsage, ConditionExprHighLevelOperandUsage}}, + {HLIL_DO_WHILE_SSA, {LoopExprHighLevelOperandUsage, ConditionPhiExprHighLevelOperandUsage, + ConditionExprHighLevelOperandUsage}}, {HLIL_FOR, {InitExprHighLevelOperandUsage, ConditionExprHighLevelOperandUsage, UpdateExprHighLevelOperandUsage, LoopExprHighLevelOperandUsage}}, + {HLIL_FOR_SSA, {InitExprHighLevelOperandUsage, ConditionPhiExprHighLevelOperandUsage, + ConditionExprHighLevelOperandUsage, UpdateExprHighLevelOperandUsage, + LoopExprHighLevelOperandUsage}}, {HLIL_SWITCH, {ConditionExprHighLevelOperandUsage, DefaultExprHighLevelOperandUsage, CasesHighLevelOperandUsage}}, {HLIL_CASE, {ValueExprsHighLevelOperandUsage, TrueExprHighLevelOperandUsage}}, @@ -394,12 +402,20 @@ HighLevelILIndexList::operator vector<size_t>() const const HighLevelILInstruction HighLevelILInstructionList::ListIterator::operator*() { - return HighLevelILInstruction(pos.GetFunction(), pos.GetFunction()->GetRawExpr((size_t)*pos), (size_t)*pos); + if (ast) + { + return HighLevelILInstruction(pos.GetFunction(), pos.GetFunction()->GetRawExpr((size_t)*pos), + (size_t)*pos, true, instructionIndex); + } + return HighLevelILInstruction(pos.GetFunction(), pos.GetFunction()->GetRawNonASTExpr((size_t)*pos), + (size_t)*pos, false, instructionIndex); } HighLevelILInstructionList::HighLevelILInstructionList(HighLevelILFunction* func, - const BNHighLevelILInstruction& instr, size_t count): m_list(func, instr, count) + const BNHighLevelILInstruction& instr, size_t count, bool asFullAst, + size_t instructionIndex): m_list(func, instr, count), m_ast(asFullAst), + m_instructionIndex(instructionIndex) { } @@ -408,6 +424,8 @@ HighLevelILInstructionList::const_iterator HighLevelILInstructionList::begin() c { const_iterator result; result.pos = m_list.begin(); + result.ast = m_ast; + result.instructionIndex = m_instructionIndex; return result; } @@ -416,6 +434,8 @@ HighLevelILInstructionList::const_iterator HighLevelILInstructionList::end() con { const_iterator result; result.pos = m_list.end(); + result.ast = m_ast; + result.instructionIndex = m_instructionIndex; return result; } @@ -661,7 +681,7 @@ HighLevelILInstruction::HighLevelILInstruction() HighLevelILInstruction::HighLevelILInstruction(HighLevelILFunction* func, - const BNHighLevelILInstruction& instr, size_t expr) + const BNHighLevelILInstruction& instr, size_t expr, bool asFullAst, size_t instrIdx) { operation = instr.operation; sourceOperand = instr.sourceOperand; @@ -675,6 +695,8 @@ HighLevelILInstruction::HighLevelILInstruction(HighLevelILFunction* func, parent = instr.parent; function = func; exprIndex = expr; + instructionIndex = instrIdx; + ast = asFullAst; } @@ -691,6 +713,8 @@ HighLevelILInstruction::HighLevelILInstruction(const HighLevelILInstructionBase& address = instr.address; function = instr.function; exprIndex = instr.exprIndex; + instructionIndex = instr.instructionIndex; + ast = instr.ast; parent = instr.parent; } @@ -721,7 +745,13 @@ size_t HighLevelILInstructionBase::GetRawOperandAsIndex(size_t operand) const HighLevelILInstruction HighLevelILInstructionBase::GetRawOperandAsExpr(size_t operand) const { - return HighLevelILInstruction(function, function->GetRawExpr(operands[operand]), operands[operand]); + if (ast) + { + return HighLevelILInstruction(function, function->GetRawExpr(operands[operand]), + operands[operand], true, instructionIndex); + } + return HighLevelILInstruction(function, function->GetRawNonASTExpr(operands[operand]), + operands[operand], false, instructionIndex); } @@ -739,7 +769,8 @@ SSAVariable HighLevelILInstructionBase::GetRawOperandAsSSAVariable(size_t operan HighLevelILInstructionList HighLevelILInstructionBase::GetRawOperandAsExprList(size_t operand) const { - return HighLevelILInstructionList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); + return HighLevelILInstructionList(function, function->GetRawExpr(operands[operand + 1]), + operands[operand], ast, instructionIndex); } @@ -865,6 +896,30 @@ HighLevelILInstruction HighLevelILInstructionBase::GetInstruction() const } +HighLevelILInstruction HighLevelILInstructionBase::AsAST() const +{ + return function->GetExpr(exprIndex, true); +} + + +HighLevelILInstruction HighLevelILInstructionBase::AsNonAST() const +{ + return function->GetExpr(exprIndex, false); +} + + +bool HighLevelILInstructionBase::HasParent() const +{ + return parent != BN_INVALID_EXPR; +} + + +HighLevelILInstruction HighLevelILInstructionBase::GetParent() const +{ + return function->GetExpr(parent, true); +} + + void HighLevelILInstruction::VisitExprs(const std::function<bool(const HighLevelILInstruction& expr)>& func) const { stack<size_t> toProcess; @@ -873,7 +928,7 @@ void HighLevelILInstruction::VisitExprs(const std::function<bool(const HighLevel toProcess.push(exprIndex); while (!toProcess.empty()) { - HighLevelILInstruction cur = function->GetExpr(toProcess.top()); + HighLevelILInstruction cur = function->GetExpr(toProcess.top(), ast); toProcess.pop(); if (!func(cur)) continue; @@ -885,29 +940,58 @@ void HighLevelILInstruction::VisitExprs(const std::function<bool(const HighLevel toProcess.push(i->exprIndex); break; case HLIL_IF: - toProcess.push(cur.GetFalseExpr<HLIL_IF>().exprIndex); - toProcess.push(cur.GetTrueExpr<HLIL_IF>().exprIndex); + if (ast) + { + toProcess.push(cur.GetFalseExpr<HLIL_IF>().exprIndex); + toProcess.push(cur.GetTrueExpr<HLIL_IF>().exprIndex); + } toProcess.push(cur.GetConditionExpr<HLIL_IF>().exprIndex); break; case HLIL_WHILE: - toProcess.push(cur.GetLoopExpr<HLIL_WHILE>().exprIndex); + if (ast) + toProcess.push(cur.GetLoopExpr<HLIL_WHILE>().exprIndex); toProcess.push(cur.GetConditionExpr<HLIL_WHILE>().exprIndex); break; + case HLIL_WHILE_SSA: + if (ast) + toProcess.push(cur.GetLoopExpr<HLIL_WHILE_SSA>().exprIndex); + toProcess.push(cur.GetConditionExpr<HLIL_WHILE_SSA>().exprIndex); + toProcess.push(cur.GetConditionPhiExpr<HLIL_WHILE_SSA>().exprIndex); + break; case HLIL_DO_WHILE: toProcess.push(cur.GetConditionExpr<HLIL_DO_WHILE>().exprIndex); - toProcess.push(cur.GetLoopExpr<HLIL_DO_WHILE>().exprIndex); + if (ast) + toProcess.push(cur.GetLoopExpr<HLIL_DO_WHILE>().exprIndex); + break; + case HLIL_DO_WHILE_SSA: + toProcess.push(cur.GetConditionExpr<HLIL_DO_WHILE_SSA>().exprIndex); + toProcess.push(cur.GetConditionPhiExpr<HLIL_DO_WHILE_SSA>().exprIndex); + if (ast) + toProcess.push(cur.GetLoopExpr<HLIL_DO_WHILE_SSA>().exprIndex); break; case HLIL_FOR: - toProcess.push(cur.GetLoopExpr<HLIL_FOR>().exprIndex); + if (ast) + toProcess.push(cur.GetLoopExpr<HLIL_FOR>().exprIndex); toProcess.push(cur.GetUpdateExpr<HLIL_FOR>().exprIndex); toProcess.push(cur.GetConditionExpr<HLIL_FOR>().exprIndex); toProcess.push(cur.GetInitExpr<HLIL_FOR>().exprIndex); break; + case HLIL_FOR_SSA: + if (ast) + toProcess.push(cur.GetLoopExpr<HLIL_FOR_SSA>().exprIndex); + toProcess.push(cur.GetUpdateExpr<HLIL_FOR_SSA>().exprIndex); + toProcess.push(cur.GetConditionExpr<HLIL_FOR_SSA>().exprIndex); + toProcess.push(cur.GetConditionPhiExpr<HLIL_FOR_SSA>().exprIndex); + toProcess.push(cur.GetInitExpr<HLIL_FOR_SSA>().exprIndex); + break; case HLIL_SWITCH: - exprs = cur.GetCases<HLIL_SWITCH>(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - toProcess.push(cur.GetDefaultExpr<HLIL_SWITCH>().exprIndex); + if (ast) + { + exprs = cur.GetCases<HLIL_SWITCH>(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + toProcess.push(cur.GetDefaultExpr<HLIL_SWITCH>().exprIndex); + } toProcess.push(cur.GetConditionExpr<HLIL_SWITCH>().exprIndex); break; case HLIL_CASE: @@ -1120,13 +1204,27 @@ ExprId HighLevelILInstruction::CopyTo(HighLevelILFunction* dest, case HLIL_WHILE: return dest->While(subExprHandler(GetConditionExpr<HLIL_WHILE>()), subExprHandler(GetLoopExpr<HLIL_WHILE>()), *this); + case HLIL_WHILE_SSA: + return dest->WhileSSA(subExprHandler(GetConditionPhiExpr<HLIL_WHILE_SSA>()), + subExprHandler(GetConditionExpr<HLIL_WHILE_SSA>()), + subExprHandler(GetLoopExpr<HLIL_WHILE_SSA>()), *this); case HLIL_DO_WHILE: return dest->DoWhile(subExprHandler(GetLoopExpr<HLIL_DO_WHILE>()), subExprHandler(GetConditionExpr<HLIL_DO_WHILE>()), *this); + case HLIL_DO_WHILE_SSA: + return dest->DoWhileSSA(subExprHandler(GetLoopExpr<HLIL_DO_WHILE_SSA>()), + subExprHandler(GetConditionPhiExpr<HLIL_DO_WHILE_SSA>()), + subExprHandler(GetConditionExpr<HLIL_DO_WHILE_SSA>()), *this); case HLIL_FOR: return dest->For(subExprHandler(GetInitExpr<HLIL_FOR>()), subExprHandler(GetConditionExpr<HLIL_FOR>()), subExprHandler(GetUpdateExpr<HLIL_FOR>()), subExprHandler(GetLoopExpr<HLIL_FOR>()), *this); + case HLIL_FOR_SSA: + return dest->ForSSA(subExprHandler(GetInitExpr<HLIL_FOR_SSA>()), + subExprHandler(GetConditionPhiExpr<HLIL_FOR_SSA>()), + subExprHandler(GetConditionExpr<HLIL_FOR_SSA>()), + subExprHandler(GetUpdateExpr<HLIL_FOR_SSA>()), + subExprHandler(GetLoopExpr<HLIL_FOR_SSA>()), *this); case HLIL_SWITCH: for (auto& i : GetCases<HLIL_SWITCH>()) params.push_back(subExprHandler(i)); @@ -1387,12 +1485,32 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons if (other.GetConditionExpr<HLIL_WHILE>() < GetConditionExpr<HLIL_WHILE>()) return false; return GetLoopExpr<HLIL_WHILE>() < other.GetLoopExpr<HLIL_WHILE>(); + case HLIL_WHILE_SSA: + if (GetConditionPhiExpr<HLIL_WHILE_SSA>() < other.GetConditionPhiExpr<HLIL_WHILE_SSA>()) + return true; + if (other.GetConditionPhiExpr<HLIL_WHILE_SSA>() < GetConditionPhiExpr<HLIL_WHILE_SSA>()) + return false; + 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_DO_WHILE_SSA: + if (GetLoopExpr<HLIL_DO_WHILE_SSA>() < other.GetLoopExpr<HLIL_DO_WHILE_SSA>()) + return true; + if (other.GetLoopExpr<HLIL_DO_WHILE_SSA>() < GetLoopExpr<HLIL_DO_WHILE_SSA>()) + return false; + if (GetConditionPhiExpr<HLIL_DO_WHILE_SSA>() < other.GetConditionPhiExpr<HLIL_DO_WHILE_SSA>()) + return true; + if (other.GetConditionPhiExpr<HLIL_DO_WHILE_SSA>() < GetConditionPhiExpr<HLIL_DO_WHILE_SSA>()) + return false; + return GetConditionExpr<HLIL_DO_WHILE_SSA>() < other.GetConditionExpr<HLIL_DO_WHILE_SSA>(); case HLIL_FOR: if (GetInitExpr<HLIL_FOR>() < other.GetInitExpr<HLIL_FOR>()) return true; @@ -1407,6 +1525,24 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons if (other.GetUpdateExpr<HLIL_FOR>() < GetUpdateExpr<HLIL_FOR>()) return false; return GetLoopExpr<HLIL_FOR>() < other.GetLoopExpr<HLIL_FOR>(); + case HLIL_FOR_SSA: + if (GetInitExpr<HLIL_FOR_SSA>() < other.GetInitExpr<HLIL_FOR_SSA>()) + return true; + if (other.GetInitExpr<HLIL_FOR_SSA>() < GetInitExpr<HLIL_FOR_SSA>()) + return false; + if (GetConditionPhiExpr<HLIL_FOR_SSA>() < other.GetConditionPhiExpr<HLIL_FOR_SSA>()) + return true; + if (other.GetConditionPhiExpr<HLIL_FOR_SSA>() < GetConditionPhiExpr<HLIL_FOR_SSA>()) + return false; + if (GetConditionExpr<HLIL_FOR_SSA>() < other.GetConditionExpr<HLIL_FOR_SSA>()) + return true; + if (other.GetConditionExpr<HLIL_FOR_SSA>() < GetConditionExpr<HLIL_FOR_SSA>()) + return false; + if (GetUpdateExpr<HLIL_FOR_SSA>() < other.GetUpdateExpr<HLIL_FOR_SSA>()) + return true; + if (other.GetUpdateExpr<HLIL_FOR_SSA>() < GetUpdateExpr<HLIL_FOR_SSA>()) + return false; + return GetLoopExpr<HLIL_FOR_SSA>() < other.GetLoopExpr<HLIL_FOR_SSA>(); case HLIL_SWITCH: if (GetConditionExpr<HLIL_SWITCH>() < other.GetConditionExpr<HLIL_SWITCH>()) return true; @@ -1946,6 +2082,15 @@ HighLevelILInstruction HighLevelILInstruction::GetConditionExpr() const } +HighLevelILInstruction HighLevelILInstruction::GetConditionPhiExpr() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(ConditionPhiExprHighLevelOperandUsage, operandIndex)) + return GetRawOperandAsExpr(operandIndex); + throw HighLevelILInstructionAccessException(); +} + + HighLevelILInstruction HighLevelILInstruction::GetTrueExpr() const { size_t operandIndex; @@ -2187,12 +2332,26 @@ ExprId HighLevelILFunction::While(ExprId condition, ExprId loopExpr, const ILSou } +ExprId HighLevelILFunction::WhileSSA(ExprId conditionPhi, ExprId condition, ExprId loopExpr, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_WHILE_SSA, loc, 0, conditionPhi, condition, loopExpr); +} + + ExprId HighLevelILFunction::DoWhile(ExprId loopExpr, ExprId condition, const ILSourceLocation& loc) { return AddExprWithLocation(HLIL_DO_WHILE, loc, 0, loopExpr, condition); } +ExprId HighLevelILFunction::DoWhileSSA(ExprId loopExpr, ExprId conditionPhi, ExprId condition, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_DO_WHILE_SSA, loc, 0, loopExpr, conditionPhi, condition); +} + + ExprId HighLevelILFunction::For(ExprId initExpr, ExprId condition, ExprId updateExpr, ExprId loopExpr, const ILSourceLocation& loc) { @@ -2200,6 +2359,13 @@ ExprId HighLevelILFunction::For(ExprId initExpr, ExprId condition, ExprId update } +ExprId HighLevelILFunction::ForSSA(ExprId initExpr, ExprId conditionPhi, ExprId condition, + ExprId updateExpr, ExprId loopExpr, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_FOR_SSA, loc, 0, initExpr, conditionPhi, condition, updateExpr, loopExpr); +} + + ExprId HighLevelILFunction::Switch(ExprId condition, ExprId defaultExpr, const std::vector<ExprId>& cases, const ILSourceLocation& loc) { diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index 967bafec..aa872e67 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -77,6 +77,7 @@ namespace BinaryNinja CarryExprHighLevelOperandUsage, IndexExprHighLevelOperandUsage, ConditionExprHighLevelOperandUsage, + ConditionPhiExprHighLevelOperandUsage, TrueExprHighLevelOperandUsage, FalseExprHighLevelOperandUsage, LoopExprHighLevelOperandUsage, @@ -214,8 +215,9 @@ namespace BinaryNinja { struct ListIterator { - size_t instructionIndex; HighLevelILIntegerList::const_iterator pos; + bool ast; + size_t instructionIndex; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } @@ -224,11 +226,14 @@ namespace BinaryNinja }; HighLevelILIntegerList m_list; + bool m_ast; + size_t m_instructionIndex; public: typedef ListIterator const_iterator; - HighLevelILInstructionList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count); + HighLevelILInstructionList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, + size_t count, bool asFullAst, size_t instructionIndex); const_iterator begin() const; const_iterator end() const; @@ -272,7 +277,8 @@ namespace BinaryNinja #else Ref<HighLevelILFunction> function; #endif - size_t exprIndex; + size_t exprIndex, instructionIndex; + bool ast; static std::unordered_map<HighLevelILOperandUsage, HighLevelILOperandType> operandTypeForUsage; static std::unordered_map<BNHighLevelILOperation, @@ -311,6 +317,12 @@ namespace BinaryNinja size_t GetInstructionIndex() const; HighLevelILInstruction GetInstruction() const; + HighLevelILInstruction AsAST() const; + HighLevelILInstruction AsNonAST() const; + + bool HasParent() const; + HighLevelILInstruction GetParent() const; + template <BNHighLevelILOperation N> HighLevelILInstructionAccessor<N>& As() { @@ -359,7 +371,8 @@ namespace BinaryNinja struct HighLevelILInstruction: public HighLevelILInstructionBase { HighLevelILInstruction(); - HighLevelILInstruction(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t expr); + HighLevelILInstruction(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, + size_t expr, bool asFullAst, size_t instructionIndex); HighLevelILInstruction(const HighLevelILInstructionBase& instr); void VisitExprs(const std::function<bool(const HighLevelILInstruction& expr)>& func) const; @@ -383,6 +396,7 @@ namespace BinaryNinja template <BNHighLevelILOperation N> HighLevelILInstruction GetRightExpr() const { return As<N>().GetRightExpr(); } template <BNHighLevelILOperation N> HighLevelILInstruction GetCarryExpr() const { return As<N>().GetCarryExpr(); } template <BNHighLevelILOperation N> HighLevelILInstruction GetIndexExpr() const { return As<N>().GetIndexExpr(); } + template <BNHighLevelILOperation N> HighLevelILInstruction GetConditionPhiExpr() const { return As<N>().GetConditionPhiExpr(); } template <BNHighLevelILOperation N> HighLevelILInstruction GetConditionExpr() const { return As<N>().GetConditionExpr(); } template <BNHighLevelILOperation N> HighLevelILInstruction GetTrueExpr() const { return As<N>().GetTrueExpr(); } template <BNHighLevelILOperation N> HighLevelILInstruction GetFalseExpr() const { return As<N>().GetFalseExpr(); } @@ -410,6 +424,7 @@ namespace BinaryNinja template <BNHighLevelILOperation N> size_t GetDestMemoryVersion() const { return As<N>().GetDestMemoryVersion(); } template <BNHighLevelILOperation N> void SetSSAVersion(size_t version) { As<N>().SetSSAVersion(version); } + template <BNHighLevelILOperation N> void SetDestSSAVersion(size_t version) { As<N>().SetDestSSAVersion(version); } template <BNHighLevelILOperation N> void SetParameterExprs(const std::vector<MediumLevelILInstruction>& params) { As<N>().SetParameterExprs(params); } template <BNHighLevelILOperation N> void SetParameterExprs(const std::vector<ExprId>& params) { As<N>().SetParameterExprs(params); } template <BNHighLevelILOperation N> void SetSourceExprs(const std::vector<MediumLevelILInstruction>& params) { As<N>().SetSourceExprs(params); } @@ -439,6 +454,7 @@ namespace BinaryNinja HighLevelILInstruction GetCarryExpr() const; HighLevelILInstruction GetIndexExpr() const; HighLevelILInstruction GetConditionExpr() const; + HighLevelILInstruction GetConditionPhiExpr() const; HighLevelILInstruction GetTrueExpr() const; HighLevelILInstruction GetFalseExpr() const; HighLevelILInstruction GetLoopExpr() const; @@ -563,11 +579,23 @@ namespace BinaryNinja HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(0); } HighLevelILInstruction GetLoopExpr() const { return GetRawOperandAsExpr(1); } }; + template <> struct HighLevelILInstructionAccessor<HLIL_WHILE_SSA>: public HighLevelILInstructionBase + { + HighLevelILInstruction GetConditionPhiExpr() const { return GetRawOperandAsExpr(0); } + HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(1); } + HighLevelILInstruction GetLoopExpr() const { return GetRawOperandAsExpr(2); } + }; template <> struct HighLevelILInstructionAccessor<HLIL_DO_WHILE>: public HighLevelILInstructionBase { HighLevelILInstruction GetLoopExpr() const { return GetRawOperandAsExpr(0); } HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(1); } }; + template <> struct HighLevelILInstructionAccessor<HLIL_DO_WHILE_SSA>: public HighLevelILInstructionBase + { + HighLevelILInstruction GetLoopExpr() const { return GetRawOperandAsExpr(0); } + HighLevelILInstruction GetConditionPhiExpr() const { return GetRawOperandAsExpr(1); } + HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(2); } + }; template <> struct HighLevelILInstructionAccessor<HLIL_FOR>: public HighLevelILInstructionBase { HighLevelILInstruction GetInitExpr() const { return GetRawOperandAsExpr(0); } @@ -575,6 +603,14 @@ namespace BinaryNinja HighLevelILInstruction GetUpdateExpr() const { return GetRawOperandAsExpr(2); } HighLevelILInstruction GetLoopExpr() const { return GetRawOperandAsExpr(3); } }; + template <> struct HighLevelILInstructionAccessor<HLIL_FOR_SSA>: public HighLevelILInstructionBase + { + HighLevelILInstruction GetInitExpr() const { return GetRawOperandAsExpr(0); } + HighLevelILInstruction GetConditionPhiExpr() const { return GetRawOperandAsExpr(1); } + HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(2); } + HighLevelILInstruction GetUpdateExpr() const { return GetRawOperandAsExpr(3); } + HighLevelILInstruction GetLoopExpr() const { return GetRawOperandAsExpr(4); } + }; template <> struct HighLevelILInstructionAccessor<HLIL_SWITCH>: public HighLevelILInstructionBase { HighLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(0); } @@ -614,7 +650,7 @@ namespace BinaryNinja { SSAVariable GetDestSSAVariable() const { return GetRawOperandAsSSAVariable(0); } void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } - HighLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } + HighLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } }; template <> struct HighLevelILInstructionAccessor<HLIL_ASSIGN>: public HighLevelILInstructionBase { diff --git a/linearviewobject.cpp b/linearviewobject.cpp index b12038d7..1a563b9e 100644 --- a/linearviewobject.cpp +++ b/linearviewobject.cpp @@ -260,3 +260,10 @@ Ref<LinearViewObject> LinearViewObject::CreateHighLevelIL(BinaryView* view, Disa return new LinearViewObject(BNCreateLinearViewHighLevelIL(view->GetObject(), settings ? settings->GetObject() : nullptr)); } + + +Ref<LinearViewObject> LinearViewObject::CreateHighLevelILSSAForm(BinaryView* view, DisassemblySettings* settings) +{ + return new LinearViewObject(BNCreateLinearViewHighLevelILSSAForm(view->GetObject(), + settings ? settings->GetObject() : nullptr)); +} diff --git a/python/highlevelil.py b/python/highlevelil.py index b31bc0cc..6565253d 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -83,8 +83,11 @@ class HighLevelILInstruction(object): HighLevelILOperation.HLIL_BLOCK: [("body", "expr_list")], HighLevelILOperation.HLIL_IF: [("condition", "expr"), ("true", "expr"), ("false", "expr")], HighLevelILOperation.HLIL_WHILE: [("condition", "expr"), ("body", "expr")], + HighLevelILOperation.HLIL_WHILE_SSA: [("condition_phi", "expr"), ("condition", "expr"), ("body", "expr")], HighLevelILOperation.HLIL_DO_WHILE: [("body", "expr"), ("condition", "expr")], + HighLevelILOperation.HLIL_DO_WHILE_SSA: [("body", "expr"), ("condition_phi", "expr"), ("condition", "expr")], HighLevelILOperation.HLIL_FOR: [("init", "expr"), ("condition", "expr"), ("update", "expr"), ("body", "expr")], + HighLevelILOperation.HLIL_FOR_SSA: [("init", "expr"), ("condition_phi", "expr"), ("condition", "expr"), ("update", "expr"), ("body", "expr")], HighLevelILOperation.HLIL_SWITCH: [("condition", "expr"), ("default", "expr"), ("cases", "expr_list")], HighLevelILOperation.HLIL_CASE: [("values", "expr_list"), ("body", "expr")], HighLevelILOperation.HLIL_BREAK: [], @@ -198,10 +201,14 @@ class HighLevelILInstruction(object): HighLevelILOperation.HLIL_FCMP_UO: [("left", "expr"), ("right", "expr")] } - def __init__(self, func, expr_index, as_ast = True): - instr = core.BNGetHighLevelILByIndex(func.handle, expr_index) + def __init__(self, func, expr_index, as_ast = True, instr_index = None): + instr = core.BNGetHighLevelILByIndex(func.handle, expr_index, as_ast) self._function = func self._expr_index = expr_index + if instr_index is None: + self._instr_index = core.BNGetHighLevelILInstructionForExpr(func.handle, expr_index) + else: + self._instr_index = instr_index self._operation = HighLevelILOperation(instr.operation) self._size = instr.size self._address = instr.address @@ -383,7 +390,7 @@ class HighLevelILInstruction(object): @property def non_ast(self): """This expression without full AST printing (read-only)""" - if self._as_ast: + if not self._as_ast: return self return HighLevelILInstruction(self._function, self._expr_index, False) @@ -439,6 +446,28 @@ class HighLevelILInstruction(object): return HighLevelILInstruction(self._function, self._parent, self._as_ast) @property + def instr_index(self): + """ """ + return self._instr_index + + @property + def instr(self): + """High level IL instruction that contains this expression""" + return self._function[self._instr_index] + + @property + def ssa_form(self): + """SSA form of expression (read-only)""" + return HighLevelILInstruction(self._function.ssa_form, + core.BNGetHighLevelILSSAExprIndex(self._function.handle, self._expr_index), self._as_ast) + + @property + def non_ssa_form(self): + """Non-SSA form of expression (read-only)""" + return HighLevelILInstruction(self._function.non_ssa_form, + core.BNGetHighLevelILNonSSAExprIndex(self._function.handle, self._expr_index), self._as_ast) + + @property def medium_level_il(self): """Medium level IL form of this expression""" expr = self._function.get_medium_level_il_expr_index(self._expr_index) @@ -489,6 +518,18 @@ class HighLevelILInstruction(object): return function.RegisterValue() return mlil.get_possible_values(options) + @property + def ssa_memory_version(self): + """Version of active memory contents in SSA form for this instruction""" + return core.BNGetHighLevelILSSAMemoryVersionAtILInstruction(self._function.handle, self._instr_index) + + def get_ssa_var_version(self, var): + var_data = core.BNVariable() + var_data.type = var.source_type + var_data.index = var.index + var_data.storage = var.storage + return core.BNGetHighLevelILSSAVarVersionAtILInstruction(self._function.handle, var_data, self._instr_index) + class HighLevelILExpr(object): """ @@ -597,6 +638,106 @@ class HighLevelILFunction(object): for i in block: yield i + @property + def ssa_form(self): + """High level IL in SSA form (read-only)""" + result = core.BNGetHighLevelILSSAForm(self.handle) + if not result: + return None + return HighLevelILFunction(self._arch, result, self._source_function) + + @property + def non_ssa_form(self): + """High level IL in non-SSA (default) form (read-only)""" + result = core.BNGetHighLevelILNonSSAForm(self.handle) + if not result: + return None + return HighLevelILFunction(self._arch, result, self._source_function) + + def get_ssa_instruction_index(self, instr): + return core.BNGetHighLevelILSSAInstructionIndex(self.handle, instr) + + def get_non_ssa_instruction_index(self, instr): + return core.BNGetHighLevelILNonSSAInstructionIndex(self.handle, instr) + + def get_ssa_var_definition(self, ssa_var): + var_data = core.BNVariable() + var_data.type = ssa_var.var.source_type + var_data.index = ssa_var.var.index + var_data.storage = ssa_var.var.storage + result = core.BNGetHighLevelILSSAVarDefinition(self.handle, var_data, ssa_var.version) + if result >= core.BNGetHighLevelILExprCount(self.handle): + return None + return HighLevelILInstruction(self, result) + + def get_ssa_memory_definition(self, version): + result = core.BNGetHighLevelILSSAMemoryDefinition(self.handle, version) + if result >= core.BNGetHighLevelILExprCount(self.handle): + return None + return HighLevelILInstruction(self, result) + + def get_ssa_var_uses(self, ssa_var): + count = ctypes.c_ulonglong() + var_data = core.BNVariable() + var_data.type = ssa_var.var.source_type + var_data.index = ssa_var.var.index + var_data.storage = ssa_var.var.storage + instrs = core.BNGetHighLevelILSSAVarUses(self.handle, var_data, ssa_var.version, count) + result = [] + for i in range(0, count.value): + result.append(HighLevelILInstruction(self, instrs[i])) + core.BNFreeILInstructionList(instrs) + return result + + def get_ssa_memory_uses(self, version): + count = ctypes.c_ulonglong() + instrs = core.BNGetHighLevelILSSAMemoryUses(self.handle, version, count) + result = [] + for i in range(0, count.value): + result.append(HighLevelILInstruction(self, instrs[i])) + core.BNFreeILInstructionList(instrs) + return result + + def is_ssa_var_live(self, ssa_var): + """ + ``is_ssa_var_live`` determines if ``ssa_var`` is live at any point in the function + + :param SSAVariable ssa_var: the SSA variable to query + :return: whether the variable is live at any point in the function + :rtype: bool + """ + var_data = core.BNVariable() + var_data.type = ssa_var.var.source_type + var_data.index = ssa_var.var.index + var_data.storage = ssa_var.var.storage + return core.BNIsHighLevelILSSAVarLive(self.handle, var_data, ssa_var.version) + + def get_var_definitions(self, var): + count = ctypes.c_ulonglong() + var_data = core.BNVariable() + var_data.type = var.source_type + var_data.index = var.index + var_data.storage = var.storage + instrs = core.BNGetHighLevelILVariableDefinitions(self.handle, var_data, count) + result = [] + for i in range(0, count.value): + result.append(HighLevelILInstruction(self, instrs[i])) + core.BNFreeILInstructionList(instrs) + return result + + def get_var_uses(self, var): + count = ctypes.c_ulonglong() + var_data = core.BNVariable() + var_data.type = var.source_type + var_data.index = var.index + var_data.storage = var.storage + instrs = core.BNGetHighLevelILVariableUses(self.handle, var_data, count) + result = [] + for i in range(0, count.value): + result.append(HighLevelILInstruction(self, instrs[i])) + core.BNFreeILInstructionList(instrs) + return result + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -616,7 +757,7 @@ class HighLevelILFunction(object): return i if (i < 0) or (i >= len(self)): raise IndexError("index out of range") - return HighLevelILInstruction(self, core.BNGetHighLevelILIndexForInstruction(self.handle, i), False) + return HighLevelILInstruction(self, core.BNGetHighLevelILIndexForInstruction(self.handle, i), False, i) def __setitem__(self, i, j): raise IndexError("instruction modification not implemented") diff --git a/python/lineardisassembly.py b/python/lineardisassembly.py index 10124bad..4435acdc 100644 --- a/python/lineardisassembly.py +++ b/python/lineardisassembly.py @@ -306,6 +306,12 @@ class LinearViewObject(object): settings = settings.handle return LinearViewObject(core.BNCreateLinearViewHighLevelIL(view.handle, settings)) + @classmethod + def hlil_ssa_form(cls, view, settings = None): + if settings is not None: + settings = settings.handle + return LinearViewObject(core.BNCreateLinearViewHighLevelILSSAForm(view.handle, settings)) + class LinearViewCursor(object): def __init__(self, root_object, handle = None): |
