diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-08-23 01:04:47 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-08-23 17:01:33 -0400 |
| commit | 0d88336e22cf85a917729fe0f814c1e63736fca0 (patch) | |
| tree | 246a7cf34d3f3919770cfbb2cf5f357adb1771e1 | |
| parent | 7f3efa01f053e19549c480a770728085900c2131 (diff) | |
Added APIs for clobbered registers, global pointers, and function exit data flow info
| -rw-r--r-- | binaryninjaapi.h | 13 | ||||
| -rw-r--r-- | binaryninjacore.h | 36 | ||||
| -rw-r--r-- | callingconvention.cpp | 20 | ||||
| -rw-r--r-- | function.cpp | 79 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 26 | ||||
| -rw-r--r-- | python/binaryview.py | 6 | ||||
| -rw-r--r-- | python/callingconvention.py | 10 | ||||
| -rw-r--r-- | python/function.py | 79 | ||||
| -rw-r--r-- | python/types.py | 37 |
9 files changed, 297 insertions, 9 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index e16679cc..f5f51908 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2185,6 +2185,8 @@ namespace BinaryNinja Confidence<Ref<CallingConvention>> GetCallingConvention() const; Confidence<std::vector<Variable>> GetParameterVariables() const; Confidence<bool> HasVariableArguments() const; + Confidence<size_t> GetStackAdjustment() const; + Confidence<std::set<uint32_t>> GetClobberedRegisters() const; void SetAutoType(Type* type); void SetAutoReturnType(const Confidence<Ref<Type>>& type); @@ -2192,6 +2194,8 @@ namespace BinaryNinja void SetAutoParameterVariables(const Confidence<std::vector<Variable>>& vars); void SetAutoHasVariableArguments(const Confidence<bool>& varArgs); void SetAutoCanReturn(const Confidence<bool>& returns); + void SetAutoStackAdjustment(const Confidence<size_t>& stackAdjust); + void SetAutoClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered); void SetUserType(Type* type); void SetReturnType(const Confidence<Ref<Type>>& type); @@ -2199,6 +2203,8 @@ namespace BinaryNinja void SetParameterVariables(const Confidence<std::vector<Variable>>& vars); void SetHasVariableArguments(const Confidence<bool>& varArgs); void SetCanReturn(const Confidence<bool>& returns); + void SetStackAdjustment(const Confidence<size_t>& stackAdjust); + void SetClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered); void ApplyImportedTypes(Symbol* sym); void ApplyAutoDiscoveredType(Type* type); @@ -2260,6 +2266,9 @@ namespace BinaryNinja std::map<std::string, double> GetAnalysisPerformanceInfo(); std::vector<DisassemblyTextLine> GetTypeTokens(DisassemblySettings* settings = nullptr); + + Confidence<RegisterValue> GetGlobalPointerValue() const; + Confidence<RegisterValue> GetRegisterValueAtExit(uint32_t reg) const; }; class AdvancedFunctionAnalysisDataRequestor @@ -2856,6 +2865,7 @@ namespace BinaryNinja void Finalize(); void GenerateSSAForm(bool analyzeConditionals = true, bool handleAliases = true, + const std::set<Variable>& knownNotAliases = std::set<Variable>(), const std::set<Variable>& knownAliases = std::set<Variable>()); bool GetExprText(Architecture* arch, ExprId expr, std::vector<InstructionTextToken>& tokens); @@ -3069,6 +3079,7 @@ namespace BinaryNinja static bool AreArgumentRegistersSharedIndexCallback(void* ctxt); static bool IsStackReservedForArgumentRegistersCallback(void* ctxt); + static bool IsStackAdjustedOnReturnCallback(void* ctxt); static uint32_t GetIntegerReturnValueRegisterCallback(void* ctxt); static uint32_t GetHighIntegerReturnValueRegisterCallback(void* ctxt); @@ -3089,6 +3100,7 @@ namespace BinaryNinja virtual std::vector<uint32_t> GetFloatArgumentRegisters(); virtual bool AreArgumentRegistersSharedIndex(); virtual bool IsStackReservedForArgumentRegisters(); + virtual bool IsStackAdjustedOnReturn(); virtual uint32_t GetIntegerReturnValueRegister() = 0; virtual uint32_t GetHighIntegerReturnValueRegister(); @@ -3111,6 +3123,7 @@ namespace BinaryNinja virtual std::vector<uint32_t> GetFloatArgumentRegisters() override; virtual bool AreArgumentRegistersSharedIndex() override; virtual bool IsStackReservedForArgumentRegisters() override; + virtual bool IsStackAdjustedOnReturn() override; virtual uint32_t GetIntegerReturnValueRegister() override; virtual uint32_t GetHighIntegerReturnValueRegister() override; diff --git a/binaryninjacore.h b/binaryninjacore.h index 0ee5c4d7..6ba7fda4 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -694,6 +694,12 @@ extern "C" int64_t value; }; + struct BNRegisterValueWithConfidence + { + BNRegisterValue value; + uint8_t confidence; + }; + struct BNValueRange { uint64_t start, end, step; @@ -1113,6 +1119,12 @@ extern "C" uint8_t confidence; }; + struct BNSizeWithConfidence + { + size_t value; + uint8_t confidence; + }; + struct BNMemberScopeWithConfidence { BNMemberScope value; @@ -1132,6 +1144,13 @@ extern "C" uint8_t confidence; }; + struct BNRegisterSetWithConfidence + { + uint32_t* regs; + size_t count; + uint8_t confidence; + }; + struct BNFunctionParameter { char* name; @@ -1243,6 +1262,7 @@ extern "C" bool (*areArgumentRegistersSharedIndex)(void* ctxt); bool (*isStackReservedForArgumentRegisters)(void* ctxt); + bool (*isStackAdjustedOnReturn)(void* ctxt); uint32_t (*getIntegerReturnValueRegister)(void* ctxt); uint32_t (*getHighIntegerReturnValueRegister)(void* ctxt); @@ -1806,6 +1826,8 @@ extern "C" BINARYNINJACOREAPI BNAddressRange* BNGetAllocatedRanges(BNBinaryView* view, size_t* count); BINARYNINJACOREAPI void BNFreeAddressRanges(BNAddressRange* ranges); + BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetGlobalPointerValue(BNBinaryView* view); + // Raw binary data view BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryDataView(BNFileMetadata* file); BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryDataViewFromBuffer(BNFileMetadata* file, BNDataBuffer* buf); @@ -2073,18 +2095,25 @@ extern "C" BINARYNINJACOREAPI BNParameterVariablesWithConfidence BNGetFunctionParameterVariables(BNFunction* func); BINARYNINJACOREAPI void BNFreeParameterVariables(BNParameterVariablesWithConfidence* vars); BINARYNINJACOREAPI BNBoolWithConfidence BNFunctionHasVariableArguments(BNFunction* func); + BINARYNINJACOREAPI BNSizeWithConfidence BNGetFunctionStackAdjustment(BNFunction* func); + BINARYNINJACOREAPI BNRegisterSetWithConfidence BNGetFunctionClobberedRegisters(BNFunction* func); + BINARYNINJACOREAPI void BNFreeClobberedRegisters(BNRegisterSetWithConfidence* regs); BINARYNINJACOREAPI void BNSetAutoFunctionReturnType(BNFunction* func, BNTypeWithConfidence* type); BINARYNINJACOREAPI void BNSetAutoFunctionCallingConvention(BNFunction* func, BNCallingConventionWithConfidence* convention); BINARYNINJACOREAPI void BNSetAutoFunctionParameterVariables(BNFunction* func, BNParameterVariablesWithConfidence* vars); BINARYNINJACOREAPI void BNSetAutoFunctionHasVariableArguments(BNFunction* func, BNBoolWithConfidence* varArgs); BINARYNINJACOREAPI void BNSetAutoFunctionCanReturn(BNFunction* func, BNBoolWithConfidence* returns); + BINARYNINJACOREAPI void BNSetAutoFunctionStackAdjustment(BNFunction* func, BNSizeWithConfidence* stackAdjust); + BINARYNINJACOREAPI void BNSetAutoFunctionClobberedRegisters(BNFunction* func, BNRegisterSetWithConfidence* regs); BINARYNINJACOREAPI void BNSetUserFunctionReturnType(BNFunction* func, BNTypeWithConfidence* type); BINARYNINJACOREAPI void BNSetUserFunctionCallingConvention(BNFunction* func, BNCallingConventionWithConfidence* convention); BINARYNINJACOREAPI void BNSetUserFunctionParameterVariables(BNFunction* func, BNParameterVariablesWithConfidence* vars); BINARYNINJACOREAPI void BNSetUserFunctionHasVariableArguments(BNFunction* func, BNBoolWithConfidence* varArgs); BINARYNINJACOREAPI void BNSetUserFunctionCanReturn(BNFunction* func, BNBoolWithConfidence* returns); + BINARYNINJACOREAPI void BNSetUserFunctionStackAdjustment(BNFunction* func, BNSizeWithConfidence* stackAdjust); + BINARYNINJACOREAPI void BNSetUserFunctionClobberedRegisters(BNFunction* func, BNRegisterSetWithConfidence* regs); BINARYNINJACOREAPI void BNApplyImportedTypes(BNFunction* func, BNSymbol* sym); BINARYNINJACOREAPI void BNApplyAutoDiscoveredFunctionType(BNFunction* func, BNType* type); @@ -2093,6 +2122,9 @@ extern "C" BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetFunctionTypeTokens(BNFunction* func, BNDisassemblySettings* settings, size_t* count); + BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetFunctionGlobalPointerValue(BNFunction* func); + BINARYNINJACOREAPI BNRegisterValueWithConfidence BNGetFunctionRegisterValueAtExit(BNFunction* func, uint32_t reg); + BINARYNINJACOREAPI BNFunction* BNGetBasicBlockFunction(BNBasicBlock* block); BINARYNINJACOREAPI BNArchitecture* BNGetBasicBlockArchitecture(BNBasicBlock* block); BINARYNINJACOREAPI uint64_t BNGetBasicBlockStart(BNBasicBlock* block); @@ -2492,7 +2524,8 @@ extern "C" BINARYNINJACOREAPI void BNMediumLevelILMarkLabel(BNMediumLevelILFunction* func, BNMediumLevelILLabel* label); BINARYNINJACOREAPI void BNFinalizeMediumLevelILFunction(BNMediumLevelILFunction* func); BINARYNINJACOREAPI void BNGenerateMediumLevelILSSAForm(BNMediumLevelILFunction* func, - bool analyzeConditionals, bool handleAliases, BNVariable* knownAliases, size_t knownAliasCount); + bool analyzeConditionals, bool handleAliases, BNVariable* knownNotAliases, size_t knownNotAliasCount, + BNVariable* knownAliases, size_t knownAliasCount); BINARYNINJACOREAPI void BNPrepareToCopyMediumLevelILFunction(BNMediumLevelILFunction* func, BNMediumLevelILFunction* src); @@ -2795,6 +2828,7 @@ extern "C" BINARYNINJACOREAPI uint32_t* BNGetFloatArgumentRegisters(BNCallingConvention* cc, size_t* count); BINARYNINJACOREAPI bool BNAreArgumentRegistersSharedIndex(BNCallingConvention* cc); BINARYNINJACOREAPI bool BNIsStackReservedForArgumentRegisters(BNCallingConvention* cc); + BINARYNINJACOREAPI bool BNIsStackAdjustedOnReturn(BNCallingConvention* cc); BINARYNINJACOREAPI uint32_t BNGetIntegerReturnValueRegister(BNCallingConvention* cc); BINARYNINJACOREAPI uint32_t BNGetHighIntegerReturnValueRegister(BNCallingConvention* cc); diff --git a/callingconvention.cpp b/callingconvention.cpp index 0a7d349c..945ba25f 100644 --- a/callingconvention.cpp +++ b/callingconvention.cpp @@ -41,6 +41,7 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name) cc.freeRegisterList = FreeRegisterListCallback; cc.areArgumentRegistersSharedIndex = AreArgumentRegistersSharedIndexCallback; cc.isStackReservedForArgumentRegisters = IsStackReservedForArgumentRegistersCallback; + cc.isStackAdjustedOnReturn = IsStackAdjustedOnReturnCallback; cc.getIntegerReturnValueRegister = GetIntegerReturnValueRegisterCallback; cc.getHighIntegerReturnValueRegister = GetHighIntegerReturnValueRegisterCallback; cc.getFloatReturnValueRegister = GetFloatReturnValueRegisterCallback; @@ -120,6 +121,13 @@ bool CallingConvention::IsStackReservedForArgumentRegistersCallback(void* ctxt) } +bool CallingConvention::IsStackAdjustedOnReturnCallback(void* ctxt) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + return cc->IsStackAdjustedOnReturn(); +} + + uint32_t CallingConvention::GetIntegerReturnValueRegisterCallback(void* ctxt) { CallingConvention* cc = (CallingConvention*)ctxt; @@ -226,6 +234,12 @@ bool CallingConvention::IsStackReservedForArgumentRegisters() } +bool CallingConvention::IsStackAdjustedOnReturn() +{ + return false; +} + + uint32_t CallingConvention::GetHighIntegerReturnValueRegister() { return BN_INVALID_REGISTER; @@ -312,6 +326,12 @@ bool CoreCallingConvention::IsStackReservedForArgumentRegisters() } +bool CoreCallingConvention::IsStackAdjustedOnReturn() +{ + return BNIsStackAdjustedOnReturn(m_object); +} + + uint32_t CoreCallingConvention::GetIntegerReturnValueRegister() { return BNGetIntegerReturnValueRegister(m_object); diff --git a/function.cpp b/function.cpp index 976d73d2..550691d0 100644 --- a/function.cpp +++ b/function.cpp @@ -508,6 +508,25 @@ Confidence<bool> Function::HasVariableArguments() const } +Confidence<size_t> Function::GetStackAdjustment() const +{ + BNSizeWithConfidence sc = BNGetFunctionStackAdjustment(m_object); + return Confidence<size_t>(sc.value, sc.confidence); +} + + +Confidence<set<uint32_t>> Function::GetClobberedRegisters() const +{ + BNRegisterSetWithConfidence regs = BNGetFunctionClobberedRegisters(m_object); + set<uint32_t> regSet; + for (size_t i = 0; i < regs.count; i++) + regSet.insert(regs.regs[i]); + Confidence<set<uint32_t>> result(regSet, regs.confidence); + BNFreeClobberedRegisters(®s); + return result; +} + + void Function::SetAutoType(Type* type) { BNSetFunctionAutoType(m_object, type->GetObject()); @@ -568,6 +587,29 @@ void Function::SetAutoCanReturn(const Confidence<bool>& returns) } +void Function::SetAutoStackAdjustment(const Confidence<size_t>& stackAdjust) +{ + BNSizeWithConfidence sc; + sc.value = stackAdjust.GetValue(); + sc.confidence = stackAdjust.GetConfidence(); + BNSetAutoFunctionStackAdjustment(m_object, &sc); +} + + +void Function::SetAutoClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered) +{ + BNRegisterSetWithConfidence regs; + regs.regs = new uint32_t[clobbered.GetValue().size()]; + regs.count = clobbered.GetValue().size(); + size_t i = 0; + for (auto reg : clobbered.GetValue()) + regs.regs[i++] = reg; + regs.confidence = clobbered.GetConfidence(); + BNSetAutoFunctionClobberedRegisters(m_object, ®s); + delete[] regs.regs; +} + + void Function::SetUserType(Type* type) { BNSetFunctionUserType(m_object, type->GetObject()); @@ -628,6 +670,29 @@ void Function::SetCanReturn(const Confidence<bool>& returns) } +void Function::SetStackAdjustment(const Confidence<size_t>& stackAdjust) +{ + BNSizeWithConfidence sc; + sc.value = stackAdjust.GetValue(); + sc.confidence = stackAdjust.GetConfidence(); + BNSetUserFunctionStackAdjustment(m_object, &sc); +} + + +void Function::SetClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered) +{ + BNRegisterSetWithConfidence regs; + regs.regs = new uint32_t[clobbered.GetValue().size()]; + regs.count = clobbered.GetValue().size(); + size_t i = 0; + for (auto reg : clobbered.GetValue()) + regs.regs[i++] = reg; + regs.confidence = clobbered.GetConfidence(); + BNSetUserFunctionClobberedRegisters(m_object, ®s); + delete[] regs.regs; +} + + void Function::ApplyImportedTypes(Symbol* sym) { BNApplyImportedTypes(m_object, sym->GetObject()); @@ -1014,6 +1079,20 @@ void Function::SetUserInstructionHighlight(Architecture* arch, uint64_t addr, ui } +Confidence<RegisterValue> Function::GetGlobalPointerValue() const +{ + BNRegisterValueWithConfidence value = BNGetFunctionGlobalPointerValue(m_object); + return Confidence<RegisterValue>(RegisterValue::FromAPIObject(value.value), value.confidence); +} + + +Confidence<RegisterValue> Function::GetRegisterValueAtExit(uint32_t reg) const +{ + BNRegisterValueWithConfidence value = BNGetFunctionRegisterValueAtExit(m_object, reg); + return Confidence<RegisterValue>(RegisterValue::FromAPIObject(value.value), value.confidence); +} + + void Function::Reanalyze() { BNReanalyzeFunction(m_object); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index f978f681..04a7341f 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -302,19 +302,31 @@ void MediumLevelILFunction::Finalize() void MediumLevelILFunction::GenerateSSAForm(bool analyzeConditionals, bool handleAliases, - const set<Variable>& knownAliases) + const set<Variable>& knownNotAliases, const set<Variable>& knownAliases) { - BNVariable* vars = new BNVariable[knownAliases.size()]; + BNVariable* knownNotAlias = new BNVariable[knownNotAliases.size()]; + BNVariable* knownAlias = new BNVariable[knownAliases.size()]; + size_t i = 0; + for (auto& j : knownNotAliases) + { + knownNotAlias[i].type = j.type; + knownNotAlias[i].index = j.index; + knownNotAlias[i].storage = j.storage; + } + + i = 0; for (auto& j : knownAliases) { - vars[i].type = j.type; - vars[i].index = j.index; - vars[i].storage = j.storage; + knownAlias[i].type = j.type; + knownAlias[i].index = j.index; + knownAlias[i].storage = j.storage; } - BNGenerateMediumLevelILSSAForm(m_object, analyzeConditionals, handleAliases, vars, knownAliases.size()); - delete[] vars; + BNGenerateMediumLevelILSSAForm(m_object, analyzeConditionals, handleAliases, knownNotAlias, knownNotAliases.size(), + knownAlias, knownAliases.size()); + delete[] knownNotAlias; + delete[] knownAlias; } diff --git a/python/binaryview.py b/python/binaryview.py index d977de50..bf8a87e0 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -927,6 +927,12 @@ class BinaryView(object): else: return BinaryView._associated_data[handle.value] + @property + def global_pointer_value(self): + """Discovered value of the global pointer register, if the binary uses one (read-only)""" + result = core.BNGetGlobalPointerValue(self.handle) + return function.RegisterValue(self.arch, result.value, confidence = result.confidence) + def __len__(self): return int(core.BNGetViewLength(self.handle)) diff --git a/python/callingconvention.py b/python/callingconvention.py index bd8bbeee..e72475c9 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -37,6 +37,7 @@ class CallingConvention(object): float_arg_regs = [] arg_regs_share_index = False stack_reserved_for_arg_regs = False + stack_adjusted_on_return = False int_return_reg = None high_int_return_reg = None float_return_reg = None @@ -59,6 +60,7 @@ class CallingConvention(object): self._cb.freeRegisterList = self._cb.freeRegisterList.__class__(self._free_register_list) self._cb.areArgumentRegistersSharedIndex = self._cb.areArgumentRegistersSharedIndex.__class__(self._arg_regs_share_index) self._cb.isStackReservedForArgumentRegisters = self._cb.isStackReservedForArgumentRegisters.__class__(self._stack_reserved_for_arg_regs) + self._cb.isStackAdjustedOnReturn = self._cb.isStackAdjustedOnReturn.__class__(self._stack_adjusted_on_return) self._cb.getIntegerReturnValueRegister = self._cb.getIntegerReturnValueRegister.__class__(self._get_int_return_reg) self._cb.getHighIntegerReturnValueRegister = self._cb.getHighIntegerReturnValueRegister.__class__(self._get_high_int_return_reg) self._cb.getFloatReturnValueRegister = self._cb.getFloatReturnValueRegister.__class__(self._get_float_return_reg) @@ -74,6 +76,7 @@ class CallingConvention(object): self.__dict__["name"] = core.BNGetCallingConventionName(self.handle) self.__dict__["arg_regs_share_index"] = core.BNAreArgumentRegistersSharedIndex(self.handle) self.__dict__["stack_reserved_for_arg_regs"] = core.BNIsStackReservedForArgumentRegisters(self.handle) + self.__dict__["stack_adjusted_on_return"] = core.BNIsStackAdjustedOnReturn(self.handle) count = ctypes.c_ulonglong() regs = core.BNGetCallerSavedRegisters(self.handle, count) @@ -218,6 +221,13 @@ class CallingConvention(object): log.log_error(traceback.format_exc()) return False + def _stack_adjusted_on_return(self, ctxt): + try: + return self.__class__.stack_adjusted_on_return + except: + log.log_error(traceback.format_exc()) + return False + def _get_int_return_reg(self, ctxt): try: return self.arch.regs[self.__class__.int_return_reg].index diff --git a/python/function.py b/python/function.py index 55151e16..553b156f 100644 --- a/python/function.py +++ b/python/function.py @@ -50,11 +50,12 @@ class LookupTableEntry(object): class RegisterValue(object): - def __init__(self, arch = None, value = None): + def __init__(self, arch = None, value = None, confidence = types.max_confidence): if value is None: self.type = RegisterValueType.UndeterminedValue else: self.type = RegisterValueType(value.state) + self.is_constant = False if value.state == RegisterValueType.EntryValue: self.arch = arch if arch is not None: @@ -63,8 +64,10 @@ class RegisterValue(object): self.reg = value.value elif (value.state == RegisterValueType.ConstantValue) or (value.state == RegisterValueType.ConstantPointerValue): self.value = value.value + self.is_constant = True elif value.state == RegisterValueType.StackFrameOffset: self.offset = value.value + self.confidence = confidence def __repr__(self): if self.type == RegisterValueType.EntryValue: @@ -280,6 +283,9 @@ class ParameterVariables(object): def __getitem__(self, idx): return self.vars[idx] + def __len__(self): + return len(self.vars) + def with_confidence(self, confidence): return ParameterVariables(list(self.vars), confidence = confidence) @@ -598,6 +604,52 @@ class Function(object): bc.confidence = types.max_confidence core.BNSetUserFunctionHasVariableArguments(self.handle, bc) + @property + def stack_adjustment(self): + """Number of bytes removed from the stack after return""" + result = core.BNGetFunctionStackAdjustment(self.handle) + return types.SizeWithConfidence(result.value, confidence = result.confidence) + + @stack_adjustment.setter + def stack_adjustment(self, value): + sc = core.BNSizeWithConfidence() + sc.value = int(value) + if hasattr(value, 'confidence'): + sc.confidence = value.confidence + else: + sc.confidence = types.max_confidence + core.BNSetUserFunctionStackAdjustment(self.handle, sc) + + @property + def clobbered_regs(self): + """Registers that are modified by this function""" + result = core.BNGetFunctionClobberedRegisters(self.handle) + reg_set = [] + for i in xrange(0, result.count): + reg_set.append(self.arch.get_reg_name(result.regs[i])) + regs = types.RegisterSet(reg_set, confidence = result.confidence) + core.BNFreeClobberedRegisters(result) + return regs + + @clobbered_regs.setter + def clobbered_regs(self, value): + regs = core.BNRegisterSetWithConfidence() + regs.regs = (ctypes.c_uint * len(value))() + regs.count = len(value) + for i in xrange(0, len(value)): + regs.regs[i] = self.arch.get_reg_index(value[i]) + if hasattr(value, 'confidence'): + regs.confidence = value.confidence + else: + regs.confidence = types.max_confidence + core.BNSetUserFunctionClobberedRegisters(self.handle, regs) + + @property + def global_pointer_value(self): + """Discovered value of the global pointer register, if the function uses one (read-only)""" + result = core.BNGetFunctionGlobalPointerValue(self.handle) + return RegisterValue(self.arch, result.value, confidence = result.confidence) + def __iter__(self): count = ctypes.c_ulonglong() blocks = core.BNGetFunctionBasicBlockList(self.handle, count) @@ -963,6 +1015,27 @@ class Function(object): bc.confidence = types.max_confidence core.BNSetAutoFunctionCanReturn(self.handle, bc) + def set_auto_stack_adjustment(self, value): + sc = core.BNSizeWithConfidence() + sc.value = int(value) + if hasattr(value, 'confidence'): + sc.confidence = value.confidence + else: + sc.confidence = types.max_confidence + core.BNSetAutoFunctionStackAdjustment(self.handle, sc) + + def set_auto_clobbered_regs(self, value): + regs = core.BNRegisterSetWithConfidence() + regs.regs = (ctypes.c_uint * len(value))() + regs.count = len(value) + for i in xrange(0, len(value)): + regs.regs[i] = self.arch.get_reg_index(value[i]) + if hasattr(value, 'confidence'): + regs.confidence = value.confidence + else: + regs.confidence = types.max_confidence + core.BNSetAutoFunctionClobberedRegisters(self.handle, regs) + def get_int_display_type(self, instr_addr, value, operand, arch=None): if arch is None: arch = self.arch @@ -1160,6 +1233,10 @@ class Function(object): core.BNFreeDisassemblyTextLines(lines, count.value) return result + def get_reg_value_at_exit(self, reg): + result = core.BNGetFunctionRegisterValueAtExit(self.handle, self.arch.get_reg_index(reg)) + return RegisterValue(self.arch, result.value, confidence = result.confidence) + class AdvancedFunctionAnalysisDataRequestor(object): def __init__(self, func = None): diff --git a/python/types.py b/python/types.py index fd2ee27e..bf4a7b74 100644 --- a/python/types.py +++ b/python/types.py @@ -650,6 +650,43 @@ class BoolWithConfidence(object): return self.value +class SizeWithConfidence(object): + def __init__(self, value, confidence = max_confidence): + self.value = value + self.confidence = confidence + + def __str__(self): + return str(self.value) + + def __repr__(self): + return repr(self.value) + + def __int__(self): + return self.value + + +class RegisterSet(object): + def __init__(self, reg_list, confidence = max_confidence): + self.regs = reg_list + self.confidence = confidence + + def __repr__(self): + return repr(self.regs) + + def __iter__(self): + for reg in self.regs: + yield reg + + def __getitem__(self, idx): + return self.regs[idx] + + def __len__(self): + return len(self.regs) + + def with_confidence(self, confidence): + return RegisterSet(list(self.regs), confidence = confidence) + + class ReferenceTypeWithConfidence(object): def __init__(self, value, confidence = max_confidence): self.value = value |
