diff options
| author | Jordan Wiens <jordan@psifertex.com> | 2016-07-24 19:12:18 -0400 |
|---|---|---|
| committer | Jordan Wiens <jordan@psifertex.com> | 2016-07-24 19:12:18 -0400 |
| commit | 4b722a7961e372bd5638a0e538272395d60a1797 (patch) | |
| tree | 8adfb97a94aa01e815cb29f8e1cd7d1e26c7f3b3 | |
| parent | 58f251e982f7c1b59c6934a72683a75c234b3b35 (diff) | |
| parent | 11cf9f176f45f03df16bf69c5ca33789ba0ded22 (diff) | |
Merge branch 'dev' of github.com:Vector35/binaryninja-api into dev
| -rw-r--r-- | architecture.cpp | 43 | ||||
| -rw-r--r-- | binaryninjaapi.h | 109 | ||||
| -rw-r--r-- | binaryninjacore.h | 104 | ||||
| -rw-r--r-- | binaryview.cpp | 258 | ||||
| -rw-r--r-- | binaryviewtype.cpp | 12 | ||||
| -rw-r--r-- | function.cpp | 12 | ||||
| -rw-r--r-- | python/__init__.py | 273 | ||||
| -rw-r--r-- | python/examples/nes.py | 1 |
8 files changed, 777 insertions, 35 deletions
diff --git a/architecture.cpp b/architecture.cpp index accfa69f..d068ff36 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -97,6 +97,20 @@ size_t Architecture::GetDefaultIntegerSizeCallback(void* ctxt) } +size_t Architecture::GetMaxInstructionLengthCallback(void* ctxt) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->GetMaxInstructionLength(); +} + + +size_t Architecture::GetOpcodeDisplayLengthCallback(void* ctxt) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->GetOpcodeDisplayLength(); +} + + bool Architecture::GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result) { @@ -390,6 +404,8 @@ void Architecture::Register(Architecture* arch) callbacks.getEndianness = GetEndiannessCallback; callbacks.getAddressSize = GetAddressSizeCallback; callbacks.getDefaultIntegerSize = GetDefaultIntegerSizeCallback; + callbacks.getMaxInstructionLength = GetMaxInstructionLengthCallback; + callbacks.getOpcodeDisplayLength = GetOpcodeDisplayLengthCallback; callbacks.getInstructionInfo = GetInstructionInfoCallback; callbacks.getInstructionText = GetInstructionTextCallback; callbacks.freeInstructionText = FreeInstructionTextCallback; @@ -466,6 +482,21 @@ size_t Architecture::GetDefaultIntegerSize() const } +size_t Architecture::GetMaxInstructionLength() const +{ + return BN_DEFAULT_NSTRUCTION_LENGTH; +} + + +size_t Architecture::GetOpcodeDisplayLength() const +{ + size_t maxLen = GetMaxInstructionLength(); + if (maxLen < BN_DEFAULT_OPCODE_DISPLAY) + return maxLen; + return BN_DEFAULT_OPCODE_DISPLAY; +} + + bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, LowLevelILFunction& il) { il.AddInstruction(il.Undefined()); @@ -874,6 +905,18 @@ size_t CoreArchitecture::GetDefaultIntegerSize() const } +size_t CoreArchitecture::GetMaxInstructionLength() const +{ + return BNGetArchitectureMaxInstructionLength(m_object); +} + + +size_t CoreArchitecture::GetOpcodeDisplayLength() const +{ + return BNGetArchitectureOpcodeDisplayLength(m_object); +} + + bool CoreArchitecture::GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) { return BNGetInstructionInfo(m_object, data, addr, maxLen, &result); diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 740247e4..1bdaab13 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -523,6 +523,7 @@ namespace BinaryNinja class BinaryView; class Function; + struct DataVariable; class BinaryDataNotification { @@ -535,6 +536,9 @@ namespace BinaryNinja static void FunctionAddedCallback(void* ctxt, BNBinaryView* data, BNFunction* func); static void FunctionRemovedCallback(void* ctxt, BNBinaryView* data, BNFunction* func); static void FunctionUpdatedCallback(void* ctxt, BNBinaryView* data, BNFunction* func); + static void DataVariableAddedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var); + static void DataVariableRemovedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var); + static void DataVariableUpdatedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var); static void StringFoundCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len); static void StringRemovedCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len); @@ -550,6 +554,9 @@ namespace BinaryNinja virtual void OnAnalysisFunctionAdded(BinaryView* view, Function* func) { (void)view; (void)func; } virtual void OnAnalysisFunctionRemoved(BinaryView* view, Function* func) { (void)view; (void)func; } virtual void OnAnalysisFunctionUpdated(BinaryView* view, Function* func) { (void)view; (void)func; } + virtual void OnDataVariableAdded(BinaryView* view, const DataVariable& var) { (void)view; (void)var; } + virtual void OnDataVariableRemoved(BinaryView* view, const DataVariable& var) { (void)view; (void)var; } + virtual void OnDataVariableUpdated(BinaryView* view, const DataVariable& var) { (void)view; (void)var; } virtual void OnStringFound(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; } virtual void OnStringRemoved(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; } }; @@ -616,6 +623,41 @@ namespace BinaryNinja Ref<Architecture> arch; uint64_t addr; }; + + struct InstructionTextToken + { + BNInstructionTextTokenType type; + std::string text; + uint64_t value; + + InstructionTextToken(); + InstructionTextToken(BNInstructionTextTokenType type, const std::string& text, uint64_t value = 0); + }; + + struct DisassemblyTextLine + { + uint64_t addr; + std::vector<InstructionTextToken> tokens; + }; + + struct LinearDisassemblyPosition + { + Ref<Function> function; + Ref<BasicBlock> block; + uint64_t address; + }; + + struct LinearDisassemblyLine + { + BNLinearDisassemblyLineType type; + Ref<Function> function; + Ref<BasicBlock> block; + size_t lineOffset; + DisassemblyTextLine contents; + }; + + class DisassemblySettings; + class AnalysisCompletionEvent: public CoreRefCountObject<BNAnalysisCompletionEvent, BNNewAnalysisCompletionEventReference, BNFreeAnalysisCompletionEvent> { @@ -630,6 +672,15 @@ namespace BinaryNinja void Cancel(); }; + struct DataVariable + { + uint64_t address; + Ref<Type> type; + bool autoDiscovered; + }; + + struct NameAndType; + /*! BinaryView is the base class for creating views on binary data (e.g. ELF, PE, Mach-O). BinaryView should be subclassed to create a new BinaryView */ @@ -768,6 +819,14 @@ namespace BinaryNinja void UpdateAnalysis(); void AbortAnalysis(); + void DefineDataVariable(uint64_t addr, Type* type); + void DefineUserDataVariable(uint64_t addr, Type* type); + void UndefineDataVariable(uint64_t addr); + void UndefineUserDataVariable(uint64_t addr); + + std::map<uint64_t, DataVariable> GetDataVariables(); + bool GetDataVariableAtAddress(uint64_t addr, DataVariable& var); + std::vector<Ref<Function>> GetAnalysisFunctionList(); bool HasFunctions() const; Ref<Function> GetAnalysisFunction(Platform* platform, uint64_t addr); @@ -797,7 +856,6 @@ namespace BinaryNinja void DefineImportedFunction(Symbol* importAddressSym, Function* func); - bool IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr); bool IsAlwaysBranchPatchAvailable(Architecture* arch, uint64_t addr); bool IsInvertBranchPatchAvailable(Architecture* arch, uint64_t addr); @@ -815,6 +873,24 @@ namespace BinaryNinja Ref<AnalysisCompletionEvent> AddAnalysisCompletionEvent(const std::function<void()>& callback); BNAnalysisProgress GetAnalysisProgress(); + + uint64_t GetNextFunctionStartAfterAddress(uint64_t addr); + uint64_t GetNextBasicBlockStartAfterAddress(uint64_t addr); + uint64_t GetNextDataAfterAddress(uint64_t addr); + uint64_t GetNextDataVariableAfterAddress(uint64_t addr); + uint64_t GetPreviousFunctionStartBeforeAddress(uint64_t addr); + uint64_t GetPreviousBasicBlockStartBeforeAddress(uint64_t addr); + uint64_t GetPreviousBasicBlockEndBeforeAddress(uint64_t addr); + uint64_t GetPreviousDataBeforeAddress(uint64_t addr); + uint64_t GetPreviousDataVariableBeforeAddress(uint64_t addr); + + LinearDisassemblyPosition GetLinearDisassemblyPositionForAddress(uint64_t addr, DisassemblySettings* settings); + std::vector<LinearDisassemblyLine> GetPreviousLinearDisassemblyLines(LinearDisassemblyPosition& pos, + DisassemblySettings* settings); + std::vector<LinearDisassemblyLine> GetNextLinearDisassemblyLines(LinearDisassemblyPosition& pos, + DisassemblySettings* settings); + + bool ParseTypeString(const std::string& text, NameAndType& result, std::string& errors); }; class BinaryData: public BinaryView @@ -848,9 +924,9 @@ namespace BinaryNinja static std::vector<Ref<BinaryViewType>> GetViewTypes(); static std::vector<Ref<BinaryViewType>> GetViewTypesForData(BinaryView* data); - static void RegisterArchitecture(const std::string& name, uint32_t id, Architecture* arch); - void RegisterArchitecture(uint32_t id, Architecture* arch); - Ref<Architecture> GetArchitecture(uint32_t id); + static void RegisterArchitecture(const std::string& name, uint32_t id, BNEndianness endian, Architecture* arch); + void RegisterArchitecture(uint32_t id, BNEndianness endian, Architecture* arch); + Ref<Architecture> GetArchitecture(uint32_t id, BNEndianness endian); static void RegisterPlatform(const std::string& name, uint32_t id, Architecture* arch, Platform* platform); static void RegisterDefaultPlatform(const std::string& name, Architecture* arch, Platform* platform); @@ -1039,16 +1115,6 @@ namespace BinaryNinja void AddBranch(BNBranchType type, uint64_t target = 0, Architecture* arch = nullptr, bool hasDelaySlot = false); }; - struct InstructionTextToken - { - BNInstructionTextTokenType type; - std::string text; - uint64_t value; - - InstructionTextToken(); - InstructionTextToken(BNInstructionTextTokenType type, const std::string& text, uint64_t value = 0); - }; - class LowLevelILFunction; class FunctionRecognizer; class CallingConvention; @@ -1070,6 +1136,8 @@ namespace BinaryNinja static BNEndianness GetEndiannessCallback(void* ctxt); static size_t GetAddressSizeCallback(void* ctxt); static size_t GetDefaultIntegerSizeCallback(void* ctxt); + static size_t GetMaxInstructionLengthCallback(void* ctxt); + static size_t GetOpcodeDisplayLengthCallback(void* ctxt); static bool GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result); static bool GetInstructionTextCallback(void* ctxt, const uint8_t* data, uint64_t addr, @@ -1121,6 +1189,9 @@ namespace BinaryNinja virtual size_t GetAddressSize() const = 0; virtual size_t GetDefaultIntegerSize() const; + virtual size_t GetMaxInstructionLength() const; + virtual size_t GetOpcodeDisplayLength() const; + virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) = 0; virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) = 0; @@ -1262,6 +1333,8 @@ namespace BinaryNinja virtual BNEndianness GetEndianness() const override; virtual size_t GetAddressSize() const override; virtual size_t GetDefaultIntegerSize() const override; + virtual size_t GetMaxInstructionLength() const override; + virtual size_t GetOpcodeDisplayLength() const override; virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override; virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override; @@ -1415,12 +1488,6 @@ namespace BinaryNinja void SetMaximumSymbolWidth(size_t width); }; - struct DisassemblyTextLine - { - uint64_t addr; - std::vector<InstructionTextToken> tokens; - }; - class Function; struct BasicBlockEdge @@ -1549,6 +1616,8 @@ namespace BinaryNinja std::set<uint32_t> GetFlagsWrittenByLiftedILInstruction(size_t i); Ref<Type> GetType() const; + void SetAutoType(Type* type); + void SetUserType(Type* type); void ApplyImportedTypes(Symbol* sym); void ApplyAutoDiscoveredType(Type* type); diff --git a/binaryninjacore.h b/binaryninjacore.h index d5274c5b..241f1f3d 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -45,7 +45,9 @@ #endif #endif -#define BN_MAX_INSTRUCTION_LENGTH 16 +#define BN_MAX_INSTRUCTION_LENGTH 256 +#define BN_DEFAULT_NSTRUCTION_LENGTH 16 +#define BN_DEFAULT_OPCODE_DISPLAY 8 #define BN_MAX_INSTRUCTION_BRANCHES 3 #define BN_MAX_STORED_DATA_LENGTH 0x3fffffff @@ -159,6 +161,18 @@ extern "C" FloatingPointToken = 8, AnnotationToken = 9, CodeRelativeAddressToken = 10, + StackVariableTypeToken = 11, + DataVariableTypeToken = 12, + FunctionReturnTypeToken = 13, + FunctionAttributeToken = 14, + ArgumentTypeToken = 15, + ArgumentNameToken = 16, + HexDumpByteValueToken = 17, + HexDumpSkippedByteToken = 18, + HexDumpInvalidByteToken = 19, + HexDumpTextToken = 20, + OpcodeToken = 21, + StringToken = 22, // The following are output by the analysis system automatically, these should // not be used directly by the architecture plugins @@ -169,6 +183,21 @@ extern "C" AddressDisplayToken = 68 }; + enum BNLinearDisassemblyLineType + { + BlankLineType, + CodeDisassemblyLineType, + DataVariableLineType, + HexDumpLineType, + FunctionHeaderLineType, + FunctionHeaderStartLineType, + FunctionHeaderEndLineType, + FunctionContinuationLineType, + StackVariableLineType, + StackVariableListEndLineType, + FunctionEndLineType + }; + enum BNSymbolType { FunctionSymbol = 0, @@ -298,6 +327,11 @@ extern "C" enum BNDisassemblyOption { ShowAddress = 0, + ShowOpcode = 1, + ExpandLongOpcode = 2, + + // Linear disassembly options + GroupLinearDisassemblyFunctions = 64, // Debugging options ShowBasicBlockRegisterState = 128, @@ -524,6 +558,13 @@ extern "C" uint64_t value; }; + struct BNDataVariable + { + uint64_t address; + BNType* type; + bool autoDiscovered; + }; + // Callbacks struct BNLogListener { @@ -550,6 +591,9 @@ extern "C" void (*functionAdded)(void* ctxt, BNBinaryView* view, BNFunction* func); void (*functionRemoved)(void* ctxt, BNBinaryView* view, BNFunction* func); void (*functionUpdated)(void* ctxt, BNBinaryView* view, BNFunction* func); + void (*dataVariableAdded)(void* ctxt, BNBinaryView* view, BNDataVariable* var); + void (*dataVariableRemoved)(void* ctxt, BNBinaryView* view, BNDataVariable* var); + void (*dataVariableUpdated)(void* ctxt, BNBinaryView* view, BNDataVariable* var); void (*stringFound)(void* ctxt, BNBinaryView* view, BNStringType type, uint64_t offset, size_t len); void (*stringRemoved)(void* ctxt, BNBinaryView* view, BNStringType type, uint64_t offset, size_t len); }; @@ -645,6 +689,8 @@ extern "C" BNEndianness (*getEndianness)(void* ctxt); size_t (*getAddressSize)(void* ctxt); size_t (*getDefaultIntegerSize)(void* ctxt); + size_t (*getMaxInstructionLength)(void* ctxt); + size_t (*getOpcodeDisplayLength)(void* ctxt); bool (*getInstructionInfo)(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result); bool (*getInstructionText)(void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNInstructionTextToken** result, size_t* count); @@ -711,6 +757,22 @@ extern "C" size_t count; }; + struct BNLinearDisassemblyLine + { + BNLinearDisassemblyLineType type; + BNFunction* function; + BNBasicBlock* block; + size_t lineOffset; + BNDisassemblyTextLine contents; + }; + + struct BNLinearDisassemblyPosition + { + BNFunction* function; + BNBasicBlock* block; + uint64_t address; + }; + struct BNReferenceSource { BNFunction* func; @@ -1077,8 +1139,10 @@ extern "C" BINARYNINJACOREAPI BNBinaryViewType* BNRegisterBinaryViewType(const char* name, const char* longName, BNCustomBinaryViewType* type); - BINARYNINJACOREAPI void BNRegisterArchitectureForViewType(BNBinaryViewType* type, uint32_t id, BNArchitecture* arch); - BINARYNINJACOREAPI BNArchitecture* BNGetArchitectureForViewType(BNBinaryViewType* type, uint32_t id); + BINARYNINJACOREAPI void BNRegisterArchitectureForViewType(BNBinaryViewType* type, uint32_t id, + BNEndianness endian, BNArchitecture* arch); + BINARYNINJACOREAPI BNArchitecture* BNGetArchitectureForViewType(BNBinaryViewType* type, uint32_t id, + BNEndianness endian); BINARYNINJACOREAPI void BNRegisterPlatformForViewType(BNBinaryViewType* type, uint32_t id, BNArchitecture* arch, BNPlatform* platform); @@ -1159,6 +1223,8 @@ extern "C" BINARYNINJACOREAPI BNEndianness BNGetArchitectureEndianness(BNArchitecture* arch); BINARYNINJACOREAPI size_t BNGetArchitectureAddressSize(BNArchitecture* arch); BINARYNINJACOREAPI size_t BNGetArchitectureDefaultIntegerSize(BNArchitecture* arch); + BINARYNINJACOREAPI size_t BNGetArchitectureMaxInstructionLength(BNArchitecture* arch); + BINARYNINJACOREAPI size_t BNGetArchitectureOpcodeDisplayLength(BNArchitecture* arch); BINARYNINJACOREAPI bool BNGetInstructionInfo(BNArchitecture* arch, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result); BINARYNINJACOREAPI bool BNGetInstructionText(BNArchitecture* arch, const uint8_t* data, uint64_t addr, @@ -1246,6 +1312,8 @@ extern "C" BINARYNINJACOREAPI BNSymbol* BNGetFunctionSymbol(BNFunction* func); BINARYNINJACOREAPI bool BNWasFunctionAutomaticallyDiscovered(BNFunction* func); BINARYNINJACOREAPI bool BNCanFunctionReturn(BNFunction* func); + BINARYNINJACOREAPI void BNSetFunctionAutoType(BNFunction* func, BNType* type); + BINARYNINJACOREAPI void BNSetFunctionUserType(BNFunction* func, BNType* type); BINARYNINJACOREAPI char* BNGetCommentForAddress(BNFunction* func, uint64_t addr); BINARYNINJACOREAPI uint64_t* BNGetCommentedAddresses(BNFunction* func, size_t* count); @@ -1362,6 +1430,36 @@ extern "C" BINARYNINJACOREAPI BNAnalysisProgress BNGetAnalysisProgress(BNBinaryView* view); + BINARYNINJACOREAPI uint64_t BNGetNextFunctionStartAfterAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetNextBasicBlockStartAfterAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetNextDataAfterAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetNextDataVariableAfterAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetPreviousFunctionStartBeforeAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetPreviousBasicBlockStartBeforeAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetPreviousBasicBlockEndBeforeAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetPreviousDataBeforeAddress(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI uint64_t BNGetPreviousDataVariableBeforeAddress(BNBinaryView* view, uint64_t addr); + + BINARYNINJACOREAPI BNLinearDisassemblyPosition BNGetLinearDisassemblyPositionForAddress(BNBinaryView* view, + uint64_t addr, BNDisassemblySettings* settings); + BINARYNINJACOREAPI void BNFreeLinearDisassemblyPosition(BNLinearDisassemblyPosition* pos); + BINARYNINJACOREAPI BNLinearDisassemblyLine* BNGetPreviousLinearDisassemblyLines(BNBinaryView* view, + BNLinearDisassemblyPosition* pos, BNDisassemblySettings* settings, size_t* count); + BINARYNINJACOREAPI BNLinearDisassemblyLine* BNGetNextLinearDisassemblyLines(BNBinaryView* view, + BNLinearDisassemblyPosition* pos, BNDisassemblySettings* settings, size_t* count); + BINARYNINJACOREAPI void BNFreeLinearDisassemblyLines(BNLinearDisassemblyLine* lines, size_t count); + + BINARYNINJACOREAPI void BNDefineDataVariable(BNBinaryView* view, uint64_t addr, BNType* type); + BINARYNINJACOREAPI void BNDefineUserDataVariable(BNBinaryView* view, uint64_t addr, BNType* type); + BINARYNINJACOREAPI void BNUndefineDataVariable(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI void BNUndefineUserDataVariable(BNBinaryView* view, uint64_t addr); + BINARYNINJACOREAPI BNDataVariable* BNGetDataVariables(BNBinaryView* view, size_t* count); + BINARYNINJACOREAPI void BNFreeDataVariables(BNDataVariable* vars, size_t count); + BINARYNINJACOREAPI bool BNGetDataVariableAtAddress(BNBinaryView* view, uint64_t addr, BNDataVariable* var); + + BINARYNINJACOREAPI bool BNParseTypeString(BNBinaryView* view, const char* text, BNNameAndType* result, char** errors); + BINARYNINJACOREAPI void BNFreeNameAndType(BNNameAndType* obj); + // Disassembly settings BINARYNINJACOREAPI BNDisassemblySettings* BNCreateDisassemblySettings(void); BINARYNINJACOREAPI BNDisassemblySettings* BNNewDisassemblySettingsReference(BNDisassemblySettings* settings); diff --git a/binaryview.cpp b/binaryview.cpp index a3abc02a..ee5bda8e 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -75,6 +75,42 @@ void BinaryDataNotification::FunctionUpdatedCallback(void* ctxt, BNBinaryView* o } +void BinaryDataNotification::DataVariableAddedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var) +{ + BinaryDataNotification* notify = (BinaryDataNotification*)ctxt; + Ref<BinaryView> view = new BinaryView(BNNewViewReference(object)); + DataVariable varObj; + varObj.address = var->address; + varObj.type = new Type(BNNewTypeReference(var->type)); + varObj.autoDiscovered = var->autoDiscovered; + notify->OnDataVariableAdded(view, varObj); +} + + +void BinaryDataNotification::DataVariableRemovedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var) +{ + BinaryDataNotification* notify = (BinaryDataNotification*)ctxt; + Ref<BinaryView> view = new BinaryView(BNNewViewReference(object)); + DataVariable varObj; + varObj.address = var->address; + varObj.type = new Type(BNNewTypeReference(var->type)); + varObj.autoDiscovered = var->autoDiscovered; + notify->OnDataVariableRemoved(view, varObj); +} + + +void BinaryDataNotification::DataVariableUpdatedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var) +{ + BinaryDataNotification* notify = (BinaryDataNotification*)ctxt; + Ref<BinaryView> view = new BinaryView(BNNewViewReference(object)); + DataVariable varObj; + varObj.address = var->address; + varObj.type = new Type(BNNewTypeReference(var->type)); + varObj.autoDiscovered = var->autoDiscovered; + notify->OnDataVariableUpdated(view, varObj); +} + + void BinaryDataNotification::StringFoundCallback(void* ctxt, BNBinaryView* object, BNStringType type, uint64_t offset, size_t len) { BinaryDataNotification* notify = (BinaryDataNotification*)ctxt; @@ -100,6 +136,9 @@ BinaryDataNotification::BinaryDataNotification() m_callbacks.functionAdded = FunctionAddedCallback; m_callbacks.functionRemoved = FunctionRemovedCallback; m_callbacks.functionUpdated = FunctionUpdatedCallback; + m_callbacks.dataVariableAdded = DataVariableAddedCallback; + m_callbacks.dataVariableRemoved = DataVariableRemovedCallback; + m_callbacks.dataVariableUpdated = DataVariableUpdatedCallback; m_callbacks.stringFound = StringFoundCallback; m_callbacks.stringRemoved = StringRemovedCallback; } @@ -764,6 +803,67 @@ void BinaryView::AbortAnalysis() } +void BinaryView::DefineDataVariable(uint64_t addr, Type* type) +{ + BNDefineDataVariable(m_object, addr, type->GetObject()); +} + + +void BinaryView::DefineUserDataVariable(uint64_t addr, Type* type) +{ + BNDefineUserDataVariable(m_object, addr, type->GetObject()); +} + + +void BinaryView::UndefineDataVariable(uint64_t addr) +{ + BNUndefineDataVariable(m_object, addr); +} + + +void BinaryView::UndefineUserDataVariable(uint64_t addr) +{ + BNUndefineUserDataVariable(m_object, addr); +} + + +map<uint64_t, DataVariable> BinaryView::GetDataVariables() +{ + size_t count; + BNDataVariable* vars = BNGetDataVariables(m_object, &count); + + map<uint64_t, DataVariable> result; + for (size_t i = 0; i < count; i++) + { + DataVariable var; + var.address = vars[i].address; + var.type = new Type(BNNewTypeReference(vars[i].type)); + var.autoDiscovered = vars[i].autoDiscovered; + result[var.address] = var; + } + + BNFreeDataVariables(vars, count); + return result; +} + + +bool BinaryView::GetDataVariableAtAddress(uint64_t addr, DataVariable& var) +{ + var.address = 0; + var.type = nullptr; + var.autoDiscovered = false; + + BNDataVariable result; + if (!BNGetDataVariableAtAddress(m_object, addr, &result)) + return false; + + var.address = result.address; + var.type = new Type(result.type); + var.autoDiscovered = result.autoDiscovered; + return true; +} + + vector<Ref<Function>> BinaryView::GetAnalysisFunctionList() { size_t count; @@ -1100,6 +1200,164 @@ BNAnalysisProgress BinaryView::GetAnalysisProgress() } +uint64_t BinaryView::GetNextFunctionStartAfterAddress(uint64_t addr) +{ + return BNGetNextFunctionStartAfterAddress(m_object, addr); +} + + +uint64_t BinaryView::GetNextBasicBlockStartAfterAddress(uint64_t addr) +{ + return BNGetNextBasicBlockStartAfterAddress(m_object, addr); +} + + +uint64_t BinaryView::GetNextDataAfterAddress(uint64_t addr) +{ + return BNGetNextDataAfterAddress(m_object, addr); +} + + +uint64_t BinaryView::GetPreviousFunctionStartBeforeAddress(uint64_t addr) +{ + return BNGetPreviousFunctionStartBeforeAddress(m_object, addr); +} + + +uint64_t BinaryView::GetPreviousBasicBlockStartBeforeAddress(uint64_t addr) +{ + return BNGetPreviousBasicBlockStartBeforeAddress(m_object, addr); +} + + +uint64_t BinaryView::GetPreviousBasicBlockEndBeforeAddress(uint64_t addr) +{ + return BNGetPreviousBasicBlockEndBeforeAddress(m_object, addr); +} + + +uint64_t BinaryView::GetPreviousDataBeforeAddress(uint64_t addr) +{ + return BNGetPreviousDataBeforeAddress(m_object, addr); +} + + +LinearDisassemblyPosition BinaryView::GetLinearDisassemblyPositionForAddress(uint64_t addr, + DisassemblySettings* settings) +{ + BNLinearDisassemblyPosition pos = BNGetLinearDisassemblyPositionForAddress(m_object, addr, + settings ? settings->GetObject() : nullptr); + + LinearDisassemblyPosition result; + result.function = pos.function ? new Function(pos.function) : nullptr; + result.block = pos.block ? new BasicBlock(pos.block) : nullptr; + result.address = pos.address; + return result; +} + + +vector<LinearDisassemblyLine> BinaryView::GetPreviousLinearDisassemblyLines(LinearDisassemblyPosition& pos, + DisassemblySettings* settings) +{ + BNLinearDisassemblyPosition linearPos; + linearPos.function = pos.function ? BNNewFunctionReference(pos.function->GetObject()) : nullptr; + linearPos.block = pos.block ? BNNewBasicBlockReference(pos.block->GetObject()) : nullptr; + linearPos.address = pos.address; + + size_t count; + BNLinearDisassemblyLine* lines = BNGetPreviousLinearDisassemblyLines(m_object, &linearPos, + settings ? settings->GetObject() : nullptr, &count); + + vector<LinearDisassemblyLine> result; + for (size_t i = 0; i < count; i++) + { + LinearDisassemblyLine line; + line.type = lines[i].type; + line.function = lines[i].function ? new Function(BNNewFunctionReference(lines[i].function)) : nullptr; + line.block = lines[i].block ? new BasicBlock(BNNewBasicBlockReference(lines[i].block)) : nullptr; + line.lineOffset = lines[i].lineOffset; + line.contents.addr = lines[i].contents.addr; + for (size_t j = 0; j < lines[i].contents.count; j++) + { + InstructionTextToken token; + token.type = lines[i].contents.tokens[j].type; + token.text = lines[i].contents.tokens[j].text; + token.value = lines[i].contents.tokens[j].value; + line.contents.tokens.push_back(token); + } + result.push_back(line); + } + + pos.function = linearPos.function ? new Function(linearPos.function) : nullptr; + pos.block = linearPos.block ? new BasicBlock(linearPos.block) : nullptr; + pos.address = linearPos.address; + + BNFreeLinearDisassemblyLines(lines, count); + return result; +} + + +vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDisassemblyPosition& pos, + DisassemblySettings* settings) +{ + BNLinearDisassemblyPosition linearPos; + linearPos.function = pos.function ? BNNewFunctionReference(pos.function->GetObject()) : nullptr; + linearPos.block = pos.block ? BNNewBasicBlockReference(pos.block->GetObject()) : nullptr; + linearPos.address = pos.address; + + size_t count; + BNLinearDisassemblyLine* lines = BNGetNextLinearDisassemblyLines(m_object, &linearPos, + settings ? settings->GetObject() : nullptr, &count); + + vector<LinearDisassemblyLine> result; + for (size_t i = 0; i < count; i++) + { + LinearDisassemblyLine line; + line.type = lines[i].type; + line.function = lines[i].function ? new Function(BNNewFunctionReference(lines[i].function)) : nullptr; + line.block = lines[i].block ? new BasicBlock(BNNewBasicBlockReference(lines[i].block)) : nullptr; + line.lineOffset = lines[i].lineOffset; + line.contents.addr = lines[i].contents.addr; + for (size_t j = 0; j < lines[i].contents.count; j++) + { + InstructionTextToken token; + token.type = lines[i].contents.tokens[j].type; + token.text = lines[i].contents.tokens[j].text; + token.value = lines[i].contents.tokens[j].value; + line.contents.tokens.push_back(token); + } + result.push_back(line); + } + + pos.function = linearPos.function ? new Function(linearPos.function) : nullptr; + pos.block = linearPos.block ? new BasicBlock(linearPos.block) : nullptr; + pos.address = linearPos.address; + + BNFreeLinearDisassemblyLines(lines, count); + return result; +} + + +bool BinaryView::ParseTypeString(const string& text, NameAndType& result, string& errors) +{ + BNNameAndType nt; + char* errorStr; + + if (!BNParseTypeString(m_object, text.c_str(), &nt, &errorStr)) + { + errors = errorStr; + BNFreeString(errorStr); + return false; + } + + result.name = nt.name; + result.type = new Type(nt.type); + errors = ""; + BNFreeString(nt.name); + return true; +} + + BinaryData::BinaryData(FileMetadata* file): BinaryView(BNCreateBinaryDataView(file->GetObject())) { } diff --git a/binaryviewtype.cpp b/binaryviewtype.cpp index 12883bd6..e7feb68c 100644 --- a/binaryviewtype.cpp +++ b/binaryviewtype.cpp @@ -106,24 +106,24 @@ vector<Ref<BinaryViewType>> BinaryViewType::GetViewTypesForData(BinaryView* data } -void BinaryViewType::RegisterArchitecture(const string& name, uint32_t id, Architecture* arch) +void BinaryViewType::RegisterArchitecture(const string& name, uint32_t id, BNEndianness endian, Architecture* arch) { Ref<BinaryViewType> type = BinaryViewType::GetByName(name); if (!type) return; - type->RegisterArchitecture(id, arch); + type->RegisterArchitecture(id, endian, arch); } -void BinaryViewType::RegisterArchitecture(uint32_t id, Architecture* arch) +void BinaryViewType::RegisterArchitecture(uint32_t id, BNEndianness endian, Architecture* arch) { - BNRegisterArchitectureForViewType(m_object, id, arch->GetObject()); + BNRegisterArchitectureForViewType(m_object, id, endian, arch->GetObject()); } -Ref<Architecture> BinaryViewType::GetArchitecture(uint32_t id) +Ref<Architecture> BinaryViewType::GetArchitecture(uint32_t id, BNEndianness endian) { - BNArchitecture* arch = BNGetArchitectureForViewType(m_object, id); + BNArchitecture* arch = BNGetArchitectureForViewType(m_object, id, endian); if (!arch) return nullptr; return new CoreArchitecture(arch); diff --git a/function.cpp b/function.cpp index ea0fec86..55f5cffb 100644 --- a/function.cpp +++ b/function.cpp @@ -354,6 +354,18 @@ Ref<Type> Function::GetType() const } +void Function::SetAutoType(Type* type) +{ + BNSetFunctionAutoType(m_object, type->GetObject()); +} + + +void Function::SetUserType(Type* type) +{ + BNSetFunctionUserType(m_object, type->GetObject()); +} + + void Function::ApplyImportedTypes(Symbol* sym) { BNApplyImportedTypes(m_object, sym->GetObject()); diff --git a/python/__init__.py b/python/__init__.py index 98b16b95..4d7e7fb8 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -387,6 +387,15 @@ class BinaryDataNotification: def function_updated(self, view, func): pass + def data_var_added(self, view, var): + pass + + def data_var_removed(self, view, var): + pass + + def data_var_updated(self, view, var): + pass + def string_found(self, view, string_type, offset, length): pass @@ -483,6 +492,9 @@ class BinaryDataNotificationCallbacks: self._cb.functionAdded = self._cb.functionAdded.__class__(self._function_added) self._cb.functionRemoved = self._cb.functionRemoved.__class__(self._function_removed) self._cb.functionUpdated = self._cb.functionUpdated.__class__(self._function_updated) + self._cb.dataVariableAdded = self._cb.dataVariableAdded.__class__(self._data_var_added) + self._cb.dataVariableRemoved = self._cb.dataVariableRemoved.__class__(self._data_var_removed) + self._cb.dataVariableUpdated = self._cb.dataVariableUpdated.__class__(self._data_var_updated) self._cb.stringFound = self._cb.stringFound.__class__(self._string_found) self._cb.stringRemoved = self._cb.stringRemoved.__class__(self._string_removed) @@ -528,6 +540,33 @@ class BinaryDataNotificationCallbacks: except: log_error(traceback.format_exc()) + def _data_var_added(self, ctxt, view, var): + try: + address = var.address + var_type = Type(core.BNNewTypeReference(var.type)) + auto_discovered = var.autoDiscovered + self.notify.data_var_added(self.view, DataVariable(address, var_type, auto_discovered)) + except: + log_error(traceback.format_exc()) + + def _data_var_removed(self, ctxt, view, var): + try: + address = var.address + var_type = Type(core.BNNewTypeReference(var.type)) + auto_discovered = var.autoDiscovered + self.notify.data_var_removed(self.view, DataVariable(address, var_type, auto_discovered)) + except: + log_error(traceback.format_exc()) + + def _data_var_updated(self, ctxt, view, var): + try: + address = var.address + var_type = Type(core.BNNewTypeReference(var.type)) + auto_discovered = var.autoDiscovered + self.notify.data_var_updated(self.view, DataVariable(address, var_type, auto_discovered)) + except: + log_error(traceback.format_exc()) + def _string_found(self, ctxt, view, string_type, offset, length): try: self.notify.string_found(self.view, core.BNStringType_names[string_type], offset, length) @@ -610,11 +649,11 @@ class BinaryViewType(object): def is_valid_for_data(self, data): return core.BNIsBinaryViewTypeValidForData(self.handle, data.handle) - def register_arch(self, ident, arch): - core.BNRegisterArchitectureForViewType(self.handle, ident, arch.handle) + def register_arch(self, ident, endian, arch): + core.BNRegisterArchitectureForViewType(self.handle, ident, endian, arch.handle) - def get_arch(self, ident): - arch = core.BNGetArchitectureForViewType(self.handle, ident) + def get_arch(self, ident, endian): + arch = core.BNGetArchitectureForViewType(self.handle, ident, endian) if arch is None: return None return Architecture(arch) @@ -676,6 +715,35 @@ class AnalysisProgress(object): def __repr__(self): return "<progress: %s>" % str(self) +class LinearDisassemblyPosition(object): + def __init__(self, func, block, addr): + self.function = func + self.block = block + self.address = addr + +class LinearDisassemblyLine(object): + def __init__(self, line_type, func, block, line_offset, contents): + self.type = line_type + self.function = func + self.block = block + self.line_offset = line_offset + self.contents = contents + + def __str__(self): + return str(self.contents) + + def __repr__(self): + return repr(self.contents) + +class DataVariable(object): + def __init__(self, addr, var_type, auto_discovered): + self.address = addr + self.type = var_type + self.auto_discovered = auto_discovered + + def __repr__(self): + return "<var 0x%x: %s>" % (self.address, str(self.type)) + class BinaryView(object): name = None """Binary View name""" @@ -969,6 +1037,25 @@ class BinaryView(object): result = core.BNGetAnalysisProgress(self.handle) return AnalysisProgress(result.state, result.count, result.total) + @property + def linear_disassembly(self): + """Iterator for all lines in the linear disassembly of the view""" + return self.get_linear_disassembly(None) + + @property + def data_vars(self): + """List of data variables (read-only)""" + count = ctypes.c_ulonglong(0) + var_list = core.BNGetDataVariables(self.handle, count) + result = {} + for i in xrange(0, count.value): + addr = var_list[i].address + var_type = Type(core.BNNewTypeReference(var_list[i].type)) + auto_discovered = var_list[i].autoDiscovered + result[addr] = DataVariable(addr, var_type, auto_discovered) + core.BNFreeDataVariables(var_list, count.value) + return result + def __len__(self): return int(core.BNGetViewLength(self.handle)) @@ -1342,6 +1429,24 @@ class BinaryView(object): def abort_analysis(self): core.BNAbortAnalysis(self.handle) + def define_data_var(self, addr, var_type): + core.BNDefineDataVariable(self.handle, addr, var_type.handle) + + def define_user_data_var(self, addr, var_type): + core.BNDefineUserDataVariable(self.handle, addr, var_type.handle) + + def undefine_data_var(self, addr): + core.BNUndefineDataVariable(self.handle, addr) + + def undefine_user_data_var(self, addr): + core.BNUndefineUserDataVariable(self.handle, addr) + + def get_data_var_at(self, addr): + var = core.BNDataVariable() + if not core.BNGetDataVariableAtAddress(self.handle, addr, var): + return None + return DataVariable(var.address, Type(var.type), var.autoDiscovered) + def get_function_at(self, platform, addr): func = core.BNGetAnalysisFunction(self.handle, platform.handle, addr) if func is None: @@ -1518,6 +1623,128 @@ class BinaryView(object): def add_analysis_completion_event(self, callback): return AnalysisCompletionEvent(self, callback) + def get_next_function_start_after(self, addr): + return core.BNGetNextFunctionStartAfterAddress(self.handle, addr) + + def get_next_basic_block_start_after(self, addr): + return core.BNGetNextBasicBlockStartAfterAddress(self.handle, addr) + + def get_next_data_after(self, addr): + return core.BNGetNextDataAfterAddress(self.handle, addr) + + def get_next_data_var_after(self, addr): + return core.BNGetNextDataVariableAfterAddress(self.handle, addr) + + def get_previous_function_start_before(self, addr): + return core.BNGetPreviousFunctionStartBeforeAddress(self.handle, addr) + + def get_previous_basic_block_start_before(self, addr): + return core.BNGetPreviousBasicBlockStartBeforeAddress(self.handle, addr) + + def get_previous_basic_block_end_before(self, addr): + return core.BNGetPreviousBasicBlockEndBeforeAddress(self.handle, addr) + + def get_previous_data_before(self, addr): + return core.BNGetPreviousDataBeforeAddress(self.handle, addr) + + def get_previous_data_var_before(self, addr): + return core.BNGetPreviousDataVariableBeforeAddress(self.handle, addr) + + def get_linear_disassembly_position_at(self, addr, settings): + if settings is not None: + settings = settings.handle + pos = core.BNGetLinearDisassemblyPositionForAddress(self.handle, addr, settings) + func = None + block = None + if pos.function: + func = Function(self, pos.function) + if pos.block: + block = BasicBlock(self, pos.block) + return LinearDisassemblyPosition(func, block, pos.address) + + def _get_linear_disassembly_lines(self, api, pos, settings): + pos_obj = core.BNLinearDisassemblyPosition() + pos_obj.function = None + pos_obj.block = None + pos_obj.address = pos.address + if pos.function is not None: + pos_obj.function = core.BNNewFunctionReference(pos.function.handle) + if pos.block is not None: + pos_obj.block = core.BNNewBasicBlockReference(pos.block.handle) + + if settings is not None: + settings = settings.handle + + count = ctypes.c_ulonglong(0) + lines = api(self.handle, pos_obj, settings, count) + + result = [] + for i in xrange(0, count.value): + func = None + block = None + if lines[i].function: + func = Function(self, core.BNNewFunctionReference(lines[i].function)) + if lines[i].block: + block = BasicBlock(self, core.BNNewBasicBlockReference(lines[i].block)) + addr = lines[i].contents.addr + tokens = [] + for j in xrange(0, lines[i].contents.count): + token_type = core.BNInstructionTextTokenType_names[lines[i].contents.tokens[j].type] + text = lines[i].contents.tokens[j].text + value = lines[i].contents.tokens[j].value + tokens.append(InstructionTextToken(token_type, text, value)) + contents = DisassemblyTextLine(addr, tokens) + result.append(LinearDisassemblyLine(lines[i].type, func, block, lines[i].lineOffset, contents)) + + func = None + block = None + if pos_obj.function: + func = Function(self, pos_obj.function) + if pos_obj.block: + block = BasicBlock(self, pos_obj.block) + pos.function = func + pos.block = block + pos.address = pos_obj.address + + core.BNFreeLinearDisassemblyLines(lines, count.value) + return result + + def get_previous_linear_disassembly_lines(self, pos, settings): + return self._get_linear_disassembly_lines(core.BNGetPreviousLinearDisassemblyLines, pos, settings) + + def get_next_linear_disassembly_lines(self, pos, settings): + return self._get_linear_disassembly_lines(core.BNGetNextLinearDisassemblyLines, pos, settings) + + def get_linear_disassembly(self, settings): + """Gets an iterator for all lines in the linear disassembly of the view for the given disassembly settings""" + class LinearDisassemblyIterator(object): + def __init__(self, view, settings): + self.view = view + self.settings = settings + + def __iter__(self): + pos = self.view.get_linear_disassembly_position_at(self.view.start, self.settings) + while True: + lines = self.view.get_next_linear_disassembly_lines(pos, self.settings) + if len(lines) == 0: + break + for line in lines: + yield line + + return iter(LinearDisassemblyIterator(self, settings)) + + def parse_type_string(self, text): + result = core.BNNameAndType() + errors = ctypes.c_char_p() + if not core.BNParseTypeString(self.handle, text, result, errors): + error_str = errors.value + core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) + raise SyntaxError, error_str + type_obj = Type(core.BNNewTypeReference(result.type)) + name = result.name + core.BNFreeNameAndType(result) + return type_obj, name + def __setattr__(self, name, value): try: object.__setattr__(self,name,value) @@ -2308,10 +2535,14 @@ class Function(object): core.BNGetFunctionLiftedIL(self.handle)), self) @property - def type(self): - """Function type (read-only)""" + def function_type(self): + """Function type""" return Type(core.BNGetFunctionType(self.handle)) + @function_type.setter + def function_type(self, value): + self.set_user_type(value) + @property def stack_layout(self): """List of function stack (read-only)""" @@ -2568,6 +2799,12 @@ class Function(object): core.BNFreeInstructionTextLines(lines, count.value) return result + def set_auto_type(self, value): + core.BNSetFunctionAutoType(self.handle, value.handle) + + def set_user_type(self, value): + core.BNSetFunctionUserType(self.handle, value.handle) + class BasicBlockEdge: def __init__(self, branch_type, target, arch): self.type = core.BNBranchType_names[branch_type] @@ -3135,6 +3372,8 @@ class Architecture(object): endianness = core.LittleEndian address_size = 8 default_int_size = 4 + max_instr_length = 16 + opcode_display_length = 8 regs = {} stack_pointer = None link_reg = None @@ -3152,6 +3391,8 @@ class Architecture(object): self.__dict__["endianness"] = core.BNEndianness_names[core.BNGetArchitectureEndianness(self.handle)] self.__dict__["address_size"] = core.BNGetArchitectureAddressSize(self.handle) self.__dict__["default_int_size"] = core.BNGetArchitectureDefaultIntegerSize(self.handle) + self.__dict__["max_instr_length"] = core.BNGetArchitectureMaxInstructionLength(self.handle) + self.__dict__["opcode_display_length"] = core.BNGetArchitectureOpcodeDisplayLength(self.handle) self.__dict__["stack_pointer"] = core.BNGetArchitectureRegisterName(self.handle, core.BNGetArchitectureStackPointerRegister(self.handle)) self.__dict__["link_reg"] = core.BNGetArchitectureRegisterName(self.handle, @@ -3229,12 +3470,18 @@ class Architecture(object): self.__dict__["flags_written_by_flag_write_type"][write_type] = flag_names else: _init_plugins() + + if self.__class__.opcode_display_length > self.__class__.max_instr_length: + self.__class__.opcode_display_length = self.__class__.max_instr_length + self._cb = core.BNCustomArchitecture() self._cb.context = 0 self._cb.init = self._cb.init.__class__(self._init) self._cb.getEndianness = self._cb.getEndianness.__class__(self._get_endianness) self._cb.getAddressSize = self._cb.getAddressSize.__class__(self._get_address_size) self._cb.getDefaultIntegerSize = self._cb.getDefaultIntegerSize.__class__(self._get_default_integer_size) + self._cb.getMaxInstructionLength = self._cb.getMaxInstructionLength.__class__(self._get_max_instruction_length) + self._cb.getOpcodeDisplayLength = self._cb.getOpcodeDisplayLength.__class__(self._get_opcode_display_length) self._cb.getInstructionInfo = self._cb.getInstructionInfo.__class__(self._get_instruction_info) self._cb.getInstructionText = self._cb.getInstructionText.__class__(self._get_instruction_text) self._cb.freeInstructionText = self._cb.freeInstructionText.__class__(self._free_instruction_text) @@ -3410,6 +3657,20 @@ class Architecture(object): log_error(traceback.format_exc()) return 4 + def _get_max_instruction_length(self, ctxt): + try: + return self.__class__.max_instr_length + except: + log_error(traceback.format_exc()) + return 16 + + def _get_opcode_display_length(self, ctxt): + try: + return self.__class__.opcode_display_length + except: + log_error(traceback.format_exc()) + return 8 + def _get_instruction_info(self, ctxt, data, addr, max_len, result): try: buf = ctypes.create_string_buffer(max_len) diff --git a/python/examples/nes.py b/python/examples/nes.py index 21b02dfa..5cb6bc0d 100644 --- a/python/examples/nes.py +++ b/python/examples/nes.py @@ -349,6 +349,7 @@ class M6502(Architecture): name = "6502" address_size = 2 default_int_size = 1 + max_instr_length = 3 regs = { "a": RegisterInfo("a", 1), "x": RegisterInfo("x", 1), |
