summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp16
-rw-r--r--binaryninjaapi.h132
-rw-r--r--binaryninjacore.h167
-rw-r--r--binaryview.cpp370
-rw-r--r--callingconvention.cpp2
-rw-r--r--python/binaryview.py134
-rw-r--r--relocationhandler.cpp114
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(), &section))
- 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(&section);
- 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