summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2022-01-20 18:02:35 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2022-01-20 20:57:20 -0500
commit12659a7e2227a2277b0ca62f7866921a70f7ea4d (patch)
treec920dadce72430f1c27cff3e3b80fdb27721d3f0
parent836848724094f8ae98c31c886ca827a41a366b21 (diff)
Async IL fetching in stack, variables, and xref views
-rw-r--r--binaryninjaapi.h13
-rw-r--r--binaryninjacore.h10
-rw-r--r--function.cpp290
-rw-r--r--ui/stackview.h3
-rw-r--r--ui/variablelist.h1
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;