summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp16
-rw-r--r--binaryninjaapi.h130
-rw-r--r--binaryninjacore.h174
-rw-r--r--binaryview.cpp414
-rw-r--r--callingconvention.cpp2
-rw-r--r--python/binaryview.py184
-rw-r--r--relocationhandler.cpp114
7 files changed, 847 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 f2c15fde..678caa06 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);
@@ -1051,28 +1048,54 @@ 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;
+
+ std::vector<std::pair<uint64_t, uint64_t>> GetRelocationRanges() const;
+ std::vector<std::pair<uint64_t, uint64_t>> GetRelocationRangesAtAddress(uint64_t addr) const;
+ uint64_t GetRelocationsCount() 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;
@@ -1123,7 +1146,8 @@ namespace BinaryNinja
virtual size_t PerformGetAddressSize() const;
virtual bool PerformSave(FileAccessor* file);
-
+ void PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc);
+ void PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref<Symbol> sym, uint64_t reloc);
void NotifyDataWritten(uint64_t offset, size_t len);
void NotifyDataInserted(uint64_t offset, size_t len);
void NotifyDataRemoved(uint64_t offset, uint64_t len);
@@ -1150,7 +1174,8 @@ 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, uint64_t target, uint64_t reloc);
+ static void DefineSymbolRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSymbol* target, uint64_t reloc);
public:
BinaryView(BNBinaryView* view);
@@ -1201,6 +1226,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;
@@ -1222,6 +1248,11 @@ namespace BinaryNinja
bool Save(FileAccessor* file);
bool Save(const std::string& path);
+ void DefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc);
+ void DefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref<Symbol> target, uint64_t reloc);
+ std::vector<std::pair<uint64_t, uint64_t>> GetRelocationRanges() const;
+ std::vector<std::pair<uint64_t, uint64_t>> GetRelocationRangesAtAddress(uint64_t addr) const;
+
void RegisterNotification(BinaryDataNotification* notify);
void UnregisterNotification(BinaryDataNotification* notify);
@@ -1341,8 +1372,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,
@@ -1355,9 +1386,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);
@@ -1376,6 +1407,19 @@ namespace BinaryNinja
void SetMaxFunctionSizeForAnalysis(uint64_t size);
};
+
+ class Relocation: public CoreRefCountObject<BNRelocation, BNNewRelocationReference, BNFreeRelocation>
+ {
+ public:
+ Relocation(BNRelocation* reloc);
+ BNRelocationInfo GetInfo() const;
+ Architecture* GetArchitecture() const;
+ uint64_t GetTarget() const;
+ uint64_t GetReloc() const;
+ Ref<Symbol> GetSymbol() const;
+ };
+
+
class BinaryData: public BinaryView
{
public:
@@ -1616,6 +1660,7 @@ namespace BinaryNinja
class MediumLevelILFunction;
class FunctionRecognizer;
class CallingConvention;
+ class RelocationHandler;
typedef size_t ExprId;
@@ -1846,6 +1891,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,
@@ -1887,6 +1934,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;
@@ -3323,6 +3371,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 fda26d47..cf84fdc5 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -144,6 +144,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);
@@ -266,7 +271,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
@@ -1039,6 +1054,8 @@ 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, uint64_t target, uint64_t reloc);
+ void (*defineSymbolRelocation) (void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSymbol* target, uint64_t reloc);
};
struct BNCustomBinaryViewType
@@ -1081,6 +1098,33 @@ 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
+ bool dataRelocation; // This relocation is effecting data not code
+ };
+
struct BNInstructionTextToken
{
BNInstructionTextTokenType type;
@@ -1332,6 +1376,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;
@@ -1727,33 +1782,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,
+ ExternalSectionSemantics
};
struct BNAddressRange
@@ -1815,6 +1850,12 @@ extern "C"
AlwaysSkipFunctionAnalysis
};
+ struct BNRange
+ {
+ uint64_t start;
+ uint64_t end;
+ };
+
enum BNAnalysisSkipReason
{
NoSkipReason,
@@ -1994,6 +2035,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);
@@ -2014,6 +2056,12 @@ 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,
+ uint64_t target, uint64_t reloc);
+ BINARYNINJACOREAPI void BNDefineSymbolRelocation(BNBinaryView* view, BNArchitecture* arch, BNRelocationInfo* info,
+ BNSymbol* target, uint64_t reloc);
+ BINARYNINJACOREAPI BNRange* BNGetRelocationRanges(BNBinaryView* segment, size_t* count);
+ BINARYNINJACOREAPI BNRange* BNGetRelocationRangesAtAddress(BNBinaryView* segment, uint64_t addr, size_t* count);
BINARYNINJACOREAPI void BNRegisterDataNotification(BNBinaryView* view, BNBinaryDataNotification* notify);
BINARYNINJACOREAPI void BNUnregisterDataNotification(BNBinaryView* view, BNBinaryDataNotification* notify);
@@ -2040,9 +2088,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,
@@ -2053,11 +2101,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);
@@ -2077,7 +2124,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);
@@ -2183,7 +2229,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,
@@ -2262,9 +2308,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,
@@ -2272,6 +2316,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);
@@ -3540,6 +3596,54 @@ extern "C"
BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key);
BINARYNINJACOREAPI void BNBinaryViewRemoveMetadata(BNBinaryView* view, const char* key);
+
+ // Relocation object methods
+ BINARYNINJACOREAPI BNRelocation* BNNewRelocationReference(BNRelocation* reloc);
+ BINARYNINJACOREAPI void BNFreeRelocation(BNRelocation* reloc);
+ BINARYNINJACOREAPI BNRelocationInfo BNRelocationGetInfo(BNRelocation* reloc);
+ BINARYNINJACOREAPI BNArchitecture* BNRelocationGetArchitecture(BNRelocation* reloc);
+ BINARYNINJACOREAPI uint64_t BNRelocationGetTarget(BNRelocation* reloc);
+ BINARYNINJACOREAPI uint64_t BNRelocationGetReloc(BNRelocation* reloc);
+ BINARYNINJACOREAPI BNSymbol* BNRelocationGetSymbol(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 BNRange* BNSegmentGetRelocationRanges(BNSegment* segment, size_t* count);
+ BINARYNINJACOREAPI uint64_t BNSegmentGetRelocationsCount(BNSegment* segment);
+ BINARYNINJACOREAPI BNRange* BNSegmentGetRelocationRangesAtAddress(BNSegment* segment, uint64_t addr, size_t* count);
+ BINARYNINJACOREAPI void BNFreeRelocationRanges(BNRange* ranges);
+ 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 bebfb801..c6970ff5 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -267,6 +267,196 @@ void AnalysisCompletionEvent::Cancel()
}
+Segment::Segment(BNSegment* seg)
+{
+ m_object = seg;
+}
+
+
+vector<pair<uint64_t, uint64_t>> Segment::GetRelocationRanges() const
+{
+ size_t count = 0;
+ BNRange* ranges = BNSegmentGetRelocationRanges(m_object, &count);
+ vector<pair<uint64_t, uint64_t>> result(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ result.push_back({ranges[i].start, ranges[i].end});
+ }
+ BNFreeRelocationRanges(ranges);
+ return result;
+}
+
+
+vector<pair<uint64_t, uint64_t>> Segment::GetRelocationRangesAtAddress(uint64_t addr) const
+{
+ size_t count = 0;
+ BNRange* ranges = BNSegmentGetRelocationRangesAtAddress(m_object, addr, &count);
+ vector<pair<uint64_t, uint64_t>> result(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ result.push_back({ranges[i].start, ranges[i].end});
+ }
+ BNFreeRelocationRanges(ranges);
+ return result;
+}
+
+
+uint64_t Segment::GetRelocationsCount() const
+{
+ return BNSegmentGetRelocationsCount(m_object);
+}
+
+
+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 +482,8 @@ BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryVi
view.isRelocatable = IsRelocatableCallback;
view.getAddressSize = GetAddressSizeCallback;
view.save = SaveCallback;
-
+ view.defineRelocation = DefineRelocationCallback;
+ view.defineSymbolRelocation = DefineSymbolRelocationCallback;
m_file = file;
AddRefForRegistration();
m_object = BNCreateCustomBinaryView(typeName.c_str(), m_file->GetObject(),
@@ -455,6 +646,27 @@ bool BinaryView::SaveCallback(void* ctxt, BNFileAccessor* file)
}
+void BinaryView::DefineRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, uint64_t target,
+ uint64_t reloc)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ BNRelocationInfo curInfo = *info;
+ Architecture* curArch = new CoreArchitecture(arch);
+ return view->PerformDefineRelocation(curArch, curInfo, target, reloc);
+}
+
+
+void BinaryView::DefineSymbolRelocationCallback(void* ctxt, BNArchitecture* arch, BNRelocationInfo* info, BNSymbol* sym,
+ uint64_t reloc)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ BNRelocationInfo curInfo = *info;
+ Architecture* curArch = new CoreArchitecture(arch);
+ Ref<Symbol> curSymbol = new Symbol(sym);
+ return view->PerformDefineRelocation(curArch, curInfo, curSymbol, reloc);
+}
+
+
bool BinaryView::PerformIsValidOffset(uint64_t offset)
{
uint8_t val;
@@ -528,6 +740,18 @@ bool BinaryView::PerformSave(FileAccessor* file)
}
+void BinaryView::PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc)
+{
+ DefineRelocation(arch, info, target, reloc);
+}
+
+
+void BinaryView::PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref<Symbol> target, uint64_t reloc)
+{
+ DefineRelocation(arch, info, target, reloc);
+}
+
+
void BinaryView::NotifyDataWritten(uint64_t offset, size_t len)
{
BNNotifyDataWritten(m_object, offset, len);
@@ -707,6 +931,46 @@ bool BinaryView::Save(const string& path)
}
+void BinaryView::DefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc)
+{
+ BNDefineRelocation(m_object, arch->GetObject(), &info, target, reloc);
+}
+
+
+void BinaryView::DefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref<Symbol> target, uint64_t reloc)
+{
+ BNDefineSymbolRelocation(m_object, arch->GetObject(), &info, target->GetObject(), reloc);
+}
+
+
+vector<pair<uint64_t, uint64_t>> BinaryView::GetRelocationRanges() const
+{
+ size_t count = 0;
+ BNRange* ranges = BNGetRelocationRanges(m_object, &count);
+ vector<pair<uint64_t, uint64_t>> result(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ result.push_back({ranges[i].start, ranges[i].end});
+ }
+ BNFreeRelocationRanges(ranges);
+ return result;
+}
+
+
+vector<pair<uint64_t, uint64_t>> BinaryView::GetRelocationRangesAtAddress(uint64_t addr) const
+{
+ size_t count = 0;
+ BNRange* ranges = BNGetRelocationRangesAtAddress(m_object, addr, &count);
+ vector<pair<uint64_t, uint64_t>> result(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ result.push_back({ranges[i].start, ranges[i].end});
+ }
+ BNFreeRelocationRanges(ranges);
+ return result;
+}
+
+
void BinaryView::RegisterNotification(BinaryDataNotification* notify)
{
BNRegisterDataNotification(m_object, notify->GetCallbacks());
@@ -785,6 +1049,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);
@@ -1757,42 +2027,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;
- result.autoDefined = segment.autoDefined;
- return true;
+ return new Segment(BNNewSegmentReference(segment));
}
@@ -1832,55 +2088,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);
@@ -1888,25 +2120,12 @@ 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;
+ BNSection* section = BNGetSectionByName(m_object, name.c_str());
+ if (section)
+ return new Section(section);
+ return nullptr;
}
@@ -2008,6 +2227,45 @@ 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));
+}
+
+
+uint64_t Relocation::GetTarget() const
+{
+ return BNRelocationGetTarget(m_object);
+}
+
+
+uint64_t Relocation::GetReloc() const
+{
+ return BNRelocationGetReloc(m_object);
+}
+
+
+Ref<Symbol> Relocation::GetSymbol() const
+{
+ BNSymbol* sym = BNRelocationGetSymbol(m_object);
+ if (!sym)
+ return nullptr;
+ return new Symbol(sym);
+}
+
+
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 1e078523..5bebec8e 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -455,32 +455,74 @@ 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)
+
+ @property
+ def reloction_count(self):
+ return core.BNSegmentGetRelocationsCount(self.handle)
+
+ @property
+ def relocation_ranges(self):
+ """List of relocation range tuples (read-only)"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNSegmentGetRelocationRanges(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
+
+ def relocation_ranges_at(self, addr):
+ """List of relocation range tuples (read-only)"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNSegmentGetRelocationRangesAtAddress(self.handle, addr, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
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,
@@ -490,25 +532,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.BNSectionGetSemantics(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)
@@ -1019,9 +1091,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
@@ -1031,10 +1102,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
@@ -1083,6 +1151,29 @@ class BinaryView(object):
def max_function_size_for_analysis(self, size):
core.BNSetMaxFunctionSizeForAnalysis(self.handle, size)
+ @property
+ def relocation_ranges(self):
+ """List of relocation range tuples (read-only)"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNGetRelocationRanges(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
+
+ def relocation_ranges_at(self, addr):
+ """List of relocation range tuples for a given address"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNGetRelocationRangesAtAddress(self.handle, addr, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
+
def __len__(self):
return int(core.BNGetViewLength(self.handle))
@@ -1866,6 +1957,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
@@ -3425,12 +3526,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()
@@ -3459,10 +3558,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
@@ -3470,9 +3566,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