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