diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2022-01-20 18:02:35 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2022-01-20 20:57:20 -0500 |
| commit | 12659a7e2227a2277b0ca62f7866921a70f7ea4d (patch) | |
| tree | c920dadce72430f1c27cff3e3b80fdb27721d3f0 | |
| parent | 836848724094f8ae98c31c886ca827a41a366b21 (diff) | |
Async IL fetching in stack, variables, and xref views
| -rw-r--r-- | binaryninjaapi.h | 13 | ||||
| -rw-r--r-- | binaryninjacore.h | 10 | ||||
| -rw-r--r-- | function.cpp | 290 | ||||
| -rw-r--r-- | ui/stackview.h | 3 | ||||
| -rw-r--r-- | ui/variablelist.h | 1 |
5 files changed, 317 insertions, 0 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index fe499587..0b1949d7 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -3494,10 +3494,16 @@ __attribute__ ((format (printf, 1, 2))) std::vector<ILReferenceSource> GetMediumLevelILVariableReferences(const Variable& var); std::vector<VariableReferenceSource> GetMediumLevelILVariableReferencesFrom(Architecture* arch, uint64_t addr); std::vector<VariableReferenceSource> GetMediumLevelILVariableReferencesInRange(Architecture* arch, uint64_t addr, uint64_t len); + std::vector<ILReferenceSource> GetMediumLevelILVariableReferencesIfAvailable(const Variable& var); + std::vector<VariableReferenceSource> GetMediumLevelILVariableReferencesFromIfAvailable(Architecture* arch, uint64_t addr); + std::vector<VariableReferenceSource> GetMediumLevelILVariableReferencesInRangeIfAvailable(Architecture* arch, uint64_t addr, uint64_t len); std::vector<ILReferenceSource> GetHighLevelILVariableReferences(const Variable& var); std::vector<VariableReferenceSource> GetHighLevelILVariableReferencesFrom(Architecture* arch, uint64_t addr); std::vector<VariableReferenceSource> GetHighLevelILVariableReferencesInRange(Architecture* arch, uint64_t addr, uint64_t len); + std::vector<ILReferenceSource> GetHighLevelILVariableReferencesIfAvailable(const Variable& var); + std::vector<VariableReferenceSource> GetHighLevelILVariableReferencesFromIfAvailable(Architecture* arch, uint64_t addr); + std::vector<VariableReferenceSource> GetHighLevelILVariableReferencesInRangeIfAvailable(Architecture* arch, uint64_t addr, uint64_t len); Ref<LowLevelILFunction> GetLiftedIL() const; Ref<LowLevelILFunction> GetLiftedILIfAvailable() const; @@ -3568,6 +3574,13 @@ __attribute__ ((format (printf, 1, 2))) std::set<Variable> GetHighLevelILAliasedVariables(); std::set<SSAVariable> GetHighLevelILSSAVariables(); + std::set<Variable> GetMediumLevelILVariablesIfAvailable(); + std::set<Variable> GetMediumLevelILAliasedVariablesIfAvailable(); + std::set<SSAVariable> GetMediumLevelILSSAVariablesIfAvailable(); + std::set<Variable> GetHighLevelILVariablesIfAvailable(); + std::set<Variable> GetHighLevelILAliasedVariablesIfAvailable(); + std::set<SSAVariable> GetHighLevelILSSAVariablesIfAvailable(); + void CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type, const std::string& name, bool ignoreDisjointUses = false); void CreateUserVariable(const Variable& var, const Confidence<Ref<Type>>& type, const std::string& name, diff --git a/binaryninjacore.h b/binaryninjacore.h index ce779cab..89b506b4 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -4105,12 +4105,22 @@ __attribute__ ((format (printf, 1, 2))) uint64_t address, size_t* count); BINARYNINJACOREAPI BNVariableReferenceSource* BNGetMediumLevelILVariableReferencesInRange(BNFunction* func, BNArchitecture* arch, uint64_t address, uint64_t len, size_t* count); + BINARYNINJACOREAPI BNILReferenceSource* BNGetMediumLevelILVariableReferencesIfAvailable(BNFunction* func, BNVariable* var, size_t * count); + BINARYNINJACOREAPI BNVariableReferenceSource* BNGetMediumLevelILVariableReferencesFromIfAvailable(BNFunction* func, BNArchitecture* arch, + uint64_t address, size_t* count); + BINARYNINJACOREAPI BNVariableReferenceSource* BNGetMediumLevelILVariableReferencesInRangeIfAvailable(BNFunction* func, BNArchitecture* arch, + uint64_t address, uint64_t len, size_t* count); BINARYNINJACOREAPI BNILReferenceSource* BNGetHighLevelILVariableReferences(BNFunction* func, BNVariable* var, size_t * count); BINARYNINJACOREAPI BNVariableReferenceSource* BNGetHighLevelILVariableReferencesFrom(BNFunction* func, BNArchitecture* arch, uint64_t address, size_t* count); BINARYNINJACOREAPI BNVariableReferenceSource* BNGetHighLevelILVariableReferencesInRange(BNFunction* func, BNArchitecture* arch, uint64_t address, uint64_t len, size_t* count); + BINARYNINJACOREAPI BNILReferenceSource* BNGetHighLevelILVariableReferencesIfAvailable(BNFunction* func, BNVariable* var, size_t * count); + BINARYNINJACOREAPI BNVariableReferenceSource* BNGetHighLevelILVariableReferencesFromIfAvailable(BNFunction* func, BNArchitecture* arch, + uint64_t address, size_t* count); + BINARYNINJACOREAPI BNVariableReferenceSource* BNGetHighLevelILVariableReferencesInRangeIfAvailable(BNFunction* func, BNArchitecture* arch, + uint64_t address, uint64_t len, size_t* count); BINARYNINJACOREAPI void BNFreeVariableList(BNVariable* vars); BINARYNINJACOREAPI void BNFreeVariableReferenceSourceList(BNVariableReferenceSource* vars, size_t count); diff --git a/function.cpp b/function.cpp index a7e4c154..5b1d2ba4 100644 --- a/function.cpp +++ b/function.cpp @@ -1260,6 +1260,126 @@ set<SSAVariable> Function::GetHighLevelILSSAVariables() } +set<Variable> Function::GetMediumLevelILVariablesIfAvailable() +{ + Ref<MediumLevelILFunction> mlil = this->GetMediumLevelILIfAvailable(); + if (!mlil) + return {}; + + size_t count; + BNVariable* vars = BNGetMediumLevelILVariables(mlil->GetObject(), &count); + + set<Variable> result; + for (size_t i = 0; i < count; ++i) + result.emplace(vars[i]); + + BNFreeVariableList(vars); + return result; +} + + +set<Variable> Function::GetMediumLevelILAliasedVariablesIfAvailable() +{ + Ref<MediumLevelILFunction> mlil = this->GetMediumLevelILIfAvailable(); + if (!mlil) + return {}; + + size_t count; + BNVariable* vars = BNGetMediumLevelILAliasedVariables(mlil->GetObject(), &count); + + set<Variable> result; + for (size_t i = 0; i < count; ++i) + result.emplace(vars[i]); + + BNFreeVariableList(vars); + return result; +} + + +set<SSAVariable> Function::GetMediumLevelILSSAVariablesIfAvailable() +{ + Ref<MediumLevelILFunction> mlil = this->GetMediumLevelILIfAvailable(); + if (!mlil) + return {}; + + size_t count; + BNVariable* vars = BNGetMediumLevelILVariables(mlil->GetObject(), &count); + + set<SSAVariable> result; + for (size_t i = 0; i < count; ++i) + { + size_t versionCount; + size_t* versions = BNGetMediumLevelILVariableSSAVersions(mlil->GetObject(), &vars[i], &versionCount); + for (size_t j = 0; j < versionCount; ++j) + result.emplace(vars[i], versions[j]); + BNFreeILInstructionList(versions); + } + + BNFreeVariableList(vars); + return result; +} + + +set<Variable> Function::GetHighLevelILVariablesIfAvailable() +{ + Ref<HighLevelILFunction> hlil = this->GetHighLevelILIfAvailable(); + if (!hlil) + return {}; + + size_t count; + BNVariable* vars = BNGetHighLevelILVariables(hlil->GetObject(), &count); + + set<Variable> result; + for (size_t i = 0; i < count; ++i) + result.emplace(vars[i]); + + BNFreeVariableList(vars); + return result; +} + + +set<Variable> Function::GetHighLevelILAliasedVariablesIfAvailable() +{ + Ref<HighLevelILFunction> hlil = this->GetHighLevelILIfAvailable(); + if (!hlil) + return {}; + + size_t count; + BNVariable* vars = BNGetHighLevelILAliasedVariables(hlil->GetObject(), &count); + + set<Variable> result; + for (size_t i = 0; i < count; ++i) + result.emplace(vars[i]); + + BNFreeVariableList(vars); + return result; +} + + +set<SSAVariable> Function::GetHighLevelILSSAVariablesIfAvailable() +{ + Ref<HighLevelILFunction> hlil = this->GetHighLevelILIfAvailable(); + if (!hlil) + return {}; + + size_t count; + BNVariable* vars = BNGetHighLevelILVariables(hlil->GetObject(), &count); + + set<SSAVariable> result; + for (size_t i = 0; i < count; ++i) + { + size_t versionCount; + size_t* versions = BNGetHighLevelILVariableSSAVersions(hlil->GetObject(), &vars[i], &versionCount); + for (size_t j = 0; j < versionCount; ++j) + result.emplace(vars[i], versions[j]); + BNFreeILInstructionList(versions); + } + + BNFreeVariableList(vars); + return result; +} + + void Function::CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type, const string& name, bool ignoreDisjointUses) { @@ -2484,6 +2604,176 @@ vector<VariableReferenceSource> Function::GetHighLevelILVariableReferencesInRang } +vector<ILReferenceSource> Function::GetMediumLevelILVariableReferencesIfAvailable(const Variable& var) +{ + size_t count; + + BNVariable varData; + varData.type = var.type; + varData.index = var.index; + varData.storage = var.storage; + + BNILReferenceSource* refs = BNGetMediumLevelILVariableReferencesIfAvailable(m_object, &varData, &count); + + vector<ILReferenceSource> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + ILReferenceSource src; + src.func = new Function(BNNewFunctionReference(refs[i].func)); + src.arch = new CoreArchitecture(refs[i].arch); + src.addr = refs[i].addr; + src.type = refs[i].type; + src.exprId = refs[i].exprId; + result.push_back(src); + } + + BNFreeILReferences(refs, count); + return result; +} + + +vector<VariableReferenceSource> Function::GetMediumLevelILVariableReferencesFromIfAvailable(Architecture* arch, uint64_t addr) +{ + size_t count; + BNVariableReferenceSource* refs = BNGetMediumLevelILVariableReferencesFromIfAvailable(m_object, arch->GetObject(), addr, &count); + + vector<VariableReferenceSource> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + VariableReferenceSource src; + src.var.index = refs[i].var.index; + src.var.storage = refs[i].var.storage; + src.var.type = refs[i].var.type; + + src.source.func = new Function(BNNewFunctionReference(refs[i].source.func)); + src.source.arch = new CoreArchitecture(refs[i].source.arch); + src.source.addr = refs[i].source.addr; + src.source.type = refs[i].source.type; + src.source.exprId = refs[i].source.exprId; + + result.push_back(src); + } + + BNFreeVariableReferenceSourceList(refs, count); + return result; +} + + +vector<VariableReferenceSource> Function::GetMediumLevelILVariableReferencesInRangeIfAvailable(Architecture* arch, uint64_t addr, uint64_t len) +{ + size_t count; + BNVariableReferenceSource* refs = BNGetMediumLevelILVariableReferencesInRangeIfAvailable(m_object, arch->GetObject(), addr, len, &count); + + vector<VariableReferenceSource> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + VariableReferenceSource src; + src.var.index = refs[i].var.index; + src.var.storage = refs[i].var.storage; + src.var.type = refs[i].var.type; + + src.source.func = new Function(BNNewFunctionReference(refs[i].source.func)); + src.source.arch = new CoreArchitecture(refs[i].source.arch); + src.source.addr = refs[i].source.addr; + src.source.type = refs[i].source.type; + src.source.exprId = refs[i].source.exprId; + + result.push_back(src); + } + + BNFreeVariableReferenceSourceList(refs, count); + return result; +} + + +vector<ILReferenceSource> Function::GetHighLevelILVariableReferencesIfAvailable(const Variable& var) +{ + size_t count; + + BNVariable varData; + varData.type = var.type; + varData.index = var.index; + varData.storage = var.storage; + + BNILReferenceSource* refs = BNGetHighLevelILVariableReferencesIfAvailable(m_object, &varData, &count); + + vector<ILReferenceSource> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + ILReferenceSource src; + src.func = new Function(BNNewFunctionReference(refs[i].func)); + src.arch = new CoreArchitecture(refs[i].arch); + src.addr = refs[i].addr; + src.type = refs[i].type; + src.exprId = refs[i].exprId; + result.push_back(src); + } + + BNFreeILReferences(refs, count); + return result; +} + + +vector<VariableReferenceSource> Function::GetHighLevelILVariableReferencesFromIfAvailable(Architecture* arch, uint64_t addr) +{ + size_t count; + BNVariableReferenceSource* refs = BNGetHighLevelILVariableReferencesFromIfAvailable(m_object, arch->GetObject(), addr, &count); + + vector<VariableReferenceSource> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + VariableReferenceSource src; + src.var.index = refs[i].var.index; + src.var.storage = refs[i].var.storage; + src.var.type = refs[i].var.type; + + src.source.func = new Function(BNNewFunctionReference(refs[i].source.func)); + src.source.arch = new CoreArchitecture(refs[i].source.arch); + src.source.addr = refs[i].source.addr; + src.source.type = refs[i].source.type; + src.source.exprId = refs[i].source.exprId; + + result.push_back(src); + } + + BNFreeVariableReferenceSourceList(refs, count); + return result; +} + + +vector<VariableReferenceSource> Function::GetHighLevelILVariableReferencesInRangeIfAvailable(Architecture* arch, uint64_t addr, uint64_t len) +{ + size_t count; + BNVariableReferenceSource* refs = BNGetHighLevelILVariableReferencesInRangeIfAvailable(m_object, arch->GetObject(), addr, len, &count); + + vector<VariableReferenceSource> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + VariableReferenceSource src; + src.var.index = refs[i].var.index; + src.var.storage = refs[i].var.storage; + src.var.type = refs[i].var.type; + + src.source.func = new Function(BNNewFunctionReference(refs[i].source.func)); + src.source.arch = new CoreArchitecture(refs[i].source.arch); + src.source.addr = refs[i].source.addr; + src.source.type = refs[i].source.type; + src.source.exprId = refs[i].source.exprId; + + result.push_back(src); + } + + BNFreeVariableReferenceSourceList(refs, count); + return result; +} + + uint64_t Function::GetHighestAddress() { return BNGetFunctionHighestAddress(m_object); diff --git a/ui/stackview.h b/ui/stackview.h index 311fa37d..34e83950 100644 --- a/ui/stackview.h +++ b/ui/stackview.h @@ -10,6 +10,8 @@ #include "sidebar.h" #include "uitypes.h" +#define STACK_VIEW_UPDATE_CHECK_INTERVAL 200 + //! Dialog to enable arbitrary stack variable creation. class BINARYNINJAUIAPI CreateStackVariableDialog : public QDialog { @@ -160,6 +162,7 @@ class BINARYNINJAUIAPI StackView : public QAbstractScrollArea, public View ViewFrame* m_view; BinaryViewRef m_data; FunctionRef m_func; + BinaryNinja::AdvancedFunctionAnalysisDataRequestor m_analysisRequestor; RenderContext m_renderer; std::vector<StackViewLine> m_lines; diff --git a/ui/variablelist.h b/ui/variablelist.h index d896beb2..cc1e1de5 100644 --- a/ui/variablelist.h +++ b/ui/variablelist.h @@ -83,6 +83,7 @@ class BINARYNINJAUIAPI VariableListModel : public QAbstractListModel ViewFrame* m_view; BinaryViewRef m_data; FunctionRef m_func; + BinaryNinja::AdvancedFunctionAnalysisDataRequestor m_analysisRequestor; std::vector<VariableListItem> m_items; QItemSelectionModel* m_selModel; |
