diff options
| -rw-r--r-- | binaryninjaapi.h | 10 | ||||
| -rw-r--r-- | binaryninjacore.h | 7 | ||||
| -rw-r--r-- | function.cpp | 15 | ||||
| -rw-r--r-- | highlevelil.cpp | 20 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 15 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 12 | ||||
| -rw-r--r-- | python/highlevelil.py | 53 | ||||
| -rw-r--r-- | ui/flowgraphwidget.h | 1 | ||||
| -rw-r--r-- | ui/linearview.h | 1 | ||||
| -rw-r--r-- | ui/theme.h | 1 |
10 files changed, 123 insertions, 12 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 7a864b58..af68eafd 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -3144,6 +3144,9 @@ __attribute__ ((format (printf, 1, 2))) Ref<FlowGraph> GetUnresolvedStackAdjustmentGraph(); void RequestDebugReport(const std::string& name); + + std::string GetGotoLabelName(uint64_t labelId); + void SetGotoLabelName(uint64_t labelId, const std::string& name); }; class AdvancedFunctionAnalysisDataRequestor @@ -4070,8 +4073,8 @@ __attribute__ ((format (printf, 1, 2))) ExprId Jump(ExprId dest, const ILSourceLocation& loc = ILSourceLocation()); ExprId Return(const std::vector<ExprId>& sources, const ILSourceLocation& loc = ILSourceLocation()); ExprId NoReturn(const ILSourceLocation& loc = ILSourceLocation()); - ExprId Goto(size_t target, const ILSourceLocation& loc = ILSourceLocation()); - ExprId Label(size_t target, const ILSourceLocation& loc = ILSourceLocation()); + ExprId Goto(uint64_t target, const ILSourceLocation& loc = ILSourceLocation()); + ExprId Label(uint64_t target, const ILSourceLocation& loc = ILSourceLocation()); ExprId VarDeclare(const Variable& var, const ILSourceLocation& loc = ILSourceLocation()); ExprId VarInit(size_t size, const Variable& dest, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); @@ -4280,6 +4283,9 @@ __attribute__ ((format (printf, 1, 2))) void VisitAllExprs(const std::function<bool(const HighLevelILInstruction& expr)>& func); Ref<FlowGraph> CreateFunctionGraph(DisassemblySettings* settings = nullptr); + + size_t GetExprIndexForLabel(uint64_t label); + std::set<size_t> GetUsesForLabel(uint64_t label); }; class FunctionRecognizer diff --git a/binaryninjacore.h b/binaryninjacore.h index 0632b62d..b1a615f5 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -254,6 +254,7 @@ extern "C" StructOffsetToken = 25, StructOffsetByteValueToken = 26, StructureHexDumpTextToken = 27, + GotoLabelToken = 28, // The following are output by the analysis system automatically, these should // not be used directly by the architecture plugins CodeSymbolToken = 64, @@ -3106,6 +3107,9 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI BNFunctionAnalysisSkipOverride BNGetFunctionAnalysisSkipOverride(BNFunction* func); BINARYNINJACOREAPI void BNSetFunctionAnalysisSkipOverride(BNFunction* func, BNFunctionAnalysisSkipOverride skip); + BINARYNINJACOREAPI char* BNGetGotoLabelName(BNFunction* func, uint64_t labelId); + BINARYNINJACOREAPI void BNSetUserGotoLabelName(BNFunction* func, uint64_t labelId, const char* name); + BINARYNINJACOREAPI BNAnalysisParameters BNGetParametersForAnalysis(BNBinaryView* view); BINARYNINJACOREAPI void BNSetParametersForAnalysis(BNBinaryView* view, BNAnalysisParameters params); BINARYNINJACOREAPI uint64_t BNGetMaxFunctionSizeForAnalysis(BNBinaryView* view); @@ -3808,6 +3812,9 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI size_t BNGetHighLevelILSSAMemoryVersionAtILInstruction(BNHighLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetHighLevelILExprIndexForLabel(BNHighLevelILFunction* func, uint64_t label); + BINARYNINJACOREAPI size_t* BNGetHighLevelILUsesForLabel(BNHighLevelILFunction* func, uint64_t label, size_t* count); + // Type Libraries BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibrary(BNArchitecture* arch, const char* name); BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibraryReference(BNTypeLibrary* lib); diff --git a/function.cpp b/function.cpp index 304a59e2..e4e8af17 100644 --- a/function.cpp +++ b/function.cpp @@ -1718,6 +1718,21 @@ void Function::RequestDebugReport(const string& name) } +string Function::GetGotoLabelName(uint64_t labelId) +{ + char* name = BNGetGotoLabelName(m_object, labelId); + string result = name; + BNFreeString(name); + return result; +} + + +void Function::SetGotoLabelName(uint64_t labelId, const std::string& name) +{ + BNSetUserGotoLabelName(m_object, labelId, name.c_str()); +} + + AdvancedFunctionAnalysisDataRequestor::AdvancedFunctionAnalysisDataRequestor(Function* func): m_func(func) { if (m_func) diff --git a/highlevelil.cpp b/highlevelil.cpp index f97b11d3..264af7c3 100644 --- a/highlevelil.cpp +++ b/highlevelil.cpp @@ -460,3 +460,23 @@ Ref<FlowGraph> HighLevelILFunction::CreateFunctionGraph(DisassemblySettings* set BNFlowGraph* graph = BNCreateHighLevelILFunctionGraph(m_object, settings ? settings->GetObject() : nullptr); return new CoreFlowGraph(graph); } + + +size_t HighLevelILFunction::GetExprIndexForLabel(uint64_t label) +{ + return BNGetHighLevelILExprIndexForLabel(m_object, label); +} + + +set<size_t> HighLevelILFunction::GetUsesForLabel(uint64_t label) +{ + size_t count; + size_t* uses = BNGetHighLevelILUsesForLabel(m_object, label, &count); + + set<size_t> result; + for (size_t i = 0; i < count; i++) + result.insert(uses[i]); + + BNFreeILInstructionList(uses); + return result; +} diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index b5c3e7ed..88f833e0 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -793,6 +793,13 @@ void HighLevelILInstructionBase::UpdateRawOperand(size_t operandIndex, ExprId va } +void HighLevelILInstructionBase::UpdateRawOperandAsInteger(size_t operandIndex, uint64_t value) +{ + operands[operandIndex] = value; + function->UpdateInstructionOperand(exprIndex, operandIndex, value); +} + + void HighLevelILInstructionBase::UpdateRawOperandAsExprList(size_t operandIndex, const vector<HighLevelILInstruction>& exprs) { vector<ExprId> exprIndexList; @@ -2208,11 +2215,11 @@ uint32_t HighLevelILInstruction::GetIntrinsic() const } -size_t HighLevelILInstruction::GetTarget() const +uint64_t HighLevelILInstruction::GetTarget() const { size_t operandIndex; if (GetOperandIndexForUsage(TargetHighLevelOperandUsage, operandIndex)) - return GetRawOperandAsIndex(operandIndex); + return GetRawOperandAsInteger(operandIndex); throw HighLevelILInstructionAccessException(); } @@ -2410,13 +2417,13 @@ ExprId HighLevelILFunction::NoReturn(const ILSourceLocation& loc) } -ExprId HighLevelILFunction::Goto(size_t target, const ILSourceLocation& loc) +ExprId HighLevelILFunction::Goto(uint64_t target, const ILSourceLocation& loc) { return AddExprWithLocation(HLIL_GOTO, loc, 0, target); } -ExprId HighLevelILFunction::Label(size_t target, const ILSourceLocation& loc) +ExprId HighLevelILFunction::Label(uint64_t target, const ILSourceLocation& loc) { return AddExprWithLocation(HLIL_LABEL, loc, 0, target); } diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index aa872e67..fd140e24 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -298,6 +298,7 @@ namespace BinaryNinja HighLevelILIndexList GetRawOperandAsIndexList(size_t operand) const; void UpdateRawOperand(size_t operandIndex, ExprId value); + void UpdateRawOperandAsInteger(size_t operandIndex, uint64_t value); void UpdateRawOperandAsSSAVariableList(size_t operandIndex, const std::vector<SSAVariable>& vars); void UpdateRawOperandAsExprList(size_t operandIndex, const std::vector<HighLevelILInstruction>& exprs); void UpdateRawOperandAsExprList(size_t operandIndex, const std::vector<size_t>& exprs); @@ -411,7 +412,7 @@ namespace BinaryNinja template <BNHighLevelILOperation N> int64_t GetConstant() const { return As<N>().GetConstant(); } template <BNHighLevelILOperation N> int64_t GetVector() const { return As<N>().GetVector(); } template <BNHighLevelILOperation N> uint32_t GetIntrinsic() const { return As<N>().GetIntrinsic(); } - template <BNHighLevelILOperation N> size_t GetTarget() const { return As<N>().GetTarget(); } + template <BNHighLevelILOperation N> uint64_t GetTarget() const { return As<N>().GetTarget(); } template <BNHighLevelILOperation N> HighLevelILInstructionList GetParameterExprs() const { return As<N>().GetParameterExprs(); } template <BNHighLevelILOperation N> HighLevelILInstructionList GetSourceExprs() const { return As<N>().GetSourceExprs(); } template <BNHighLevelILOperation N> HighLevelILInstructionList GetDestExprs() const { return As<N>().GetDestExprs(); } @@ -438,6 +439,7 @@ namespace BinaryNinja template <BNHighLevelILOperation N> void SetSourceSSAVariables(const std::vector<SSAVariable>& vars) { As<N>().SetSourceSSAVariables(vars); } template <BNHighLevelILOperation N> void SetSourceMemoryVersion(size_t version) { return As<N>().SetSourceMemoryVersion(version); } template <BNHighLevelILOperation N> void SetDestMemoryVersion(size_t version) { return As<N>().SetDestMemoryVersion(version); } + template <BNHighLevelILOperation N> void SetTarget(uint64_t target) { As<N>().SetTarget(target); } bool GetOperandIndexForUsage(HighLevelILOperandUsage usage, size_t& operandIndex) const; @@ -468,7 +470,7 @@ namespace BinaryNinja int64_t GetConstant() const; int64_t GetVector() const; uint32_t GetIntrinsic() const; - size_t GetTarget() const; + uint64_t GetTarget() const; HighLevelILInstructionList GetParameterExprs() const; HighLevelILInstructionList GetSourceExprs() const; HighLevelILInstructionList GetDestExprs() const; @@ -624,11 +626,13 @@ namespace BinaryNinja }; template <> struct HighLevelILInstructionAccessor<HLIL_GOTO>: public HighLevelILInstructionBase { - size_t GetTarget() const { return GetRawOperandAsIndex(0); } + uint64_t GetTarget() const { return GetRawOperandAsInteger(0); } + void SetTarget(uint64_t target) { UpdateRawOperandAsInteger(0, target); } }; template <> struct HighLevelILInstructionAccessor<HLIL_LABEL>: public HighLevelILInstructionBase { - size_t GetTarget() const { return GetRawOperandAsIndex(0); } + uint64_t GetTarget() const { return GetRawOperandAsInteger(0); } + void SetTarget(uint64_t target) { UpdateRawOperandAsInteger(0, target); } }; template <> struct HighLevelILInstructionAccessor<HLIL_RET>: public HighLevelILInstructionBase diff --git a/python/highlevelil.py b/python/highlevelil.py index 6565253d..5cf94b34 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -72,6 +72,38 @@ class HighLevelILOperationAndSize(object): self._size = value +class GotoLabel(object): + def __init__(self, function, id): + self._function = function + self._id = id + + @property + def label_id(self): + return self._id + + @property + def name(self): + return core.BNGetGotoLabelName(self._function.source_function.handle, self._id) + + @name.setter + def name(self, value): + core.BNSetUserGotoLabelName(self._function.source_function.handle, self._id, value) + + @property + def definition(self): + return self._function.get_label(self._id) + + @property + def uses(self): + return self._function.get_label_uses(self._id) + + def __str__(self): + return self.name + + def __repr__(self): + return "<label: %s>" % self.name + + class HighLevelILInstruction(object): """ ``class HighLevelILInstruction`` High Level Intermediate Language Instructions form an abstract syntax tree of @@ -95,8 +127,8 @@ class HighLevelILInstruction(object): HighLevelILOperation.HLIL_JUMP: [("dest", "expr")], HighLevelILOperation.HLIL_RET: [("src", "expr_list")], HighLevelILOperation.HLIL_NORET: [], - HighLevelILOperation.HLIL_GOTO: [("target", "int")], - HighLevelILOperation.HLIL_LABEL: [("target", "int")], + HighLevelILOperation.HLIL_GOTO: [("target", "label")], + HighLevelILOperation.HLIL_LABEL: [("target", "label")], HighLevelILOperation.HLIL_VAR_DECLARE: [("var", "var")], HighLevelILOperation.HLIL_VAR_INIT: [("dest", "var"), ("src", "expr")], HighLevelILOperation.HLIL_VAR_INIT_SSA: [("dest", "var_ssa"), ("src", "expr")], @@ -271,6 +303,8 @@ class HighLevelILInstruction(object): value = instr.operands[i] if (value & (1 << 63)) != 0: value = None + elif operand_type == "label": + value = GotoLabel(self.function, instr.operands[i]) self._operands.append(value) self.__dict__[name] = value i += 1 @@ -877,6 +911,21 @@ class HighLevelILFunction(object): return None return result + def get_label(self, label_idx): + result = core.BNGetHighLevelILExprIndexForLabel(self.handle, label_idx) + if result >= core.BNGetHighLevelILExprCount(self.handle): + return None + return HighLevelILInstruction(self, result) + + def get_label_uses(self, label_idx): + count = ctypes.c_ulonglong() + uses = core.BNGetHighLevelILUsesForLabel(self.handle, label_idx, count) + result = [] + for i in range(0, count.value): + result.append(HighLevelILInstruction(self, uses[i])) + core.BNFreeILInstructionList(uses) + return result + class HighLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, view, handle, owner): diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h index dc358871..e90bcdc5 100644 --- a/ui/flowgraphwidget.h +++ b/ui/flowgraphwidget.h @@ -155,6 +155,7 @@ protected: void bindActions(); void navigateToAddress(uint64_t addr); + void navigateToGotoLabel(uint64_t label); void setGraphInternal(FlowGraphRef graph, FlowGraphHistoryEntry* entry, bool useAddr, uint64_t addr, bool notify, bool recenterWithPreviousGraph); diff --git a/ui/linearview.h b/ui/linearview.h index 46addd4f..2c9c5fcc 100644 --- a/ui/linearview.h +++ b/ui/linearview.h @@ -144,6 +144,7 @@ class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, publ void updateCache(); void refreshAtCurrentLocation(); bool navigateToAddress(uint64_t addr, bool center, bool updateHighlight, bool navByRef = false); + bool navigateToGotoLabel(uint64_t label); void scrollLines(int count); @@ -69,6 +69,7 @@ enum ThemeColor UncertainColor, NameSpaceColor, NameSpaceSeparatorColor, + GotoLabelColor, // Script console colors ScriptConsoleOutputColor, |
