diff options
| author | Chinmay <chinmay1dd@gmail.com> | 2020-08-12 01:20:22 -0700 |
|---|---|---|
| committer | Chinmay Deshpande <chinmay1dd@gmail.com> | 2020-08-13 19:31:20 -0700 |
| commit | 139c90f93cb10317339fce1ad81ac61425498099 (patch) | |
| tree | 25e90b6cfdc91580eba6017b55b5046bf1faae33 | |
| parent | 153e9543984751449e64048a5acceff9524221ce (diff) | |
Update function names and change up API
| -rw-r--r-- | binaryninjaapi.h | 25 | ||||
| -rw-r--r-- | binaryninjacore.h | 15 | ||||
| -rw-r--r-- | function.cpp | 40 | ||||
| -rw-r--r-- | python/function.py | 59 |
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: |
