summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChinmay <chinmay1dd@gmail.com>2020-08-12 01:20:22 -0700
committerChinmay Deshpande <chinmay1dd@gmail.com>2020-08-13 19:31:20 -0700
commit139c90f93cb10317339fce1ad81ac61425498099 (patch)
tree25e90b6cfdc91580eba6017b55b5046bf1faae33
parent153e9543984751449e64048a5acceff9524221ce (diff)
Update function names and change up API
-rw-r--r--binaryninjaapi.h25
-rw-r--r--binaryninjacore.h15
-rw-r--r--function.cpp40
-rw-r--r--python/function.py59
4 files changed, 119 insertions, 20 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 90bbc4c2..692cbebf 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2909,6 +2909,24 @@ __attribute__ ((format (printf, 1, 2)))
Ref<Architecture> arch;
uint64_t address;
+ ArchAndAddr& operator=(const ArchAndAddr& a)
+ {
+ arch = a.arch;
+ address = a.address;
+ return *this;
+ }
+ bool operator==(const ArchAndAddr& a) const
+ {
+ return (arch == a.arch) && (address == a.address);
+ }
+ bool operator<(const ArchAndAddr& a) const
+ {
+ if (arch < a.arch)
+ return true;
+ if (arch > a.arch)
+ return false;
+ return address < a.address;
+ }
ArchAndAddr(): arch(nullptr), address(0) {}
ArchAndAddr(Architecture* a, uint64_t addr): arch(a), address(addr) {}
};
@@ -3163,9 +3181,10 @@ __attribute__ ((format (printf, 1, 2)))
Ref<FlowGraph> GetUnresolvedStackAdjustmentGraph();
- void SetVariableValue(const Variable& var, uint64_t defAddr, PossibleValueSet& value);
- void ClearInformedVariableValue(const Variable& var, uint64_t defAddr);
- void ClearInformedVariableValues();
+ void SetUserVariableValue(const Variable& var, uint64_t defAddr, PossibleValueSet& value);
+ void ClearUserVariableValue(const Variable& var, uint64_t defAddr);
+ std::map<Variable, std::map<ArchAndAddr, PossibleValueSet>> GetAllUserVariableValues();
+ void ClearAllUserVariableValues();
void RequestDebugReport(const std::string& name);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 6c32545a..68af6ee0 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -881,6 +881,7 @@ extern "C"
size_t count;
};
+
struct BNRegisterOrConstant
{
bool constant;
@@ -1866,6 +1867,13 @@ extern "C"
uint64_t address;
};
+ struct BNUserVariableValue
+ {
+ BNVariable var;
+ BNArchitectureAndAddress defSite;
+ BNPossibleValueSet value;
+ };
+
enum BNAnalysisState
{
IdleState,
@@ -3370,9 +3378,10 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI BNFlowGraph* BNGetUnresolvedStackAdjustmentGraph(BNFunction* func);
- BINARYNINJACOREAPI void BNSetVariableValue(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite, const BNPossibleValueSet* value);
- BINARYNINJACOREAPI void BNClearInformedVariableValue(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite);
- BINARYNINJACOREAPI void BNClearInformedVariableValues(BNFunction* func);
+ BINARYNINJACOREAPI void BNSetUserVariableValue(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite, const BNPossibleValueSet* value);
+ BINARYNINJACOREAPI void BNClearUserVariableValue(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite);
+ BINARYNINJACOREAPI BNUserVariableValue* BNGetAllUserVariableValues(BNFunction *func, size_t* count);
+ BINARYNINJACOREAPI void BNFreeUserVariableValues(BNUserVariableValue* result);
BINARYNINJACOREAPI void BNRequestFunctionDebugReport(BNFunction* func, const char* name);
diff --git a/function.cpp b/function.cpp
index 9dc9ea21..ecb81a67 100644
--- a/function.cpp
+++ b/function.cpp
@@ -1771,7 +1771,7 @@ Ref<FlowGraph> Function::GetUnresolvedStackAdjustmentGraph()
}
-void Function::SetVariableValue(const Variable& var, uint64_t defAddr, PossibleValueSet& value)
+void Function::SetUserVariableValue(const Variable& var, uint64_t defAddr, PossibleValueSet& value)
{
auto mlil = GetMediumLevelIL();
auto varDefs = mlil->GetVariableDefinitions(var);
@@ -1804,11 +1804,11 @@ void Function::SetVariableValue(const Variable& var, uint64_t defAddr, PossibleV
auto valueObj = value.ToAPIObject();
- BNSetVariableValue(m_object, &var_data, &defSite, &valueObj);
+ BNSetUserVariableValue(m_object, &var_data, &defSite, &valueObj);
}
-void Function::ClearInformedVariableValue(const Variable& var, uint64_t defAddr)
+void Function::ClearUserVariableValue(const Variable& var, uint64_t defAddr)
{
auto mlil = GetMediumLevelIL();
auto varDefs = mlil->GetVariableDefinitions(var);
@@ -1838,13 +1838,41 @@ void Function::ClearInformedVariableValue(const Variable& var, uint64_t defAddr)
var_data.index = var.index;
var_data.storage = var.storage;
- BNClearInformedVariableValue(m_object, &var_data, &defSite);
+ BNClearUserVariableValue(m_object, &var_data, &defSite);
}
-void Function::ClearInformedVariableValues()
+map<Variable, map<ArchAndAddr, PossibleValueSet>> Function::GetAllUserVariableValues()
{
- BNClearInformedVariableValues(m_object);
+ size_t count;
+ map<Variable, map<ArchAndAddr, PossibleValueSet>> result;
+ BNUserVariableValue* var_values = BNGetAllUserVariableValues(m_object, &count);
+
+ for (size_t i = 0; i < count; i++)
+ {
+ Variable var(var_values[i].var);
+ Architecture* arch = new CoreArchitecture(var_values[i].defSite.arch);
+ uint64_t address = var_values[i].defSite.address;
+ ArchAndAddr defSite(arch, address);
+ PossibleValueSet value = PossibleValueSet::FromAPIObject(var_values[i].value);
+ result[var][defSite] = value;
+ }
+
+ BNFreeUserVariableValues(var_values);
+ return result;
+}
+
+
+void Function::ClearAllUserVariableValues()
+{
+ const map<Variable, map<ArchAndAddr, PossibleValueSet>>& allValues = GetAllUserVariableValues();
+ for (auto& valuePair : allValues)
+ {
+ for (auto& valMap : valuePair.second)
+ {
+ ClearUserVariableValue(valuePair.first, valMap.first.address);
+ }
+ }
}
diff --git a/python/function.py b/python/function.py
index 42bc06f0..429c9f47 100644
--- a/python/function.py
+++ b/python/function.py
@@ -396,7 +396,7 @@ class PossibleValueSet(object):
elif self.type == RegisterValueType.StackFrameOffset:
result.offset = self.value
elif self.type == RegisterValueType.SignedRangeValue:
- result.offst = self.value
+ result.offset = self.value
result.ranges = (core.BNValueRange * self.count)()
for i in range(0, self.count):
start = self.ranges[i].start
@@ -440,7 +440,7 @@ class PossibleValueSet(object):
result.valueSet = ctypes.cast(values, ctypes.POINTER(ctypes.c_long))
result.count = self.count
return result
-
+
@property
def type(self):
""" """
@@ -598,6 +598,21 @@ class PossibleValueSet(object):
result.mapping = mapping
return result
+class ArchAndAddr(object):
+ def __init__(self, arch = None, addr = 0):
+ self._arch = binaryninja.architecture.CoreArchitecture(arch)
+ self._addr = addr
+
+ def __repr__(self):
+ return "archandaddr <%s @ %#x>" % (self._arch.name, self._addr)
+
+ @property
+ def arch(self):
+ return self._arch
+
+ @property
+ def addr(self):
+ return self._addr
class StackVariableReference(object):
def __init__(self, src_operand, t, name, var, ref_ofs, size):
@@ -854,6 +869,15 @@ class ConstantReference(object):
self._intermediate = value
+class UserVariableValueInfo(object):
+ def __init__(self, var, def_site, value):
+ self.var = var
+ self.def_site = def_site
+ self.value = value
+
+ def __repr__(self):
+ return "<user value for %s @ %s:%#x -> %s>" % (self.var, self.def_site.arch.name, self.def_site.addr, self.value)
+
class IndirectBranchInfo(object):
def __init__(self, source_arch, source_addr, dest_arch, dest_addr, auto_defined):
@@ -2557,7 +2581,7 @@ class Function(object):
arch = self.arch
return core.BNIsCallInstruction(self.handle, arch.handle, addr)
- def set_var_value(self, var, def_addr, value):
+ def set_user_var_value(self, var, def_addr, value):
var_defs = self.mlil.get_var_definitions(var)
if var_defs is None:
raise ValueError("Could not get definition for Variable")
@@ -2576,9 +2600,9 @@ class Function(object):
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
- core.BNSetVariableValue(self.handle, var_data, def_site, value._to_api_object())
+ core.BNSetUserVariableValue(self.handle, var_data, def_site, value._to_api_object())
- def clear_informed_var_value(self, var, def_addr):
+ def clear_user_var_value(self, var, def_addr):
var_defs = self.mlil.get_var_definitions(var)
if var_defs is None:
raise ValueError("Could not get definition for Variable")
@@ -2597,10 +2621,28 @@ class Function(object):
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
- core.BNClearInformedVariableValue(self.handle, var_data, def_site)
+ core.BNClearUserVariableValue(self.handle, var_data, def_site)
+
+ def get_all_user_var_values(self):
+ count = ctypes.c_ulonglong(0)
+ var_values = core.BNGetAllUserVariableValues(self.handle, count)
+ result = {}
+ i = 0
+ for i in range(count.value):
+ var_val = var_values[i]
+ var = Variable(self, var_val.var.type, var_val.var.index, var_val.var.storage)
+ if var not in result:
+ result[var] = {}
+ def_site = ArchAndAddr(var_val.defSite.arch, var_val.defSite.address)
+ result[var][def_site] = PossibleValueSet(def_site.arch, var_val.value)
+ core.BNFreeUserVariableValues(var_values)
+ return result
- def clear_informed_var_values(self):
- core.BNClearInformedVariableValues(self.handle)
+ def clear_all_user_var_values(self):
+ all_values = self.get_all_user_var_values()
+ for var in all_values:
+ for def_site in all_values[var]:
+ self.clear_user_var_value(var, def_site.addr)
def request_debug_report(self, name):
core.BNRequestFunctionDebugReport(self.handle, name)
@@ -3276,6 +3318,7 @@ class InstructionTextToken(object):
return self._width
+
class DisassemblyTextRenderer(object):
def __init__(self, func = None, settings = None, handle = None):
if handle is None: