diff options
| -rw-r--r-- | architecture.cpp | 16 | ||||
| -rw-r--r-- | binaryninjaapi.h | 132 | ||||
| -rw-r--r-- | binaryninjacore.h | 167 | ||||
| -rw-r--r-- | binaryview.cpp | 370 | ||||
| -rw-r--r-- | callingconvention.cpp | 2 | ||||
| -rw-r--r-- | python/binaryview.py | 134 | ||||
| -rw-r--r-- | relocationhandler.cpp | 114 |
7 files changed, 748 insertions, 187 deletions
diff --git a/architecture.cpp b/architecture.cpp index 682cffbc..d7ab348b 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -20,6 +20,7 @@ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> +#include <cstdint> #include <inttypes.h> #include "binaryninjaapi.h" @@ -140,8 +141,8 @@ BNArchitecture* Architecture::GetAssociatedArchitectureByAddressCallback(void* c } -bool Architecture::GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, - size_t maxLen, BNInstructionInfo* result) +bool Architecture::GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, + BNInstructionInfo* result) { Architecture* arch = (Architecture*)ctxt; @@ -1120,6 +1121,17 @@ void Architecture::RegisterFunctionRecognizer(FunctionRecognizer* recog) } +void Architecture::RegisterRelocationHandler(const string& viewName, RelocationHandler* handler) +{ + BNArchitectureRegisterRelocationHandler(m_object, viewName.c_str(), handler->GetObject()); +} + + +Ref<RelocationHandler> Architecture::GetRelocationHandler(const std::string& viewName) +{ + return new CoreRelocationHandler(BNArchitectureGetRelocationHandler(m_object, viewName.c_str())); +} + bool Architecture::IsBinaryViewTypeConstantDefined(const string& type, const string& name) { return BNIsBinaryViewTypeArchitectureConstantDefined(m_object, type.c_str(), name.c_str()); diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 7a13118f..b753455b 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -19,7 +19,6 @@ // IN THE SOFTWARE. #pragma once - #ifdef WIN32 #define NOMINMAX #include <windows.h> @@ -34,6 +33,7 @@ #include <set> #include <mutex> #include <memory> +#include <cstdint> #include "binaryninjacore.h" #include "json/json.h" @@ -853,7 +853,6 @@ namespace BinaryNinja BinaryNinja::Ref<BinaryNinja::BinaryView> GetViewOfType(const std::string& name); }; - class BinaryView; class Function; struct DataVariable; @@ -935,12 +934,10 @@ namespace BinaryNinja class Function; class BasicBlock; - class Symbol: public CoreRefCountObject<BNSymbol, BNNewSymbolReference, BNFreeSymbol> { public: - Symbol(BNSymbolType type, const std::string& shortName, const std::string& fullName, - const std::string& rawName, uint64_t addr); + Symbol(BNSymbolType type, const std::string& shortName, const std::string& fullName, const std::string& rawName, uint64_t addr); Symbol(BNSymbolType type, const std::string& name, uint64_t addr); Symbol(BNSymbol* sym); @@ -1032,28 +1029,50 @@ namespace BinaryNinja bool autoDiscovered; }; - struct Segment + class Segment: public CoreRefCountObject<BNSegment, BNNewSegmentReference, BNFreeSegment> { - uint64_t start, length; - uint64_t dataOffset, dataLength; - uint32_t flags; - bool autoDefined; + public: + Segment(BNSegment* seg); + uint64_t GetStart() const; + uint64_t GetLength() const; + uint64_t GetEnd() const; + uint64_t GetDataEnd() const; + uint64_t GetDataOffset() const; + uint64_t GetDataLength() const; + uint32_t GetFlags() const; + bool IsAutoDefined() const; + + void SetStart(uint64_t newSegmentBase); + void SetLength(uint64_t length); + void SetDataOffset(uint64_t dataOffset); + void SetDataLength(uint64_t dataLength); + void SetFlags(uint64_t flags); + + size_t Read(BinaryView* view, uint8_t* dest, uint64_t offset, size_t len); }; - struct Section + class Section: public CoreRefCountObject<BNSection, BNNewSectionReference, BNFreeSection> { - std::string name, type; - uint64_t start, length; - std::string linkedSection, infoSection; - uint64_t infoData; - uint64_t align, entrySize; - BNSectionSemantics semantics; - bool autoDefined; + public: + Section(BNSection* sec); + Section(const std::string& name, uint64_t start, uint64_t length, BNSectionSemantics semantics, + const std::string& type, uint64_t align, uint64_t entrySize, const std::string& linkedSection, + const std::string& infoSection, uint64_t infoData, bool autoDefined); + std::string GetName() const; + std::string GetType() const; + uint64_t GetStart() const; + uint64_t GetLength() const; + uint64_t GetInfoData() const; + uint64_t GetAlignment() const; + uint64_t GetEntrySize() const; + std::string GetLinkedSection() const; + std::string GetInfoSection() const; + BNSectionSemantics GetSemantics() const; + bool AutoDefined() const; }; struct QualifiedNameAndType; class Metadata; - class QueryMetadataException: public std::exception { const std::string m_error; @@ -1104,7 +1123,10 @@ namespace BinaryNinja virtual size_t PerformGetAddressSize() const; virtual bool PerformSave(FileAccessor* file); - + void PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Symbol> sym, uint64_t symOffset, + const Ref<Segment> seg, uint64_t segOffset); + void PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Section> sec, uint64_t secOffset, + const Ref<Segment> seg, uint64_t segOffset); void NotifyDataWritten(uint64_t offset, size_t len); void NotifyDataInserted(uint64_t offset, size_t len); void NotifyDataRemoved(uint64_t offset, uint64_t len); @@ -1131,7 +1153,10 @@ namespace BinaryNinja static bool IsRelocatableCallback(void* ctxt); static size_t GetAddressSizeCallback(void* ctxt); static bool SaveCallback(void* ctxt, BNFileAccessor* file); - + static void DefineRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSymbol* sym, + uint64_t symOffset, BNSegment* seg, uint64_t segOffset); + static void DefineSectionRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSection* sec, + uint64_t secOffset, BNSegment* seg, uint64_t segOffset); public: BinaryView(BNBinaryView* view); @@ -1182,6 +1207,7 @@ namespace BinaryNinja bool IsOffsetBackedByFile(uint64_t offset) const; bool IsOffsetCodeSemantics(uint64_t offset) const; bool IsOffsetWritableSemantics(uint64_t offset) const; + bool IsOffsetExternSemantics(uint64_t offset) const; uint64_t GetNextValidOffset(uint64_t offset) const; uint64_t GetStart() const; @@ -1203,6 +1229,10 @@ namespace BinaryNinja bool Save(FileAccessor* file); bool Save(const std::string& path); + void DefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Symbol> sym, uint64_t symOffset, + const Ref<Segment> seg, uint64_t segOffset); + void DefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Section> sec, uint64_t secOffset, + const Ref<Segment> seg, uint64_t segOffset); void RegisterNotification(BinaryDataNotification* notify); void UnregisterNotification(BinaryDataNotification* notify); @@ -1321,8 +1351,8 @@ namespace BinaryNinja void RemoveAutoSegment(uint64_t start, uint64_t length); void AddUserSegment(uint64_t start, uint64_t length, uint64_t dataOffset, uint64_t dataLength, uint32_t flags); void RemoveUserSegment(uint64_t start, uint64_t length); - std::vector<Segment> GetSegments(); - bool GetSegmentAt(uint64_t addr, Segment& result); + std::vector<Ref<Segment>> GetSegments(); + Ref<Segment> GetSegmentAt(uint64_t addr); bool GetAddressForDataOffset(uint64_t offset, uint64_t& addr); void AddAutoSection(const std::string& name, uint64_t start, uint64_t length, @@ -1335,9 +1365,9 @@ namespace BinaryNinja uint64_t align = 1, uint64_t entrySize = 0, const std::string& linkedSection = "", const std::string& infoSection = "", uint64_t infoData = 0); void RemoveUserSection(const std::string& name); - std::vector<Section> GetSections(); - std::vector<Section> GetSectionsAt(uint64_t addr); - bool GetSectionByName(const std::string& name, Section& result); + std::vector<Ref<Section>> GetSections(); + std::vector<Ref<Section>> GetSectionsAt(uint64_t addr); + Ref<Section> GetSectionByName(const std::string& name); std::vector<std::string> GetUniqueSectionNames(const std::vector<std::string>& names); @@ -1354,6 +1384,22 @@ namespace BinaryNinja void SetMaxFunctionSizeForAnalysis(uint64_t size); }; + + class Relocation: public CoreRefCountObject<BNRelocation, BNNewRelocationReference, BNFreeRelocation> + { + public: + Relocation(BNRelocation* reloc); + BNRelocationInfo GetInfo() const; + Architecture* GetArchitecture() const; + Ref<Symbol> GetSymbol(); + uint64_t GetSymbolOffset() const; + uint64_t GetTargetAddress() const; + Ref<Segment> GetSegment(); + uint64_t GetSegmentOffset() const; + uint64_t GetDestAddress() const; + }; + + class BinaryData: public BinaryView { public: @@ -1594,6 +1640,7 @@ namespace BinaryNinja class MediumLevelILFunction; class FunctionRecognizer; class CallingConvention; + class RelocationHandler; typedef size_t ExprId; @@ -1824,6 +1871,8 @@ namespace BinaryNinja virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value); void RegisterFunctionRecognizer(FunctionRecognizer* recog); + void RegisterRelocationHandler(const std::string& viewName, RelocationHandler* handler); + Ref<RelocationHandler> GetRelocationHandler(const std::string& viewName); bool IsBinaryViewTypeConstantDefined(const std::string& type, const std::string& name); uint64_t GetBinaryViewTypeConstant(const std::string& type, const std::string& name, @@ -1865,6 +1914,7 @@ namespace BinaryNinja virtual std::string GetRegisterName(uint32_t reg) override; virtual std::string GetFlagName(uint32_t flag) override; virtual std::string GetFlagWriteTypeName(uint32_t flags) override; + virtual std::string GetSemanticFlagClassName(uint32_t semClass) override; virtual std::string GetSemanticFlagGroupName(uint32_t semGroup) override; virtual std::vector<uint32_t> GetFullWidthRegisters() override; @@ -3300,6 +3350,36 @@ namespace BinaryNinja virtual bool RecognizeMediumLevelIL(BinaryView* data, Function* func, MediumLevelILFunction* il); }; + class RelocationHandler: public CoreRefCountObject<BNRelocationHandler, + BNNewRelocationHandlerReference, BNFreeRelocationHandler> + { + static bool GetRelocationInfoCallback(void* ctxt, BNBinaryView* view, BNArchitecture* arch, + BNRelocationInfo* result, size_t resultCount); + static bool ApplyRelocationCallback(void* ctxt, BNBinaryView* view, BNArchitecture* arch, BNRelocation* reloc, + uint8_t* dest, size_t len); + + protected: + RelocationHandler(); + RelocationHandler(BNRelocationHandler* handler); + static void FreeCallback(void* ctxt); + + public: + + virtual bool GetRelocationInfo(Ref<BinaryView> view, Ref<Architecture> arch, std::vector<BNRelocationInfo>& result); + virtual bool ApplyRelocation(Ref<BinaryView> view, Ref<Architecture> arch, Ref<Relocation> reloc, uint8_t* dest, + size_t len); + }; + + class CoreRelocationHandler: public RelocationHandler + { + public: + CoreRelocationHandler(BNRelocationHandler* handler); + + virtual bool GetRelocationInfo(Ref<BinaryView> view, Ref<Architecture> arch, std::vector<BNRelocationInfo>& result) override; + virtual bool ApplyRelocation(Ref<BinaryView> view, Ref<Architecture> arch, Ref<Relocation> reloc, uint8_t* dest, + size_t len) override; + }; + class UpdateException: public std::exception { const std::string m_desc; diff --git a/binaryninjacore.h b/binaryninjacore.h index e4d3a919..202684a8 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -142,6 +142,11 @@ extern "C" struct BNRepoPlugin; struct BNRepositoryManager; struct BNMetadata; + struct BNRelocation; + struct BNSegment; + struct BNSection; + struct BNRelocationInfo; + struct BNRelocationHandler; typedef bool (*BNLoadPluginCallback)(const char* repoPath, const char* pluginPath, void* ctx); @@ -264,7 +269,17 @@ extern "C" ImportAddressSymbol = 1, ImportedFunctionSymbol = 2, DataSymbol = 3, - ImportedDataSymbol = 4 + ImportedDataSymbol = 4, + ExternalSymbol = 5, + LabelSymbol = 6 + }; + + enum BNSymbolBinding + { + NoBinding, + LocalBinding, + GlobalBinding, + WeakBinding }; enum BNActionType @@ -1037,6 +1052,10 @@ extern "C" bool (*isRelocatable)(void* ctxt); size_t (*getAddressSize)(void* ctxt); bool (*save)(void* ctxt, BNFileAccessor* accessor); + void (*defineRelocation) (void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSymbol* sym, + uint64_t symOffset, BNSegment* seg, uint64_t segOffset); + void (*defineSectionRelocation) (void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSection* sec, + uint64_t secOffset, BNSegment* seg, uint64_t segOffset); }; struct BNCustomBinaryViewType @@ -1079,6 +1098,32 @@ extern "C" BNArchitecture* branchArch[BN_MAX_INSTRUCTION_BRANCHES]; // If null, same architecture as instruction }; + enum BNRelocationType + { + ELFGlobalRelocationType, + ELFCopyRelocationType, + ELFJumpSlotRelocationType, + StandardRelocationType, + IgnoredRelocation + }; + + struct BNRelocationInfo + { + BNRelocationType type; // BinaryNinja Relocation Type + bool pcRelative; // PC Relative or Absolute (subtract address from relocation) + bool baseRelative; // Relative to start of module (Add module base to relocation) + size_t size; // Size of the data to be written + size_t truncateSize; // After addition/subtraction truncate to + uint64_t nativeType; // Base type from relocation entry + size_t addend; // Addend value from relocation entry + bool hasSign; // Addend should be subtracted + bool implicitAddend; // Addend should be read from the BinaryView + bool external; // Relocation entry points to external symbol + size_t symbolIndex; // Index into symbol table + size_t sectionIndex; // Index into the section table + uint64_t address; // Absolute address or segment offset + }; + struct BNInstructionTextToken { BNInstructionTextTokenType type; @@ -1330,6 +1375,17 @@ extern "C" bool (*recognizeMediumLevelIL)(void* ctxt, BNBinaryView* data, BNFunction* func, BNMediumLevelILFunction* il); }; + struct BNCustomRelocationHandler + { + void* context; + void (*freeObject)(void* ctxt); + + bool (*getRelocationInfo)(void* ctxt, BNBinaryView* view, BNArchitecture* arch, BNRelocationInfo* result, + size_t resultCount); + bool (*applyRelocation)(void* ctxt, BNBinaryView* view, BNArchitecture* arch, BNRelocation* reloc, uint8_t* dest, + size_t len); + }; + struct BNTypeParserResult { BNQualifiedNameAndType* types; @@ -1678,33 +1734,13 @@ extern "C" SegmentDenyExecute = 0x40 }; - struct BNSegment - { - uint64_t start, length; - uint64_t dataOffset, dataLength; - uint32_t flags; - bool autoDefined; - }; - enum BNSectionSemantics { DefaultSectionSemantics, ReadOnlyCodeSectionSemantics, ReadOnlyDataSectionSemantics, - ReadWriteDataSectionSemantics - }; - - struct BNSection - { - char* name; - char* type; - uint64_t start, length; - char* linkedSection; - char* infoSection; - uint64_t infoData; - uint64_t align, entrySize; - BNSectionSemantics semantics; - bool autoDefined; + ReadWriteDataSectionSemantics, + ExternalCodeSectionSemantics }; struct BNAddressRange @@ -1937,6 +1973,7 @@ extern "C" BINARYNINJACOREAPI bool BNIsOffsetExecutable(BNBinaryView* view, uint64_t offset); BINARYNINJACOREAPI bool BNIsOffsetBackedByFile(BNBinaryView* view, uint64_t offset); BINARYNINJACOREAPI bool BNIsOffsetCodeSemantics(BNBinaryView* view, uint64_t offset); + BINARYNINJACOREAPI bool BNIsOffsetExternSemantics(BNBinaryView* view, uint64_t offset); BINARYNINJACOREAPI bool BNIsOffsetWritableSemantics(BNBinaryView* view, uint64_t offset); BINARYNINJACOREAPI uint64_t BNGetNextValidOffset(BNBinaryView* view, uint64_t offset); BINARYNINJACOREAPI uint64_t BNGetStartOffset(BNBinaryView* view); @@ -1957,7 +1994,10 @@ extern "C" BINARYNINJACOREAPI bool BNSaveToFile(BNBinaryView* view, BNFileAccessor* file); BINARYNINJACOREAPI bool BNSaveToFilename(BNBinaryView* view, const char* filename); - + BINARYNINJACOREAPI void BNDefineRelocation(BNBinaryView* view, BNArchitecture* arch, BNRelocationInfo* info, + BNSymbol* sym, uint64_t symOffset, BNSegment* seg, uint64_t segOffset); + BINARYNINJACOREAPI void BNDefineSectionRelocation(BNBinaryView* view, BNArchitecture* arch, BNRelocationInfo* info, + BNSection* sec, uint64_t secOffset, BNSegment* seg, uint64_t segOffset); BINARYNINJACOREAPI void BNRegisterDataNotification(BNBinaryView* view, BNBinaryDataNotification* notify); BINARYNINJACOREAPI void BNUnregisterDataNotification(BNBinaryView* view, BNBinaryDataNotification* notify); @@ -1983,9 +2023,9 @@ extern "C" BINARYNINJACOREAPI void BNAddUserSegment(BNBinaryView* view, uint64_t start, uint64_t length, uint64_t dataOffset, uint64_t dataLength, uint32_t flags); BINARYNINJACOREAPI void BNRemoveUserSegment(BNBinaryView* view, uint64_t start, uint64_t length); - BINARYNINJACOREAPI BNSegment* BNGetSegments(BNBinaryView* view, size_t* count); - BINARYNINJACOREAPI void BNFreeSegmentList(BNSegment* segments); - BINARYNINJACOREAPI bool BNGetSegmentAt(BNBinaryView* view, uint64_t addr, BNSegment* result); + BINARYNINJACOREAPI BNSegment** BNGetSegments(BNBinaryView* view, size_t* count); + BINARYNINJACOREAPI void BNFreeSegmentList(BNSegment** segments, size_t count); + BINARYNINJACOREAPI BNSegment* BNGetSegmentAt(BNBinaryView* view, uint64_t addr); BINARYNINJACOREAPI bool BNGetAddressForDataOffset(BNBinaryView* view, uint64_t offset, uint64_t* addr); BINARYNINJACOREAPI void BNAddAutoSection(BNBinaryView* view, const char* name, uint64_t start, uint64_t length, @@ -1996,11 +2036,10 @@ extern "C" BNSectionSemantics semantics, const char* type, uint64_t align, uint64_t entrySize, const char* linkedSection, const char* infoSection, uint64_t infoData); BINARYNINJACOREAPI void BNRemoveUserSection(BNBinaryView* view, const char* name); - BINARYNINJACOREAPI BNSection* BNGetSections(BNBinaryView* view, size_t* count); - BINARYNINJACOREAPI BNSection* BNGetSectionsAt(BNBinaryView* view, uint64_t addr, size_t* count); - BINARYNINJACOREAPI void BNFreeSectionList(BNSection* sections, size_t count); - BINARYNINJACOREAPI bool BNGetSectionByName(BNBinaryView* view, const char* name, BNSection* result); - BINARYNINJACOREAPI void BNFreeSection(BNSection* section); + BINARYNINJACOREAPI BNSection** BNGetSections(BNBinaryView* view, size_t* count); + BINARYNINJACOREAPI BNSection** BNGetSectionsAt(BNBinaryView* view, uint64_t addr, size_t* count); + BINARYNINJACOREAPI void BNFreeSectionList(BNSection** sections, size_t count); + BINARYNINJACOREAPI BNSection* BNGetSectionByName(BNBinaryView* view, const char* name); BINARYNINJACOREAPI char** BNGetUniqueSectionNames(BNBinaryView* view, const char** names, size_t count); @@ -2020,7 +2059,6 @@ extern "C" BINARYNINJACOREAPI BNBinaryView* BNCreateCustomBinaryView(const char* name, BNFileMetadata* file, BNBinaryView* parent, BNCustomBinaryView* view); - // Binary view type management BINARYNINJACOREAPI BNBinaryViewType* BNGetBinaryViewTypeByName(const char* name); BINARYNINJACOREAPI BNBinaryViewType** BNGetBinaryViewTypes(size_t* count); BINARYNINJACOREAPI BNBinaryViewType** BNGetBinaryViewTypesForData(BNBinaryView* data, size_t* count); @@ -2126,7 +2164,7 @@ extern "C" BINARYNINJACOREAPI size_t BNGetArchitectureOpcodeDisplayLength(BNArchitecture* arch); BINARYNINJACOREAPI BNArchitecture* BNGetAssociatedArchitectureByAddress(BNArchitecture* arch, uint64_t* addr); BINARYNINJACOREAPI bool BNGetInstructionInfo(BNArchitecture* arch, const uint8_t* data, uint64_t addr, - size_t maxLen, BNInstructionInfo* result); + size_t maxLen, BNInstructionInfo* result); BINARYNINJACOREAPI bool BNGetInstructionText(BNArchitecture* arch, const uint8_t* data, uint64_t addr, size_t* len, BNInstructionTextToken** result, size_t* count); BINARYNINJACOREAPI bool BNGetInstructionLowLevelIL(BNArchitecture* arch, const uint8_t* data, uint64_t addr, @@ -2205,9 +2243,7 @@ extern "C" BINARYNINJACOREAPI bool BNArchitectureInvertBranch(BNArchitecture* arch, uint8_t* data, uint64_t addr, size_t len); BINARYNINJACOREAPI bool BNArchitectureSkipAndReturnValue(BNArchitecture* arch, uint8_t* data, uint64_t addr, size_t len, uint64_t value); - BINARYNINJACOREAPI void BNRegisterArchitectureFunctionRecognizer(BNArchitecture* arch, BNFunctionRecognizer* rec); - BINARYNINJACOREAPI bool BNIsBinaryViewTypeArchitectureConstantDefined(BNArchitecture* arch, const char* type, const char* name); BINARYNINJACOREAPI uint64_t BNGetBinaryViewTypeArchitectureConstant(BNArchitecture* arch, const char* type, @@ -2215,6 +2251,18 @@ extern "C" BINARYNINJACOREAPI void BNSetBinaryViewTypeArchitectureConstant(BNArchitecture* arch, const char* type, const char* name, uint64_t value); + BINARYNINJACOREAPI void BNArchitectureRegisterRelocationHandler(BNArchitecture* arch, const char* viewName, + BNRelocationHandler* handler); + BINARYNINJACOREAPI BNRelocationHandler* BNCreateRelocationHandler(BNCustomRelocationHandler* handler); + BINARYNINJACOREAPI BNRelocationHandler* BNArchitectureGetRelocationHandler(BNArchitecture* arch, const char* viewName); + BINARYNINJACOREAPI BNRelocationHandler* BNNewRelocationHandlerReference(BNRelocationHandler* handler); + BINARYNINJACOREAPI void BNFreeRelocationHandler(BNRelocationHandler* handler); + BINARYNINJACOREAPI bool BNRelocationHandlerGetRelocationInfo(BNRelocationHandler* handler, BNBinaryView* data, + BNArchitecture* arch, BNRelocationInfo* info, size_t infoCount); + BINARYNINJACOREAPI bool BNRelocationHandlerApplyRelocation(BNRelocationHandler* handler, BNBinaryView* view, + BNArchitecture* arch, BNRelocation* reloc, uint8_t* dest, size_t len); + BINARYNINJACOREAPI bool BNRelocationHandlerDefaultApplyRelocation(BNRelocationHandler* handler, BNBinaryView* view, + BNArchitecture* arch, BNRelocation* reloc, uint8_t* dest, size_t len); // Analysis BINARYNINJACOREAPI void BNAddAnalysisOption(BNBinaryView* view, const char* name); BINARYNINJACOREAPI void BNAddFunctionForAnalysis(BNBinaryView* view, BNPlatform* platform, uint64_t addr); @@ -3462,6 +3510,53 @@ extern "C" BINARYNINJACOREAPI char* BNGetLinuxCADirectory(); BINARYNINJACOREAPI char* BNGetLinuxCABundlePath(); + + // Relocation object methods + BINARYNINJACOREAPI BNRelocation* BNNewRelocationReference(BNRelocation* reloc); + BINARYNINJACOREAPI void BNFreeRelocation(BNRelocation* reloc); + BINARYNINJACOREAPI BNRelocationInfo BNRelocationGetInfo(BNRelocation* reloc); + BINARYNINJACOREAPI BNArchitecture* BNRelocationGetArchitecture(BNRelocation* reloc); + BINARYNINJACOREAPI BNSymbol* BNRelocationGetSymbol(BNRelocation* reloc); + BINARYNINJACOREAPI uint64_t BNRelocationGetSymbolOffset(BNRelocation* reloc); + BINARYNINJACOREAPI uint64_t BNRelocationGetTargetAddress(BNRelocation* reloc); + BINARYNINJACOREAPI BNSegment* BNRelocationGetSegment(BNRelocation* reloc); + BINARYNINJACOREAPI uint64_t BNRelocationGetSegmentOffset(BNRelocation* reloc); + BINARYNINJACOREAPI uint64_t BNRelocationGetDestAddress(BNRelocation* reloc); + + // Segment object methods + BINARYNINJACOREAPI BNSegment* BNCreateSegment(uint64_t start, uint64_t length, uint64_t dataOffset, uint64_t dataLength, uint32_t flags, + bool autoDefined); + BINARYNINJACOREAPI BNSegment* BNNewSegmentReference(BNSegment* seg); + BINARYNINJACOREAPI void BNFreeSegment(BNSegment* seg); + BINARYNINJACOREAPI uint64_t BNSegmentGetStart(BNSegment* segment); + BINARYNINJACOREAPI uint64_t BNSegmentGetLength(BNSegment* segment); + BINARYNINJACOREAPI uint64_t BNSegmentGetEnd(BNSegment* segment); + BINARYNINJACOREAPI uint64_t BNSegmentGetDataEnd(BNSegment* segment); + BINARYNINJACOREAPI uint64_t BNSegmentGetDataOffset(BNSegment* segment); + BINARYNINJACOREAPI uint64_t BNSegmentGetDataLength(BNSegment* segment); + BINARYNINJACOREAPI uint32_t BNSegmentGetFlags(BNSegment* segment); + BINARYNINJACOREAPI bool BNSegmentIsAutoDefined(BNSegment* segment); + BINARYNINJACOREAPI void BNSegmentSetLength(BNSegment* segment, uint64_t length); + BINARYNINJACOREAPI void BNSegmentSetDataOffset(BNSegment* segment, uint64_t dataOffset); + BINARYNINJACOREAPI void BNSegmentSetDataLength(BNSegment* segment, uint64_t dataLength); + BINARYNINJACOREAPI void BNSegmentSetFlags(BNSegment* segment, uint32_t flags); + BINARYNINJACOREAPI size_t BNSegmentRead(BNSegment* segment, BNBinaryView* view, uint8_t* dest, uint64_t offset, size_t len); + + // Section object methods + BINARYNINJACOREAPI BNSection* BNNewSectionReference(BNSection* section); + BINARYNINJACOREAPI void BNFreeSection(BNSection* section); + BINARYNINJACOREAPI char* BNSectionGetName(BNSection* section); + BINARYNINJACOREAPI char* BNSectionGetType(BNSection* section); + BINARYNINJACOREAPI uint64_t BNSectionGetStart(BNSection* section); + BINARYNINJACOREAPI uint64_t BNSectionGetLength(BNSection* section); + BINARYNINJACOREAPI uint64_t BNSectionGetEnd(BNSection* section); + BINARYNINJACOREAPI char* BNSectionGetLinkedSection(BNSection* section); + BINARYNINJACOREAPI char* BNSectionGetInfoSection(BNSection* section); + BINARYNINJACOREAPI uint64_t BNSectionGetInfoData(BNSection* section); + BINARYNINJACOREAPI uint64_t BNSectionGetAlign(BNSection* section); + BINARYNINJACOREAPI uint64_t BNSectionGetEntrySize(BNSection* section); + BINARYNINJACOREAPI BNSectionSemantics BNSectionGetSemantics(BNSection* section); + BINARYNINJACOREAPI bool BNSectionIsAutoDefined(BNSection* section); #ifdef __cplusplus } #endif diff --git a/binaryview.cpp b/binaryview.cpp index 0a9a7118..055608a4 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -267,6 +267,162 @@ void AnalysisCompletionEvent::Cancel() } +Segment::Segment(BNSegment* seg) +{ + m_object = seg; +} + + +uint64_t Segment::GetStart() const +{ + return BNSegmentGetStart(m_object); +} + + +uint64_t Segment::GetLength() const +{ + return BNSegmentGetLength(m_object); +} + + +uint64_t Segment::GetEnd() const +{ + return BNSegmentGetEnd(m_object); +} + + +uint64_t Segment::GetDataEnd() const +{ + return BNSegmentGetDataEnd(m_object); +} + + +uint64_t Segment::GetDataOffset() const +{ + return BNSegmentGetDataOffset(m_object); +} + + +uint64_t Segment::GetDataLength() const +{ + return BNSegmentGetDataLength(m_object); +} + + +uint32_t Segment::GetFlags() const +{ + return BNSegmentGetFlags(m_object); +} + + +bool Segment::IsAutoDefined() const +{ + return BNSegmentIsAutoDefined(m_object); +} + + +void Segment::SetLength(uint64_t length) +{ + BNSegmentSetLength(m_object, length); +} + + +void Segment::SetDataOffset(uint64_t dataOffset) +{ + BNSegmentSetDataOffset(m_object, dataOffset); +} + + +void Segment::SetDataLength(uint64_t dataLength) +{ + BNSegmentSetDataLength(m_object, dataLength); +} + + +void Segment::SetFlags(uint64_t flags) +{ + BNSegmentSetFlags(m_object, flags); +} + + +size_t Segment::Read(BinaryView* view, uint8_t* dest, uint64_t offset, size_t len) +{ + return BNSegmentRead(m_object, view->GetObject(), dest, offset, len); +} + + +Section::Section(BNSection* sec) +{ + m_object = sec; +} + + +std::string Section::GetName() const +{ + return BNSectionGetName(m_object); +} + + +std::string Section::GetType() const +{ + return BNSectionGetType(m_object); +} + + +uint64_t Section::GetStart() const +{ + return BNSectionGetStart(m_object); +} + + +uint64_t Section::GetLength() const +{ + return BNSectionGetLength(m_object); +} + + +uint64_t Section::GetInfoData() const +{ + return BNSectionGetInfoData(m_object); +} + + +uint64_t Section::GetAlignment() const +{ + return BNSectionGetAlign(m_object); +} + + +uint64_t Section::GetEntrySize() const +{ + return BNSectionGetEntrySize(m_object); +} + + +std::string Section::GetLinkedSection() const +{ + return BNSectionGetLinkedSection(m_object); +} + + +std::string Section::GetInfoSection() const +{ + return BNSectionGetInfoSection(m_object); +} + + +BNSectionSemantics Section::GetSemantics() const +{ + return BNSectionGetSemantics(m_object); +} + + +bool Section::AutoDefined() const +{ + return BNSectionIsAutoDefined(m_object); +} + + BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryView* parentView) { BNCustomBinaryView view; @@ -292,7 +448,8 @@ BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryVi view.isRelocatable = IsRelocatableCallback; view.getAddressSize = GetAddressSizeCallback; view.save = SaveCallback; - + view.defineRelocation = DefineRelocationCallback; + view.defineSectionRelocation = DefineSectionRelocationCallback; m_file = file; AddRefForRegistration(); m_object = BNCreateCustomBinaryView(typeName.c_str(), m_file->GetObject(), @@ -455,6 +612,30 @@ bool BinaryView::SaveCallback(void* ctxt, BNFileAccessor* file) } +void BinaryView::DefineRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSymbol* sym, + uint64_t symOffset, BNSegment* seg, uint64_t segOffset) +{ + BinaryView* view = (BinaryView*)ctxt; + BNRelocationInfo curInfo = *info; + Ref<Symbol> curSym = new Symbol(BNNewSymbolReference(sym)); + Ref<Segment> curSeg = new Segment(BNNewSegmentReference(seg)); + Architecture* curArch = new CoreArchitecture(arch); + return view->PerformDefineRelocation(curArch, curInfo, curSym, symOffset, curSeg, segOffset); +} + + +void BinaryView::DefineSectionRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSection* sec, + uint64_t secOffset, BNSegment* seg, uint64_t segOffset) +{ + BinaryView* view = (BinaryView*)ctxt; + BNRelocationInfo curInfo = *info; + Ref<Section> curSec = new Section(BNNewSectionReference(sec)); + Ref<Segment> curSeg = new Segment(BNNewSegmentReference(seg)); + Architecture* curArch = new CoreArchitecture(arch); + return view->PerformDefineRelocation(curArch, curInfo, curSec, secOffset, curSeg, segOffset); +} + + bool BinaryView::PerformIsValidOffset(uint64_t offset) { uint8_t val; @@ -528,6 +709,20 @@ bool BinaryView::PerformSave(FileAccessor* file) } +void BinaryView::PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Symbol> sym, + uint64_t symOffset, const Ref<Segment> seg, uint64_t segOffset) +{ + DefineRelocation(arch, info, sym, symOffset, seg, segOffset); +} + + +void BinaryView::PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Section> sec, + uint64_t secOffset, const Ref<Segment> seg, uint64_t segOffset) +{ + DefineRelocation(arch, info, sec, secOffset, seg, segOffset); +} + + void BinaryView::NotifyDataWritten(uint64_t offset, size_t len) { BNNotifyDataWritten(m_object, offset, len); @@ -707,6 +902,20 @@ bool BinaryView::Save(const string& path) } +void BinaryView::DefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Symbol> sym, + uint64_t symOffset, const Ref<Segment> seg, uint64_t segOffset) +{ + BNDefineRelocation(m_object, arch->GetObject(), &info, sym->GetObject(), symOffset, seg->GetObject(), segOffset); +} + + +void BinaryView::DefineRelocation(Architecture* arch, BNRelocationInfo& info, const Ref<Section> sec, + uint64_t secOffset, const Ref<Segment> seg, uint64_t segOffset) +{ + BNDefineSectionRelocation(m_object, arch->GetObject(), &info, sec->GetObject(), secOffset, seg->GetObject(), segOffset); +} + + void BinaryView::RegisterNotification(BinaryDataNotification* notify) { BNRegisterDataNotification(m_object, notify->GetCallbacks()); @@ -785,6 +994,12 @@ bool BinaryView::IsOffsetCodeSemantics(uint64_t offset) const } +bool BinaryView::IsOffsetExternSemantics(uint64_t offset) const +{ + return BNIsOffsetExternSemantics(m_object, offset); +} + + bool BinaryView::IsOffsetWritableSemantics(uint64_t offset) const { return BNIsOffsetWritableSemantics(m_object, offset); @@ -1742,41 +1957,28 @@ void BinaryView::RemoveUserSegment(uint64_t start, uint64_t length) } -vector<Segment> BinaryView::GetSegments() +vector<Ref<Segment>> BinaryView::GetSegments() { size_t count; - BNSegment* segments = BNGetSegments(m_object, &count); + BNSegment** segments = BNGetSegments(m_object, &count); - vector<Segment> result; + vector<Ref<Segment>> result; result.reserve(count); for (size_t i = 0; i < count; i++) - { - Segment segment; - segment.start = segments[i].start; - segment.length = segments[i].length; - segment.dataOffset = segments[i].dataOffset; - segment.dataLength = segments[i].dataLength; - segment.flags = segments[i].flags; - segment.autoDefined = segments[i].autoDefined; - result.push_back(segment); - } + result.push_back(new Segment(BNNewSegmentReference(segments[i]))); - BNFreeSegmentList(segments); + BNFreeSegmentList(segments, count); return result; } -bool BinaryView::GetSegmentAt(uint64_t addr, Segment& result) + +Ref<Segment> BinaryView::GetSegmentAt(uint64_t addr) { - BNSegment segment; - if (!BNGetSegmentAt(m_object, addr, &segment)) - return false; + BNSegment* segment = BNGetSegmentAt(m_object, addr); + if (!segment) + return nullptr; - result.start = segment.start; - result.length = segment.length; - result.dataOffset = segment.dataOffset; - result.dataLength = segment.dataLength; - result.flags = segment.flags; - return true; + return new Segment(BNNewSegmentReference(segment)); } @@ -1816,55 +2018,31 @@ void BinaryView::RemoveUserSection(const string& name) } -vector<Section> BinaryView::GetSections() +vector<Ref<Section>> BinaryView::GetSections() { size_t count; - BNSection* sections = BNGetSections(m_object, &count); + BNSection** sections = BNGetSections(m_object, &count); - vector<Section> result; - result.reserve(count); + vector<Ref<Section>> result; + result.reserve(count); for (size_t i = 0; i < count; i++) - { - Section section; - section.name = sections[i].name; - section.type = sections[i].type; - section.start = sections[i].start; - section.length = sections[i].length; - section.linkedSection = sections[i].linkedSection; - section.infoSection = sections[i].infoSection; - section.infoData = sections[i].infoData; - section.align = sections[i].align; - section.entrySize = sections[i].entrySize; - section.semantics = sections[i].semantics; - result.push_back(section); - } + result.push_back(new Section(BNNewSectionReference(sections[i]))); BNFreeSectionList(sections, count); return result; } -vector<Section> BinaryView::GetSectionsAt(uint64_t addr) +vector<Ref<Section>> BinaryView::GetSectionsAt(uint64_t addr) { size_t count; - BNSection* sections = BNGetSectionsAt(m_object, addr, &count); + BNSection** sections = BNGetSectionsAt(m_object, addr, &count); - vector<Section> result; - result.reserve(count); + vector<Ref<Section>> result; + result.reserve(count); for (size_t i = 0; i < count; i++) { - Section section; - section.name = sections[i].name; - section.type = sections[i].type; - section.start = sections[i].start; - section.length = sections[i].length; - section.linkedSection = sections[i].linkedSection; - section.infoSection = sections[i].infoSection; - section.infoData = sections[i].infoData; - section.align = sections[i].align; - section.entrySize = sections[i].entrySize; - section.semantics = sections[i].semantics; - result.push_back(section); + result.push_back(new Section(BNNewSectionReference(sections[i]))); } BNFreeSectionList(sections, count); @@ -1872,25 +2050,9 @@ vector<Section> BinaryView::GetSectionsAt(uint64_t addr) } -bool BinaryView::GetSectionByName(const string& name, Section& result) +Ref<Section> BinaryView::GetSectionByName(const string& name) { - BNSection section; - if (!BNGetSectionByName(m_object, name.c_str(), §ion)) - return false; - - result.name = section.name; - result.type = section.type; - result.start = section.start; - result.length = section.length; - result.linkedSection = section.linkedSection; - result.infoSection = section.infoSection; - result.infoData = section.infoData; - result.align = section.align; - result.entrySize = section.entrySize; - result.semantics = section.semantics; - - BNFreeSection(§ion); - return true; + return new Section(BNGetSectionByName(m_object, name.c_str())); } @@ -1980,6 +2142,60 @@ void BinaryView::SetMaxFunctionSizeForAnalysis(uint64_t size) } +Relocation::Relocation(BNRelocation* reloc) +{ + m_object = reloc; +} + + +BNRelocationInfo Relocation::GetInfo() const +{ + return BNRelocationGetInfo(m_object); +} + + +Architecture* Relocation::GetArchitecture() const +{ + return new CoreArchitecture(BNRelocationGetArchitecture(m_object)); +} + + +Ref<Symbol> Relocation::GetSymbol() +{ + return new Symbol(BNNewSymbolReference(BNRelocationGetSymbol(m_object))); +} + + +uint64_t Relocation::GetSymbolOffset() const +{ + return BNRelocationGetSymbolOffset(m_object); +} + + +uint64_t Relocation::GetTargetAddress() const +{ + return BNRelocationGetTargetAddress(m_object); +} + + +Ref<Segment> Relocation::GetSegment() +{ + return new Segment(BNNewSegmentReference(BNRelocationGetSegment(m_object))); +} + + +uint64_t Relocation::GetSegmentOffset() const +{ + return BNRelocationGetSegmentOffset(m_object); +} + + +uint64_t Relocation::GetDestAddress() const +{ + return BNRelocationGetDestAddress(m_object); +} + + BinaryData::BinaryData(FileMetadata* file): BinaryView(BNCreateBinaryDataView(file->GetObject())) { } diff --git a/callingconvention.cpp b/callingconvention.cpp index a56b8f11..3a7298a2 100644 --- a/callingconvention.cpp +++ b/callingconvention.cpp @@ -432,4 +432,4 @@ Variable CoreCallingConvention::GetIncomingVariableForParameterVariable(const Va Variable CoreCallingConvention::GetParameterVariableForIncomingVariable(const Variable& var, Function* func) { return BNGetParameterVariableForIncomingVariable(m_object, &var, func ? func->GetObject() : nullptr); -} +}
\ No newline at end of file diff --git a/python/binaryview.py b/python/binaryview.py index 0cf25e70..0b090a9a 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -427,32 +427,47 @@ class BinaryViewType(object): class Segment(object): - def __init__(self, start, length, data_offset, data_length, flags, auto_defined): - self.start = start - self.length = length - self.data_offset = data_offset - self.data_length = data_length - self.flags = flags - self.auto_defined = auto_defined + def __init__(self, handle): + self.handle = handle + + @property + def start(self): + return core.BNSegmentGetStart(self.handle) + + @property + def end(self): + return core.BNSegmentGetEnd(self.handle) @property def executable(self): - return (self.flags & SegmentFlag.SegmentExecutable) != 0 + return (core.BNSegmentGetFlags(self.handle) & SegmentFlag.SegmentExecutable) != 0 @property def writable(self): - return (self.flags & SegmentFlag.SegmentWritable) != 0 + return (core.BNSegmentGetFlags(self.handle) & SegmentFlag.SegmentWritable) != 0 @property def readable(self): - return (self.flags & SegmentFlag.SegmentReadable) != 0 + return (core.BNSegmentGetFlags(self.handle) & SegmentFlag.SegmentReadable) != 0 @property def end(self): - return self.start + self.length + return core.BNSegmentGetEnd(self.handle) + + @property + def data_length(self): + return core.BNSegmentGetDataLength(self.handle) + + @property + def data_offset(self): + return core.BNSegmentGetDataOffset(self.handle) + + @property + def data_end(self): + return core.BNSegmentGetDataEnd(self.handle) def __len__(self): - return self.length + return core.BNSegmentGetLength(self.handle) def __repr__(self): return "<segment: %#x-%#x, %s%s%s>" % (self.start, self.end, @@ -462,25 +477,55 @@ class Segment(object): class Section(object): - def __init__(self, name, section_type, start, length, linked_section, info_section, info_data, align, entry_size, semantics, auto_defined): - self.name = name - self.type = section_type - self.start = start - self.length = length - self.linked_section = linked_section - self.info_section = info_section - self.info_data = info_data - self.align = align - self.entry_size = entry_size - self.semantics = SectionSemantics(semantics) - self.auto_defined = auto_defined + def __init__(self, handle): + self.handle = core.handle_of_type(handle, core.BNSection) + + @property + def name(self): + return core.BNSectionGetName(self.handle) + + @property + def type(self): + return core.BNSectionGetType(self.handle) + + @property + def start(self): + return core.BNSectionGetStart(self.handle) + + @property + def linked_section(self): + return core.BNSectionLinkedSection(self.handle) + + @property + def info_section(self): + return core.BNSectionInfoSection(self.handle) + + @property + def info_data(self): + return core.BNSectionInfoData(self.handle) + + @property + def align(self): + return core.BNSectionAlign(self.handle) + + @property + def entry_size(self): + return core.BNSectionEntrySize(self.handle) + + @property + def semantics(self): + return SectionSemantics(core.BNSectionSemantics(self.handle)) + + @property + def auto_defined(self): + return core.BNSectionAutoDefined(self.handle) @property def end(self): - return self.start + self.length + return self.start + len(self) def __len__(self): - return self.length + return core.BNSectionGetLength(self.handle) def __repr__(self): return "<section %s: %#x-%#x>" % (self.name, self.start, self.end) @@ -977,9 +1022,8 @@ class BinaryView(object): segment_list = core.BNGetSegments(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(Segment(segment_list[i].start, segment_list[i].length, - segment_list[i].dataOffset, segment_list[i].dataLength, segment_list[i].flags, segment_list[i].autoDefined)) - core.BNFreeSegmentList(segment_list) + result.append(Segment(core.BNNewSegmentReference(segment_list[i]))) + core.BNFreeSegmentList(segment_list, count.value) return result @property @@ -989,10 +1033,7 @@ class BinaryView(object): section_list = core.BNGetSections(self.handle, count) result = {} for i in xrange(0, count.value): - result[section_list[i].name] = Section(section_list[i].name, section_list[i].type, section_list[i].start, - section_list[i].length, section_list[i].linkedSection, section_list[i].infoSection, - section_list[i].infoData, section_list[i].align, section_list[i].entrySize, - section_list[i].semantics, section_list[i].autoDefined) + result[core.BNSectionGetName(section_list[i])] = Section(section_list[i]) core.BNFreeSectionList(section_list, count.value) return result @@ -1816,6 +1857,16 @@ class BinaryView(object): """ return core.BNIsOffsetCodeSemantics(self.handle, addr) + def is_offset_extern_semantics(self, addr): + """ + ``is_offset_extern_semantics`` checks if an virtual address ``addr`` is semantically valid for external references. + + :param int addr: a virtual address to be checked + :return: true if the virtual address is valid for writing, false if the virtual address is invalid or error + :rtype: bool + """ + return core.BNIsOffsetExternSemantics(self.handle, addr) + def is_offset_writable_semantics(self, addr): """ ``is_offset_writable_semantics`` checks if an virtual address ``addr`` is semantically writable. Some sections @@ -3373,12 +3424,10 @@ class BinaryView(object): core.BNRemoveUserSegment(self.handle, start, length) def get_segment_at(self, addr): - segment = core.BNSegment() - if not core.BNGetSegmentAt(self.handle, addr, segment): + seg = core.BNGetSegmentAt(self.handle, addr) + if not seg: return None - result = Segment(segment.start, segment.length, segment.dataOffset, segment.dataLength, - segment.flags, segment.autoDefined) - return result + return Segment(seg) def get_address_for_data_offset(self, offset): address = ctypes.c_ulonglong() @@ -3407,10 +3456,7 @@ class BinaryView(object): section_list = core.BNGetSectionsAt(self.handle, addr, count) result = [] for i in xrange(0, count.value): - result.append(Section(section_list[i].name, section_list[i].type, section_list[i].start, - section_list[i].length, section_list[i].linkedSection, section_list[i].infoSection, - section_list[i].infoData, section_list[i].align, section_list[i].entrySize, - section_list[i].semantics, section_list[i].autoDefined)) + result.append(Section(section_list[i])) core.BNFreeSectionList(section_list, count.value) return result @@ -3418,9 +3464,7 @@ class BinaryView(object): section = core.BNSection() if not core.BNGetSectionByName(self.handle, name, section): return None - result = Section(section.name, section.type, section.start, section.length, section.linkedSection, - section.infoSection, section.infoData, section.align, section.entrySize, section.semantics, - section.autoDefined) + result = Section(section) core.BNFreeSection(section) return result diff --git a/relocationhandler.cpp b/relocationhandler.cpp new file mode 100644 index 00000000..2f0cbbde --- /dev/null +++ b/relocationhandler.cpp @@ -0,0 +1,114 @@ +// Copyright (c) 2015-2017 Vector 35 LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "binaryninjaapi.h" + +using namespace std; +using namespace BinaryNinja; + + +RelocationHandler::RelocationHandler(BNRelocationHandler* handler) +{ + m_object = handler; +} + + +RelocationHandler::RelocationHandler() +{ + BNCustomRelocationHandler handler; + handler.context = this; + handler.freeObject = FreeCallback; + handler.getRelocationInfo = GetRelocationInfoCallback; + handler.applyRelocation = ApplyRelocationCallback; + + AddRefForRegistration(); + m_object = BNCreateRelocationHandler(&handler); +} + + +void RelocationHandler::FreeCallback(void* ctxt) +{ + RelocationHandler* handler = (RelocationHandler*)ctxt; + handler->ReleaseForRegistration(); +} + + +bool RelocationHandler::GetRelocationInfoCallback(void* ctxt, BNBinaryView* view, BNArchitecture* arch, + BNRelocationInfo* result, size_t resultCount) +{ + RelocationHandler* handler = (RelocationHandler*)ctxt; + Ref<BinaryView> viewObj = new BinaryView(BNNewViewReference(view)); + Ref<Architecture> archObj = new CoreArchitecture(arch); + if (!result) + return false; + vector<BNRelocationInfo> resultVector(&result[0], &result[resultCount]); + bool success = handler->GetRelocationInfo(viewObj, archObj, resultVector); + for (size_t i = 0; i < resultCount; i++) + result[i] = resultVector[i]; + return success; +} + + +bool RelocationHandler::ApplyRelocationCallback(void* ctxt, BNBinaryView* view, BNArchitecture* arch, BNRelocation* reloc, + uint8_t* dest, size_t len) +{ + RelocationHandler* handler = (RelocationHandler*)ctxt; + Ref<Architecture> archObj = new CoreArchitecture(arch); + Ref<BinaryView> viewObj = new BinaryView(BNNewViewReference(view)); + Ref<Relocation> relocObj = new Relocation(BNNewRelocationReference(reloc)); + return handler->ApplyRelocation(viewObj, archObj, relocObj, dest, len); +} + + +bool RelocationHandler::GetRelocationInfo(Ref<BinaryView> view, Ref<Architecture> arch, std::vector<BNRelocationInfo>& result) +{ + return false; +} + + +bool RelocationHandler::ApplyRelocation(Ref<BinaryView> view, Ref<Architecture> arch, Ref<Relocation> reloc, uint8_t* dest, + size_t len) +{ + return BNRelocationHandlerDefaultApplyRelocation(m_object, view->GetObject(), arch->GetObject(), BNNewRelocationReference(reloc->GetObject()), dest, len); +} + +CoreRelocationHandler::CoreRelocationHandler(BNRelocationHandler* handler) : RelocationHandler(handler) +{ +} + + +bool CoreRelocationHandler::ApplyRelocation(Ref<BinaryView> view, Ref<Architecture> arch, Ref<Relocation> reloc, uint8_t* dest, + size_t len) +{ + return BNRelocationHandlerApplyRelocation(m_object, view->GetObject(), arch->GetObject(), BNNewRelocationReference(reloc->GetObject()), dest, len); +} + + +bool CoreRelocationHandler::GetRelocationInfo(Ref<BinaryView> view, Ref<Architecture> arch, std::vector<BNRelocationInfo>& result) +{ + BNRelocationInfo* results = new BNRelocationInfo[result.size()]; + for (size_t i = 0; i < result.size(); i++) + results[i] = result[i]; + bool status = BNRelocationHandlerGetRelocationInfo(m_object, view->GetObject(), arch->GetObject(), results, + result.size()); + for (size_t i = 0; i < result.size(); i++) + result[i] = results[i]; + return status; +}
\ No newline at end of file |
