summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp61
-rw-r--r--basicblock.cpp2
-rw-r--r--binaryninjaapi.cpp9
-rw-r--r--binaryninjaapi.h173
-rw-r--r--binaryninjacore.h167
-rw-r--r--binaryview.cpp135
-rw-r--r--demangle.cpp4
-rw-r--r--function.cpp4
-rw-r--r--functiongraphblock.cpp2
-rw-r--r--lowlevelil.cpp8
-rw-r--r--platform.cpp149
-rw-r--r--python/__init__.py4
-rw-r--r--python/architecture.py54
-rw-r--r--python/basicblock.py4
-rw-r--r--python/binaryview.py199
-rw-r--r--python/function.py19
-rw-r--r--python/generator.cpp56
-rw-r--r--python/lowlevelil.py4
-rw-r--r--python/platform.py91
-rw-r--r--python/types.py292
-rw-r--r--type.cpp547
21 files changed, 1655 insertions, 329 deletions
diff --git a/architecture.cpp b/architecture.cpp
index 3c7d9af8..d72e7f42 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -52,7 +52,14 @@ InstructionTextToken::InstructionTextToken(): type(TextToken), value(0)
InstructionTextToken::InstructionTextToken(BNInstructionTextTokenType t, const std::string& txt, uint64_t val,
- size_t s, size_t o) : type(t), text(txt), value(val), size(s), operand(o)
+ size_t s, size_t o) : type(t), text(txt), value(val), size(s), operand(o), context(NoTokenContext), address(0)
+{
+}
+
+
+InstructionTextToken::InstructionTextToken(BNInstructionTextTokenType t, BNInstructionTextTokenContext ctxt,
+ const string& txt, uint64_t a, uint64_t val, size_t s, size_t o):
+ type(t), text(txt), value(val), size(s), operand(o), context(ctxt), address(a)
{
}
@@ -153,6 +160,8 @@ bool Architecture::GetInstructionTextCallback(void* ctxt, const uint8_t* data, u
(*result)[i].value = tokens[i].value;
(*result)[i].size = tokens[i].size;
(*result)[i].operand = tokens[i].operand;
+ (*result)[i].context = tokens[i].context;
+ (*result)[i].address = tokens[i].address;
}
return true;
}
@@ -737,9 +746,9 @@ void Architecture::SetBinaryViewTypeConstant(const string& type, const string& n
bool Architecture::ParseTypesFromSource(const string& source, const string& fileName,
- map<string, Ref<Type>>& types, map<string, Ref<Type>>& variables,
- map<string, Ref<Type>>& functions, string& errors,
- const vector<string>& includeDirs)
+ map<QualifiedName, Ref<Type>>& types, map<QualifiedName, Ref<Type>>& variables,
+ map<QualifiedName, Ref<Type>>& functions, string& errors, const vector<string>& includeDirs,
+ const string& autoTypeSource)
{
BNTypeParserResult result;
char* errorStr;
@@ -753,26 +762,35 @@ bool Architecture::ParseTypesFromSource(const string& source, const string& file
functions.clear();
bool ok = BNParseTypesFromSource(m_object, source.c_str(), fileName.c_str(), &result,
- &errorStr, includeDirList, includeDirs.size());
+ &errorStr, includeDirList, includeDirs.size(), autoTypeSource.c_str());
errors = errorStr;
BNFreeString(errorStr);
if (!ok)
return false;
for (size_t i = 0; i < result.typeCount; i++)
- types[result.types[i].name] = new Type(BNNewTypeReference(result.types[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.types[i].name);
+ types[name] = new Type(BNNewTypeReference(result.types[i].type));
+ }
for (size_t i = 0; i < result.variableCount; i++)
- types[result.variables[i].name] = new Type(BNNewTypeReference(result.variables[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.variables[i].name);
+ types[name] = new Type(BNNewTypeReference(result.variables[i].type));
+ }
for (size_t i = 0; i < result.functionCount; i++)
- types[result.functions[i].name] = new Type(BNNewTypeReference(result.functions[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.functions[i].name);
+ types[name] = new Type(BNNewTypeReference(result.functions[i].type));
+ }
BNFreeTypeParserResult(&result);
return true;
}
-bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<string, Ref<Type>>& types,
- map<string, Ref<Type>>& variables, map<string, Ref<Type>>& functions,
- string& errors, const vector<string>& includeDirs)
+bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<QualifiedName, Ref<Type>>& types,
+ map<QualifiedName, Ref<Type>>& variables, map<QualifiedName, Ref<Type>>& functions,
+ string& errors, const vector<string>& includeDirs, const string& autoTypeSource)
{
BNTypeParserResult result;
char* errorStr;
@@ -786,18 +804,27 @@ bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<string,
functions.clear();
bool ok = BNParseTypesFromSourceFile(m_object, fileName.c_str(), &result, &errorStr,
- includeDirList, includeDirs.size());
+ includeDirList, includeDirs.size(), autoTypeSource.c_str());
errors = errorStr;
BNFreeString(errorStr);
if (!ok)
return false;
for (size_t i = 0; i < result.typeCount; i++)
- types[result.types[i].name] = new Type(BNNewTypeReference(result.types[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.types[i].name);
+ types[name] = new Type(BNNewTypeReference(result.types[i].type));
+ }
for (size_t i = 0; i < result.variableCount; i++)
- variables[result.variables[i].name] = new Type(BNNewTypeReference(result.variables[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.variables[i].name);
+ variables[name] = new Type(BNNewTypeReference(result.variables[i].type));
+ }
for (size_t i = 0; i < result.functionCount; i++)
- functions[result.functions[i].name] = new Type(BNNewTypeReference(result.functions[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.functions[i].name);
+ functions[name] = new Type(BNNewTypeReference(result.functions[i].type));
+ }
BNFreeTypeParserResult(&result);
return true;
}
@@ -954,8 +981,8 @@ bool CoreArchitecture::GetInstructionText(const uint8_t* data, uint64_t addr, si
for (size_t i = 0; i < count; i++)
{
- result.push_back(InstructionTextToken(tokens[i].type, tokens[i].text, tokens[i].value,
- tokens[i].size, tokens[i].operand));
+ result.push_back(InstructionTextToken(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address,
+ tokens[i].value, tokens[i].size, tokens[i].operand));
}
BNFreeInstructionText(tokens, count);
diff --git a/basicblock.cpp b/basicblock.cpp
index 93a279a1..4edcc568 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -164,6 +164,8 @@ vector<DisassemblyTextLine> BasicBlock::GetDisassemblyText(DisassemblySettings*
token.value = lines[i].tokens[j].value;
token.size = lines[i].tokens[j].size;
token.operand = lines[i].tokens[j].operand;
+ token.context = lines[i].tokens[j].context;
+ token.address = lines[i].tokens[j].address;
line.tokens.push_back(token);
}
result.push_back(line);
diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp
index 483d7393..6b303bcd 100644
--- a/binaryninjaapi.cpp
+++ b/binaryninjaapi.cpp
@@ -257,3 +257,12 @@ void BinaryNinja::SetWorkerThreadCount(size_t count)
{
BNSetWorkerThreadCount(count);
}
+
+
+string BinaryNinja::GetUniqueIdentifierString()
+{
+ char* str = BNGetUniqueIdentifierString();
+ string result = str;
+ BNFreeString(str);
+ return result;
+}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 204cd2d8..370a9ae2 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -277,6 +277,7 @@ namespace BinaryNinja
class MainThreadAction;
class MainThreadActionHandler;
class InteractionHandler;
+ class QualifiedName;
struct FormInputField;
/*! Logs to the error console with the given BNLogLevel.
@@ -371,7 +372,7 @@ namespace BinaryNinja
bool DemangleMS(Architecture* arch,
const std::string& mangledName,
Type** outType,
- std::vector<std::string>& outVarName);
+ QualifiedName& outVarName);
void RegisterMainThread(MainThreadActionHandler* handler);
Ref<MainThreadAction> ExecuteOnMainThread(const std::function<void()>& action);
@@ -411,6 +412,53 @@ namespace BinaryNinja
BNMessageBoxButtonResult ShowMessageBox(const std::string& title, const std::string& text,
BNMessageBoxButtonSet buttons = OKButtonSet, BNMessageBoxIcon icon = InformationIcon);
+ std::string GetUniqueIdentifierString();
+
+ class QualifiedName
+ {
+ std::vector<std::string> m_name;
+
+ public:
+ QualifiedName();
+ QualifiedName(const std::string& name);
+ QualifiedName(const std::vector<std::string>& name);
+ QualifiedName(const QualifiedName& name);
+
+ QualifiedName& operator=(const std::string& name);
+ QualifiedName& operator=(const std::vector<std::string>& name);
+ QualifiedName& operator=(const QualifiedName& name);
+
+ bool operator==(const QualifiedName& other) const;
+ bool operator!=(const QualifiedName& other) const;
+ bool operator<(const QualifiedName& other) const;
+
+ QualifiedName operator+(const QualifiedName& other) const;
+
+ std::string& operator[](size_t i);
+ const std::string& operator[](size_t i) const;
+ std::vector<std::string>::iterator begin();
+ std::vector<std::string>::iterator end();
+ std::vector<std::string>::const_iterator begin() const;
+ std::vector<std::string>::const_iterator end() const;
+ std::string& front();
+ const std::string& front() const;
+ std::string& back();
+ const std::string& back() const;
+ void insert(std::vector<std::string>::iterator loc, const std::string& name);
+ void insert(std::vector<std::string>::iterator loc, std::vector<std::string>::iterator b,
+ std::vector<std::string>::iterator e);
+ void erase(std::vector<std::string>::iterator i);
+ void clear();
+ void push_back(const std::string& name);
+ size_t size() const;
+
+ std::string GetString() const;
+
+ BNQualifiedName GetAPIObject() const;
+ static void FreeAPIObject(BNQualifiedName* name);
+ static QualifiedName FromAPIObject(BNQualifiedName* name);
+ };
+
class DataBuffer
{
BNDataBuffer* m_buffer;
@@ -593,6 +641,8 @@ namespace BinaryNinja
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);
+ static void TypeDefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type);
+ static void TypeUndefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type);
public:
BinaryDataNotification();
@@ -611,6 +661,8 @@ namespace BinaryNinja
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; }
+ virtual void OnTypeDefined(BinaryView* data, const QualifiedName& name, Type* type) { (void)data; (void)name; (void)type; }
+ virtual void OnTypeUndefined(BinaryView* data, const QualifiedName& name, Type* type) { (void)data; (void)name; (void)type; }
};
class FileAccessor
@@ -682,10 +734,15 @@ namespace BinaryNinja
std::string text;
uint64_t value;
size_t size, operand;
+ BNInstructionTextTokenContext context;
+ uint64_t address;
InstructionTextToken();
InstructionTextToken(BNInstructionTextTokenType type, const std::string& text, uint64_t value = 0,
size_t size = 0, size_t operand = BN_INVALID_OPERAND);
+ InstructionTextToken(BNInstructionTextTokenType type, BNInstructionTextTokenContext context,
+ const std::string& text, uint64_t address, uint64_t value = 0, size_t size = 0,
+ size_t operand = BN_INVALID_OPERAND);
};
struct DisassemblyTextLine
@@ -749,7 +806,7 @@ namespace BinaryNinja
uint64_t align, entrySize;
};
- struct NameAndType;
+ struct QualifiedNameAndType;
/*! 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
@@ -971,15 +1028,21 @@ namespace BinaryNinja
std::vector<LinearDisassemblyLine> GetNextLinearDisassemblyLines(LinearDisassemblyPosition& pos,
DisassemblySettings* settings);
- bool ParseTypeString(const std::string& text, NameAndType& result, std::string& errors);
+ bool ParseTypeString(const std::string& text, QualifiedNameAndType& result, std::string& errors);
+
+ std::map<QualifiedName, Ref<Type>> GetTypes();
+ Ref<Type> GetTypeByName(const QualifiedName& name);
+ Ref<Type> GetTypeById(const std::string& id);
+ std::string GetTypeId(const QualifiedName& name);
+ QualifiedName GetTypeNameById(const std::string& id);
+ bool IsTypeAutoDefined(const QualifiedName& name);
+ QualifiedName DefineType(const std::string& id, const QualifiedName& defaultName, Ref<Type> type);
+ void DefineUserType(const QualifiedName& name, Ref<Type> type);
+ void UndefineType(const std::string& id);
+ void UndefineUserType(const QualifiedName& name);
+ void RenameType(const QualifiedName& oldName, const QualifiedName& newName);
- std::map<std::string, Ref<Type>> GetTypes();
- Ref<Type> GetTypeByName(const std::string& name);
- bool IsTypeAutoDefined(const std::string& name);
- void DefineType(const std::string& name, Ref<Type> type);
- void DefineUserType(const std::string& name, Ref<Type> type);
- void UndefineType(const std::string& name);
- void UndefineUserType(const std::string& name);
+ void RegisterPlatformTypes(Platform* platform);
bool FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags = NoFindFlags);
@@ -998,6 +1061,7 @@ namespace BinaryNinja
void RemoveUserSegment(uint64_t start, uint64_t length);
std::vector<Segment> GetSegments();
bool GetSegmentAt(uint64_t addr, Segment& result);
+ bool GetAddressForDataOffset(uint64_t offset, uint64_t& addr);
void AddAutoSection(const std::string& name, uint64_t start, uint64_t length, const std::string& type = "",
uint64_t align = 1, uint64_t entrySize = 0, const std::string& linkedSection = "",
@@ -1429,13 +1493,17 @@ namespace BinaryNinja
void SetBinaryViewTypeConstant(const std::string& type, const std::string& name, uint64_t value);
bool ParseTypesFromSource(const std::string& source, const std::string& fileName,
- std::map<std::string, Ref<Type>>& types, std::map<std::string, Ref<Type>>& variables,
- std::map<std::string, Ref<Type>>& functions, std::string& errors,
- const std::vector<std::string>& includeDirs = std::vector<std::string>());
- bool ParseTypesFromSourceFile(const std::string& fileName, std::map<std::string, Ref<Type>>& types,
- std::map<std::string, Ref<Type>>& variables,
- std::map<std::string, Ref<Type>>& functions, std::string& errors,
- const std::vector<std::string>& includeDirs = std::vector<std::string>());
+ std::map<QualifiedName, Ref<Type>>& types,
+ std::map<QualifiedName, Ref<Type>>& variables,
+ std::map<QualifiedName, Ref<Type>>& functions, std::string& errors,
+ const std::vector<std::string>& includeDirs = std::vector<std::string>(),
+ const std::string& autoTypeSource = "");
+ bool ParseTypesFromSourceFile(const std::string& fileName,
+ std::map<QualifiedName, Ref<Type>>& types,
+ std::map<QualifiedName, Ref<Type>>& variables,
+ std::map<QualifiedName, Ref<Type>>& functions, std::string& errors,
+ const std::vector<std::string>& includeDirs = std::vector<std::string>(),
+ const std::string& autoTypeSource = "");
void RegisterCallingConvention(CallingConvention* cc);
std::vector<Ref<CallingConvention>> GetCallingConventions();
@@ -1498,7 +1566,7 @@ namespace BinaryNinja
};
class Structure;
- class UnknownType;
+ class NamedTypeReference;
class Enumeration;
struct NameAndType
@@ -1507,6 +1575,12 @@ namespace BinaryNinja
Ref<Type> type;
};
+ struct QualifiedNameAndType
+ {
+ QualifiedName name;
+ Ref<Type> type;
+ };
+
class Type: public CoreRefCountObject<BNType, BNNewTypeReference, BNFreeType>
{
public:
@@ -1526,17 +1600,21 @@ namespace BinaryNinja
bool CanReturn() const;
Ref<Structure> GetStructure() const;
Ref<Enumeration> GetEnumeration() const;
- Ref<UnknownType> GetUnknownType() const;
+ Ref<NamedTypeReference> GetNamedTypeReference() const;
uint64_t GetElementCount() const;
void SetFunctionCanReturn(bool canReturn);
std::string GetString() const;
- std::string GetTypeAndName(const std::vector<std::string>& name) const;
+ std::string GetTypeAndName(const QualifiedName& name) const;
std::string GetStringBeforeName() const;
std::string GetStringAfterName() const;
+ std::vector<InstructionTextToken> GetTokens() const;
+ std::vector<InstructionTextToken> GetTokensBeforeName() const;
+ std::vector<InstructionTextToken> GetTokensAfterName() const;
+
Ref<Type> Duplicate() const;
static Ref<Type> VoidType();
@@ -1544,7 +1622,10 @@ namespace BinaryNinja
static Ref<Type> IntegerType(size_t width, bool sign, const std::string& altName = "");
static Ref<Type> FloatType(size_t width, const std::string& typeName = "");
static Ref<Type> StructureType(Structure* strct);
- static Ref<Type> UnknownNamedType(UnknownType* unknwn);
+ static Ref<Type> NamedType(NamedTypeReference* ref, size_t width = 0, size_t align = 1);
+ static Ref<Type> NamedType(const QualifiedName& name, Type* type);
+ static Ref<Type> NamedType(const std::string& id, const QualifiedName& name, Type* type);
+ static Ref<Type> NamedType(BinaryView* view, const QualifiedName& name);
static Ref<Type> EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0, bool issigned = false);
static Ref<Type> PointerType(Architecture* arch, Type* type, bool cnst = false, bool vltl = false,
BNReferenceType refType = PointerReferenceType);
@@ -1552,15 +1633,29 @@ namespace BinaryNinja
static Ref<Type> FunctionType(Type* returnValue, CallingConvention* callingConvention,
const std::vector<NameAndType>& params, bool varArg = false);
- static std::string GetQualifiedName(const std::vector<std::string>& names);
+ static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name);
+ static std::string GenerateAutoDemangledTypeId(const QualifiedName& name);
+ static std::string GetAutoDemangledTypeIdSource();
};
- class UnknownType: public CoreRefCountObject<BNUnknownType, BNNewUnknownTypeReference, BNFreeUnknownType>
+ class NamedTypeReference: public CoreRefCountObject<BNNamedTypeReference, BNNewNamedTypeReference,
+ BNFreeNamedTypeReference>
{
public:
- UnknownType(BNUnknownType* s, std::vector<std::string> name = {});
- std::vector<std::string> GetName() const;
- void SetName(const std::vector<std::string>& name);
+ NamedTypeReference(BNNamedTypeReference* nt);
+ NamedTypeReference(BNNamedTypeReferenceClass cls = UnknownNamedTypeClass, const std::string& id = "",
+ const QualifiedName& name = QualifiedName());
+ BNNamedTypeReferenceClass GetTypeClass() const;
+ void SetTypeClass(BNNamedTypeReferenceClass cls);
+ std::string GetTypeId() const;
+ void SetTypeId(const std::string& id);
+ QualifiedName GetName() const;
+ void SetName(const QualifiedName& name);
+
+ static Ref<NamedTypeReference> GenerateAutoTypeReference(BNNamedTypeReferenceClass cls,
+ const std::string& source, const QualifiedName& name);
+ static Ref<NamedTypeReference> GenerateAutoDemangledTypeReference(BNNamedTypeReferenceClass cls,
+ const QualifiedName& name);
};
struct StructureMember
@@ -1573,13 +1668,14 @@ namespace BinaryNinja
class Structure: public CoreRefCountObject<BNStructure, BNNewStructureReference, BNFreeStructure>
{
public:
+ Structure();
Structure(BNStructure* s);
- std::vector<std::string> GetName() const;
- void SetName(const std::vector<std::string>& name);
std::vector<StructureMember> GetMembers() const;
uint64_t GetWidth() const;
+ void SetWidth(size_t width);
size_t GetAlignment() const;
+ void SetAlignment(size_t align);
bool IsPacked() const;
void SetPacked(bool packed);
bool IsUnion() const;
@@ -1588,6 +1684,7 @@ namespace BinaryNinja
void AddMember(Type* type, const std::string& name);
void AddMemberAtOffset(Type* type, const std::string& name, uint64_t offset);
void RemoveMember(size_t idx);
+ void ReplaceMember(size_t idx, Type* type, const std::string& name);
};
struct EnumerationMember
@@ -1602,13 +1699,12 @@ namespace BinaryNinja
public:
Enumeration(BNEnumeration* e);
- std::vector<std::string> GetName() const;
- void SetName(const std::vector<std::string>& name);
-
std::vector<EnumerationMember> GetMembers() const;
void AddMember(const std::string& name);
void AddMemberWithValue(const std::string& name, uint64_t value);
+ void RemoveMember(size_t idx);
+ void ReplaceMember(size_t idx, const std::string& name, uint64_t value);
};
class DisassemblySettings: public CoreRefCountObject<BNDisassemblySettings,
@@ -2248,6 +2344,21 @@ namespace BinaryNinja
Ref<Platform> GetRelatedPlatform(Architecture* arch);
void AddRelatedPlatform(Architecture* arch, Platform* platform);
Ref<Platform> GetAssociatedPlatformByAddress(uint64_t& addr);
+
+ std::map<QualifiedName, Ref<Type>> GetTypes();
+ std::map<QualifiedName, Ref<Type>> GetVariables();
+ std::map<QualifiedName, Ref<Type>> GetFunctions();
+ std::map<uint32_t, QualifiedNameAndType> GetSystemCalls();
+ Ref<Type> GetTypeByName(const QualifiedName& name);
+ Ref<Type> GetVariableByName(const QualifiedName& name);
+ Ref<Type> GetFunctionByName(const QualifiedName& name);
+ std::string GetSystemCallName(uint32_t n);
+ Ref<Type> GetSystemCallType(uint32_t n);
+
+ std::string GenerateAutoPlatformTypeId(const QualifiedName& name);
+ Ref<NamedTypeReference> GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls,
+ const QualifiedName& name);
+ std::string GetAutoPlatformTypeIdSource();
};
class ScriptingOutputListener
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 1ee71402..b8531742 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -94,7 +94,7 @@ extern "C"
struct BNLowLevelILFunction;
struct BNType;
struct BNStructure;
- struct BNUnknownType;
+ struct BNNamedTypeReference;
struct BNEnumeration;
struct BNCallingConvention;
struct BNPlatform;
@@ -166,19 +166,17 @@ 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,
- CharacterConstantToken = 23,
+ ArgumentNameToken = 11,
+ HexDumpByteValueToken = 12,
+ HexDumpSkippedByteToken = 13,
+ HexDumpInvalidByteToken = 14,
+ HexDumpTextToken = 15,
+ OpcodeToken = 16,
+ StringToken = 17,
+ CharacterConstantToken = 18,
+ KeywordToken = 19,
+ TypeNameToken = 20,
+ FieldNameToken = 21,
// The following are output by the analysis system automatically, these should
// not be used directly by the architecture plugins
@@ -189,6 +187,15 @@ extern "C"
AddressDisplayToken = 68
};
+ enum BNInstructionTextTokenContext
+ {
+ NoTokenContext = 0,
+ StackVariableTokenContext = 1,
+ DataVariableTokenContext = 2,
+ FunctionReturnTokenContext = 3,
+ ArgumentTokenContext = 4
+ };
+
enum BNLinearDisassemblyLineType
{
BlankLineType,
@@ -364,7 +371,17 @@ extern "C"
FunctionTypeClass = 8,
VarArgsTypeClass = 9,
ValueTypeClass = 10,
- UnknownTypeClass = 11
+ NamedTypeReferenceClass = 11
+ };
+
+ enum BNNamedTypeReferenceClass
+ {
+ UnknownNamedTypeClass = 0,
+ TypedefNamedTypeClass = 1,
+ ClassNamedTypeClass = 2,
+ StructNamedTypeClass = 3,
+ UnionNamedTypeClass = 4,
+ EnumNamedTypeClass = 5
};
enum BNStructureType
@@ -614,6 +631,12 @@ extern "C"
bool (*navigate)(void* ctxt, const char* view, uint64_t offset);
};
+ struct BNQualifiedName
+ {
+ char** name;
+ size_t nameCount;
+ };
+
struct BNBinaryDataNotification
{
void* context;
@@ -628,6 +651,8 @@ extern "C"
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);
+ void (*typeDefined)(void* ctxt, BNBinaryView* view, BNQualifiedName* name, BNType* type);
+ void (*typeUndefined)(void* ctxt, BNBinaryView* view, BNQualifiedName* name, BNType* type);
};
struct BNFileAccessor
@@ -708,6 +733,8 @@ extern "C"
char* text;
uint64_t value;
size_t size, operand;
+ BNInstructionTextTokenContext context;
+ uint64_t address;
};
struct BNInstructionTextLine
@@ -831,6 +858,12 @@ extern "C"
BNType* type;
};
+ struct BNQualifiedNameAndType
+ {
+ BNQualifiedName name;
+ BNType* type;
+ };
+
struct BNStructureMember
{
BNType* type;
@@ -853,9 +886,9 @@ extern "C"
struct BNTypeParserResult
{
- BNNameAndType* types;
- BNNameAndType* variables;
- BNNameAndType* functions;
+ BNQualifiedNameAndType* types;
+ BNQualifiedNameAndType* variables;
+ BNQualifiedNameAndType* functions;
size_t typeCount, variableCount, functionCount;
};
@@ -1187,6 +1220,13 @@ extern "C"
uint64_t end;
};
+ struct BNSystemCallInfo
+ {
+ uint32_t number;
+ BNQualifiedName name;
+ BNType* type;
+ };
+
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
BINARYNINJACOREAPI void BNFreeString(char* str);
BINARYNINJACOREAPI void BNFreeStringList(char** strs, size_t count);
@@ -1204,6 +1244,8 @@ extern "C"
BINARYNINJACOREAPI void BNRegisterObjectDestructionCallbacks(BNObjectDestructionCallbacks* callbacks);
BINARYNINJACOREAPI void BNUnregisterObjectDestructionCallbacks(BNObjectDestructionCallbacks* callbacks);
+ BINARYNINJACOREAPI char* BNGetUniqueIdentifierString(void);
+
// Plugin initialization
BINARYNINJACOREAPI void BNInitCorePlugins(void);
BINARYNINJACOREAPI void BNInitUserPlugins(void);
@@ -1390,6 +1432,7 @@ extern "C"
BINARYNINJACOREAPI BNSegment* BNGetSegments(BNBinaryView* view, size_t* count);
BINARYNINJACOREAPI void BNFreeSegmentList(BNSegment* segments);
BINARYNINJACOREAPI bool BNGetSegmentAt(BNBinaryView* view, uint64_t addr, BNSegment* result);
+ 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,
const char* type, uint64_t align, uint64_t entrySize, const char* linkedSection, const char* infoSection,
@@ -1768,17 +1811,31 @@ extern "C"
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 bool BNParseTypeString(BNBinaryView* view, const char* text,
+ BNQualifiedNameAndType* result, char** errors);
BINARYNINJACOREAPI void BNFreeNameAndType(BNNameAndType* obj);
+ BINARYNINJACOREAPI void BNFreeQualifiedNameAndType(BNQualifiedNameAndType* obj);
- BINARYNINJACOREAPI BNNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count);
- BINARYNINJACOREAPI void BNFreeTypeList(BNNameAndType* types, size_t count);
- BINARYNINJACOREAPI BNType* BNGetAnalysisTypeByName(BNBinaryView* view, const char* name);
- BINARYNINJACOREAPI bool BNIsAnalysisTypeAutoDefined(BNBinaryView* view, const char* name);
- BINARYNINJACOREAPI void BNDefineAnalysisType(BNBinaryView* view, const char* name, BNType* type);
- BINARYNINJACOREAPI void BNDefineUserAnalysisType(BNBinaryView* view, const char* name, BNType* type);
- BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, const char* name);
- BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, const char* name);
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count);
+ BINARYNINJACOREAPI void BNFreeTypeList(BNQualifiedNameAndType* types, size_t count);
+ BINARYNINJACOREAPI BNType* BNGetAnalysisTypeByName(BNBinaryView* view, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNType* BNGetAnalysisTypeById(BNBinaryView* view, const char* id);
+ BINARYNINJACOREAPI char* BNGetAnalysisTypeId(BNBinaryView* view, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNQualifiedName BNGetAnalysisTypeNameById(BNBinaryView* view, const char* id);
+ BINARYNINJACOREAPI bool BNIsAnalysisTypeAutoDefined(BNBinaryView* view, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNQualifiedName BNDefineAnalysisType(BNBinaryView* view, const char* id,
+ BNQualifiedName* defaultName, BNType* type);
+ BINARYNINJACOREAPI void BNDefineUserAnalysisType(BNBinaryView* view, BNQualifiedName* name, BNType* type);
+ BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, const char* id);
+ BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, BNQualifiedName* name);
+ BINARYNINJACOREAPI void BNRenameAnalysisType(BNBinaryView* view, BNQualifiedName* oldName, BNQualifiedName* newName);
+ BINARYNINJACOREAPI char* BNGenerateAutoTypeId(const char* source, BNQualifiedName* name);
+ BINARYNINJACOREAPI char* BNGenerateAutoPlatformTypeId(BNPlatform* platform, BNQualifiedName* name);
+ BINARYNINJACOREAPI char* BNGenerateAutoDemangledTypeId(BNQualifiedName* name);
+ BINARYNINJACOREAPI char* BNGetAutoPlatformTypeIdSource(BNPlatform* platform);
+ BINARYNINJACOREAPI char* BNGetAutoDemangledTypeIdSource(void);
+
+ BINARYNINJACOREAPI void BNRegisterPlatformTypes(BNBinaryView* view, BNPlatform* platform);
BINARYNINJACOREAPI void BNReanalyzeAllFunctions(BNBinaryView* view);
BINARYNINJACOREAPI void BNReanalyzeFunction(BNFunction* func);
@@ -1942,7 +1999,7 @@ extern "C"
BNNameAndType* params, size_t paramCount, bool varArg);
BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type);
BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type);
- BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, const char** nameList, size_t nameCount);
+ BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name);
BINARYNINJACOREAPI void BNFreeType(BNType* type);
BINARYNINJACOREAPI BNTypeClass BNGetTypeClass(BNType* type);
@@ -1960,30 +2017,42 @@ extern "C"
BINARYNINJACOREAPI bool BNFunctionTypeCanReturn(BNType* type);
BINARYNINJACOREAPI BNStructure* BNGetTypeStructure(BNType* type);
BINARYNINJACOREAPI BNEnumeration* BNGetTypeEnumeration(BNType* type);
+ BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type);
BINARYNINJACOREAPI uint64_t BNGetTypeElementCount(BNType* type);
BINARYNINJACOREAPI void BNSetFunctionCanReturn(BNType* type, bool canReturn);
BINARYNINJACOREAPI char* BNGetTypeString(BNType* type);
BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type);
BINARYNINJACOREAPI char* BNGetTypeStringAfterName(BNType* type);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokens(BNType* type, size_t* count);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensBeforeName(BNType* type, size_t* count);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensAfterName(BNType* type, size_t* count);
+ BINARYNINJACOREAPI void BNFreeTokenList(BNInstructionTextToken* tokens, size_t count);
- BINARYNINJACOREAPI BNType* BNCreateUnknownNamedType(BNUnknownType* ut);
- BINARYNINJACOREAPI BNUnknownType* BNCreateUnknownType(void);
- BINARYNINJACOREAPI void BNSetUnknownTypeName(BNUnknownType* ut, const char** name, size_t size);
- BINARYNINJACOREAPI char** BNGetUnknownTypeName(BNUnknownType* ut, size_t* size);
- BINARYNINJACOREAPI void BNFreeUnknownType(BNUnknownType* ut);
- BINARYNINJACOREAPI BNUnknownType* BNNewUnknownTypeReference(BNUnknownType* ut);
+ BINARYNINJACOREAPI BNType* BNCreateNamedTypeReference(BNNamedTypeReference* nt, size_t width, size_t align);
+ BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromTypeAndId(const char* id, BNQualifiedName* name, BNType* type);
+ BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromType(BNBinaryView* view, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNNamedTypeReference* BNCreateNamedType(void);
+ BINARYNINJACOREAPI void BNSetTypeReferenceClass(BNNamedTypeReference* nt, BNNamedTypeReferenceClass cls);
+ BINARYNINJACOREAPI BNNamedTypeReferenceClass BNGetTypeReferenceClass(BNNamedTypeReference* nt);
+ BINARYNINJACOREAPI void BNSetTypeReferenceId(BNNamedTypeReference* nt, const char* id);
+ BINARYNINJACOREAPI char* BNGetTypeReferenceId(BNNamedTypeReference* nt);
+ BINARYNINJACOREAPI void BNSetTypeReferenceName(BNNamedTypeReference* nt, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNQualifiedName BNGetTypeReferenceName(BNNamedTypeReference* nt);
+ BINARYNINJACOREAPI void BNFreeQualifiedName(BNQualifiedName* name);
+ BINARYNINJACOREAPI void BNFreeNamedTypeReference(BNNamedTypeReference* nt);
+ BINARYNINJACOREAPI BNNamedTypeReference* BNNewNamedTypeReference(BNNamedTypeReference* nt);
BINARYNINJACOREAPI BNStructure* BNCreateStructure(void);
BINARYNINJACOREAPI BNStructure* BNNewStructureReference(BNStructure* s);
BINARYNINJACOREAPI void BNFreeStructure(BNStructure* s);
- BINARYNINJACOREAPI char** BNGetStructureName(BNStructure* s, size_t* size);
- BINARYNINJACOREAPI void BNSetStructureName(BNStructure* s, const char** names, size_t size);
BINARYNINJACOREAPI BNStructureMember* BNGetStructureMembers(BNStructure* s, size_t* count);
BINARYNINJACOREAPI void BNFreeStructureMemberList(BNStructureMember* members, size_t count);
BINARYNINJACOREAPI uint64_t BNGetStructureWidth(BNStructure* s);
+ BINARYNINJACOREAPI void BNSetStructureWidth(BNStructure* s, uint64_t width);
BINARYNINJACOREAPI size_t BNGetStructureAlignment(BNStructure* s);
+ BINARYNINJACOREAPI void BNSetStructureAlignment(BNStructure* s, size_t align);
BINARYNINJACOREAPI bool BNIsStructurePacked(BNStructure* s);
BINARYNINJACOREAPI void BNSetStructurePacked(BNStructure* s, bool packed);
BINARYNINJACOREAPI bool BNIsStructureUnion(BNStructure* s);
@@ -1992,28 +2061,29 @@ extern "C"
BINARYNINJACOREAPI void BNAddStructureMember(BNStructure* s, BNType* type, const char* name);
BINARYNINJACOREAPI void BNAddStructureMemberAtOffset(BNStructure* s, BNType* type, const char* name, uint64_t offset);
BINARYNINJACOREAPI void BNRemoveStructureMember(BNStructure* s, size_t idx);
+ BINARYNINJACOREAPI void BNReplaceStructureMember(BNStructure* s, size_t idx, BNType* type, const char* name);
BINARYNINJACOREAPI BNEnumeration* BNCreateEnumeration(void);
BINARYNINJACOREAPI BNEnumeration* BNNewEnumerationReference(BNEnumeration* e);
BINARYNINJACOREAPI void BNFreeEnumeration(BNEnumeration* e);
- BINARYNINJACOREAPI char** BNGetEnumerationName(BNEnumeration* e, size_t* size);
- BINARYNINJACOREAPI void BNSetEnumerationName(BNEnumeration* e, const char** name, size_t size);
BINARYNINJACOREAPI BNEnumerationMember* BNGetEnumerationMembers(BNEnumeration* e, size_t* count);
BINARYNINJACOREAPI void BNFreeEnumerationMemberList(BNEnumerationMember* members, size_t count);
BINARYNINJACOREAPI void BNAddEnumerationMember(BNEnumeration* e, const char* name);
BINARYNINJACOREAPI void BNAddEnumerationMemberWithValue(BNEnumeration* e, const char* name, uint64_t value);
+ BINARYNINJACOREAPI void BNRemoveEnumerationMember(BNEnumeration* e, size_t idx);
+ BINARYNINJACOREAPI void BNReplaceEnumerationMember(BNEnumeration* e, size_t idx, const char* name, uint64_t value);
// Source code processing
BINARYNINJACOREAPI bool BNPreprocessSource(const char* source, const char* fileName, char** output, char** errors,
- const char** includeDirs, size_t includeDirCount);
+ const char** includeDirs, size_t includeDirCount);
BINARYNINJACOREAPI bool BNParseTypesFromSource(BNArchitecture* arch, const char* source, const char* fileName,
- BNTypeParserResult* result, char** errors,
- const char** includeDirs, size_t includeDirCount);
+ BNTypeParserResult* result, char** errors, const char** includeDirs, size_t includeDirCount,
+ const char* autoTypeSource);
BINARYNINJACOREAPI bool BNParseTypesFromSourceFile(BNArchitecture* arch, const char* fileName,
- BNTypeParserResult* result, char** errors,
- const char** includeDirs, size_t includeDirCount);
+ BNTypeParserResult* result, char** errors, const char** includeDirs, size_t includeDirCount,
+ const char* autoTypeSource);
BINARYNINJACOREAPI void BNFreeTypeParserResult(BNTypeParserResult* result);
// Updates
@@ -2142,6 +2212,17 @@ extern "C"
BINARYNINJACOREAPI void BNAddRelatedPlatform(BNPlatform* platform, BNArchitecture* arch, BNPlatform* related);
BINARYNINJACOREAPI BNPlatform* BNGetAssociatedPlatformByAddress(BNPlatform* platform, uint64_t* addr);
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetPlatformTypes(BNPlatform* platform, size_t* count);
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetPlatformVariables(BNPlatform* platform, size_t* count);
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetPlatformFunctions(BNPlatform* platform, size_t* count);
+ BINARYNINJACOREAPI BNSystemCallInfo* BNGetPlatformSystemCalls(BNPlatform* platform, size_t* count);
+ BINARYNINJACOREAPI void BNFreeSystemCallList(BNSystemCallInfo* syscalls, size_t count);
+ BINARYNINJACOREAPI BNType* BNGetPlatformTypeByName(BNPlatform* platform, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNType* BNGetPlatformVariableByName(BNPlatform* platform, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNType* BNGetPlatformFunctionByName(BNPlatform* platform, BNQualifiedName* name);
+ BINARYNINJACOREAPI char* BNGetPlatformSystemCallName(BNPlatform* platform, uint32_t number);
+ BINARYNINJACOREAPI BNType* BNGetPlatformSystemCallType(BNPlatform* platform, uint32_t number);
+
//Demangler
BINARYNINJACOREAPI bool BNDemangleMS(BNArchitecture* arch,
const char* mangledName,
diff --git a/binaryview.cpp b/binaryview.cpp
index cc6667c5..8edbc2bf 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -129,6 +129,24 @@ void BinaryDataNotification::StringRemovedCallback(void* ctxt, BNBinaryView* obj
}
+void BinaryDataNotification::TypeDefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type)
+{
+ BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
+ Ref<BinaryView> view = new BinaryView(BNNewViewReference(data));
+ Ref<Type> typeObj = new Type(BNNewTypeReference(type));
+ notify->OnTypeDefined(view, QualifiedName::FromAPIObject(name), typeObj);
+}
+
+
+void BinaryDataNotification::TypeUndefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type)
+{
+ BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
+ Ref<BinaryView> view = new BinaryView(BNNewViewReference(data));
+ Ref<Type> typeObj = new Type(BNNewTypeReference(type));
+ notify->OnTypeUndefined(view, QualifiedName::FromAPIObject(name), typeObj);
+}
+
+
BinaryDataNotification::BinaryDataNotification()
{
m_callbacks.context = this;
@@ -143,6 +161,8 @@ BinaryDataNotification::BinaryDataNotification()
m_callbacks.dataVariableUpdated = DataVariableUpdatedCallback;
m_callbacks.stringFound = StringFoundCallback;
m_callbacks.stringRemoved = StringRemovedCallback;
+ m_callbacks.typeDefined = TypeDefinedCallback;
+ m_callbacks.typeUndefined = TypeUndefinedCallback;
}
@@ -1366,6 +1386,8 @@ vector<LinearDisassemblyLine> BinaryView::GetPreviousLinearDisassemblyLines(Line
token.value = lines[i].contents.tokens[j].value;
token.size = lines[i].contents.tokens[j].size;
token.operand = lines[i].contents.tokens[j].operand;
+ token.context = lines[i].contents.tokens[j].context;
+ token.address = lines[i].contents.tokens[j].address;
line.contents.tokens.push_back(token);
}
result.push_back(line);
@@ -1409,6 +1431,8 @@ vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDi
token.value = lines[i].contents.tokens[j].value;
token.size = lines[i].contents.tokens[j].size;
token.operand = lines[i].contents.tokens[j].operand;
+ token.context = lines[i].contents.tokens[j].context;
+ token.address = lines[i].contents.tokens[j].address;
line.contents.tokens.push_back(token);
}
result.push_back(line);
@@ -1423,9 +1447,9 @@ vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDi
}
-bool BinaryView::ParseTypeString(const string& text, NameAndType& result, string& errors)
+bool BinaryView::ParseTypeString(const string& text, QualifiedNameAndType& result, string& errors)
{
- BNNameAndType nt;
+ BNQualifiedNameAndType nt;
char* errorStr;
if (!BNParseTypeString(m_object, text.c_str(), &nt, &errorStr))
@@ -1435,64 +1459,127 @@ bool BinaryView::ParseTypeString(const string& text, NameAndType& result, string
return false;
}
- result.name = nt.name;
- result.type = new Type(nt.type);
+ result.name = QualifiedName::FromAPIObject(&nt.name);
+ result.type = new Type(BNNewTypeReference(nt.type));
errors = "";
- BNFreeString(nt.name);
+ BNFreeQualifiedNameAndType(&nt);
return true;
}
-map<string, Ref<Type>> BinaryView::GetTypes()
+map<QualifiedName, Ref<Type>> BinaryView::GetTypes()
{
size_t count;
- BNNameAndType* types = BNGetAnalysisTypeList(m_object, &count);
+ BNQualifiedNameAndType* types = BNGetAnalysisTypeList(m_object, &count);
- map<string, Ref<Type>> result;
+ map<QualifiedName, Ref<Type>> result;
for (size_t i = 0; i < count; i++)
- result[types[i].name] = new Type(BNNewTypeReference(types[i].type));
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&types[i].name);
+ result[name] = new Type(BNNewTypeReference(types[i].type));
+ }
BNFreeTypeList(types, count);
return result;
}
-Ref<Type> BinaryView::GetTypeByName(const string& name)
+Ref<Type> BinaryView::GetTypeByName(const QualifiedName& name)
{
- BNType* type = BNGetAnalysisTypeByName(m_object, name.c_str());
+ BNQualifiedName nameObj = name.GetAPIObject();
+ BNType* type = BNGetAnalysisTypeByName(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+
if (!type)
return nullptr;
return new Type(type);
}
-bool BinaryView::IsTypeAutoDefined(const std::string& name)
+Ref<Type> BinaryView::GetTypeById(const string& id)
+{
+ BNType* type = BNGetAnalysisTypeById(m_object, id.c_str());
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+QualifiedName BinaryView::GetTypeNameById(const string& id)
+{
+ BNQualifiedName name = BNGetAnalysisTypeNameById(m_object, id.c_str());
+ QualifiedName result = QualifiedName::FromAPIObject(&name);
+ BNFreeQualifiedName(&name);
+ return result;
+}
+
+
+string BinaryView::GetTypeId(const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ char* id = BNGetAnalysisTypeId(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+ string result = id;
+ BNFreeString(id);
+ return result;
+}
+
+
+bool BinaryView::IsTypeAutoDefined(const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ bool result = BNIsAnalysisTypeAutoDefined(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+ return result;
+}
+
+
+QualifiedName BinaryView::DefineType(const string& id, const QualifiedName& defaultName, Ref<Type> type)
{
- return BNIsAnalysisTypeAutoDefined(m_object, name.c_str());
+ BNQualifiedName nameObj = defaultName.GetAPIObject();
+ BNQualifiedName regName = BNDefineAnalysisType(m_object, id.c_str(), &nameObj, type->GetObject());
+ QualifiedName::FreeAPIObject(&nameObj);
+ QualifiedName result = QualifiedName::FromAPIObject(&regName);
+ BNFreeQualifiedName(&regName);
+ return result;
}
-void BinaryView::DefineType(const std::string& name, Ref<Type> type)
+void BinaryView::DefineUserType(const QualifiedName& name, Ref<Type> type)
{
- BNDefineAnalysisType(m_object, name.c_str(), type->GetObject());
+ BNQualifiedName nameObj = name.GetAPIObject();
+ BNDefineUserAnalysisType(m_object, &nameObj, type->GetObject());
+ QualifiedName::FreeAPIObject(&nameObj);
}
-void BinaryView::DefineUserType(const std::string& name, Ref<Type> type)
+void BinaryView::UndefineType(const string& id)
{
- BNDefineUserAnalysisType(m_object, name.c_str(), type->GetObject());
+ BNUndefineAnalysisType(m_object, id.c_str());
}
-void BinaryView::UndefineType(const std::string& name)
+void BinaryView::UndefineUserType(const QualifiedName& name)
{
- BNUndefineAnalysisType(m_object, name.c_str());
+ BNQualifiedName nameObj = name.GetAPIObject();
+ BNUndefineUserAnalysisType(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
}
-void BinaryView::UndefineUserType(const std::string& name)
+void BinaryView::RenameType(const QualifiedName& oldName, const QualifiedName& newName)
{
- BNUndefineUserAnalysisType(m_object, name.c_str());
+ BNQualifiedName oldNameObj = oldName.GetAPIObject();
+ BNQualifiedName newNameObj = newName.GetAPIObject();
+ BNRenameAnalysisType(m_object, &oldNameObj, &newNameObj);
+ QualifiedName::FreeAPIObject(&oldNameObj);
+ QualifiedName::FreeAPIObject(&newNameObj);
+}
+
+
+void BinaryView::RegisterPlatformTypes(Platform* platform)
+{
+ BNRegisterPlatformTypes(m_object, platform->GetObject());
}
@@ -1604,6 +1691,12 @@ bool BinaryView::GetSegmentAt(uint64_t addr, Segment& result)
}
+bool BinaryView::GetAddressForDataOffset(uint64_t offset, uint64_t& addr)
+{
+ return BNGetAddressForDataOffset(m_object, offset, &addr);
+}
+
+
void BinaryView::AddAutoSection(const string& name, uint64_t start, uint64_t length, const string& type,
uint64_t align, uint64_t entrySize, const string& linkedSection, const string& infoSection, uint64_t infoData)
{
diff --git a/demangle.cpp b/demangle.cpp
index a12303ca..70a2fe08 100644
--- a/demangle.cpp
+++ b/demangle.cpp
@@ -6,7 +6,7 @@ using namespace std;
bool DemangleMS(Architecture* arch,
const std::string& mangledName,
Type** outType,
- std::vector<std::string>& outVarName)
+ QualifiedName& outVarName)
{
BNType* localType = (*outType)->GetObject();
char** localVarName = nullptr;
@@ -26,7 +26,7 @@ bool DemangleMS(Architecture* arch,
bool DemangleGNU3(Architecture* arch,
const std::string& mangledName,
Type** outType,
- std::vector<std::string>& outVarName)
+ QualifiedName& outVarName)
{
BNType* localType = (*outType)->GetObject();
char** localVarName = nullptr;
diff --git a/function.cpp b/function.cpp
index 109b6f49..b1d008ee 100644
--- a/function.cpp
+++ b/function.cpp
@@ -567,6 +567,10 @@ vector<vector<InstructionTextToken>> Function::GetBlockAnnotations(Architecture*
token.type = lines[i].tokens[j].type;
token.text = lines[i].tokens[j].text;
token.value = lines[i].tokens[j].value;
+ token.size = lines[i].tokens[j].size;
+ token.operand = lines[i].tokens[j].operand;
+ token.context = lines[i].tokens[j].context;
+ token.address = lines[i].tokens[j].address;
line.push_back(token);
}
result.push_back(line);
diff --git a/functiongraphblock.cpp b/functiongraphblock.cpp
index 47261453..db69c25a 100644
--- a/functiongraphblock.cpp
+++ b/functiongraphblock.cpp
@@ -101,6 +101,8 @@ const vector<DisassemblyTextLine>& FunctionGraphBlock::GetLines()
token.value = lines[i].tokens[j].value;
token.size = lines[i].tokens[j].size;
token.operand = lines[i].tokens[j].operand;
+ token.context = lines[i].tokens[j].context;
+ token.address = lines[i].tokens[j].address;
line.tokens.push_back(token);
}
result.push_back(line);
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index a312bbd6..bf3b980e 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -579,6 +579,10 @@ bool LowLevelILFunction::GetExprText(Architecture* arch, ExprId expr, vector<Ins
token.type = list[i].type;
token.text = list[i].text;
token.value = list[i].value;
+ token.size = list[i].size;
+ token.operand = list[i].operand;
+ token.context = list[i].context;
+ token.address = list[i].address;
tokens.push_back(token);
}
@@ -603,6 +607,10 @@ bool LowLevelILFunction::GetInstructionText(Function* func, Architecture* arch,
token.type = list[i].type;
token.text = list[i].text;
token.value = list[i].value;
+ token.size = list[i].size;
+ token.operand = list[i].operand;
+ token.context = list[i].context;
+ token.address = list[i].address;
tokens.push_back(token);
}
diff --git a/platform.cpp b/platform.cpp
index 7a6571cc..afbcbbf3 100644
--- a/platform.cpp
+++ b/platform.cpp
@@ -253,3 +253,152 @@ Ref<Platform> Platform::GetAssociatedPlatformByAddress(uint64_t& addr)
return nullptr;
return new Platform(platform);
}
+
+
+map<QualifiedName, Ref<Type>> Platform::GetTypes()
+{
+ size_t count;
+ BNQualifiedNameAndType* types = BNGetPlatformTypes(m_object, &count);
+
+ map<QualifiedName, Ref<Type>> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&types[i].name);
+ result[name] = new Type(BNNewTypeReference(types[i].type));
+ }
+
+ BNFreeTypeList(types, count);
+ return result;
+}
+
+
+map<QualifiedName, Ref<Type>> Platform::GetVariables()
+{
+ size_t count;
+ BNQualifiedNameAndType* types = BNGetPlatformVariables(m_object, &count);
+
+ map<QualifiedName, Ref<Type>> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&types[i].name);
+ result[name] = new Type(BNNewTypeReference(types[i].type));
+ }
+
+ BNFreeTypeList(types, count);
+ return result;
+}
+
+
+map<QualifiedName, Ref<Type>> Platform::GetFunctions()
+{
+ size_t count;
+ BNQualifiedNameAndType* types = BNGetPlatformFunctions(m_object, &count);
+
+ map<QualifiedName, Ref<Type>> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&types[i].name);
+ result[name] = new Type(BNNewTypeReference(types[i].type));
+ }
+
+ BNFreeTypeList(types, count);
+ return result;
+}
+
+
+map<uint32_t, QualifiedNameAndType> Platform::GetSystemCalls()
+{
+ size_t count;
+ BNSystemCallInfo* calls = BNGetPlatformSystemCalls(m_object, &count);
+
+ map<uint32_t, QualifiedNameAndType> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ QualifiedNameAndType nt;
+ nt.name = QualifiedName::FromAPIObject(&calls[i].name);
+ nt.type = new Type(BNNewTypeReference(calls[i].type));
+ result[calls[i].number] = nt;
+ }
+
+ BNFreeSystemCallList(calls, count);
+ return result;
+}
+
+
+Ref<Type> Platform::GetTypeByName(const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ BNType* type = BNGetPlatformTypeByName(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+Ref<Type> Platform::GetVariableByName(const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ BNType* type = BNGetPlatformVariableByName(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+Ref<Type> Platform::GetFunctionByName(const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ BNType* type = BNGetPlatformFunctionByName(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+string Platform::GetSystemCallName(uint32_t n)
+{
+ char* str = BNGetPlatformSystemCallName(m_object, n);
+ string result = str;
+ BNFreeString(str);
+ return result;
+}
+
+
+Ref<Type> Platform::GetSystemCallType(uint32_t n)
+{
+ BNType* type = BNGetPlatformSystemCallType(m_object, n);
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+string Platform::GenerateAutoPlatformTypeId(const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ char* str = BNGenerateAutoPlatformTypeId(m_object, &nameObj);
+ string result = str;
+ QualifiedName::FreeAPIObject(&nameObj);
+ BNFreeString(str);
+ return result;
+}
+
+
+Ref<NamedTypeReference> Platform::GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls,
+ const QualifiedName& name)
+{
+ string id = GenerateAutoPlatformTypeId(name);
+ return new NamedTypeReference(cls, id, name);
+}
+
+
+string Platform::GetAutoPlatformTypeIdSource()
+{
+ char* str = BNGetAutoPlatformTypeIdSource(m_object);
+ string result = str;
+ BNFreeString(str);
+ return result;
+}
diff --git a/python/__init__.py b/python/__init__.py
index e4d45435..b1f5cd08 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -54,6 +54,10 @@ def shutdown():
core.BNShutdown()
+def get_unique_identifier():
+ return core.BNGetUniqueIdentifierString()
+
+
class _DestructionCallbackHandler(object):
def __init__(self):
self._cb = core.BNObjectDestructionCallbacks()
diff --git a/python/architecture.py b/python/architecture.py
index 3e899d68..5bafe949 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -364,7 +364,7 @@ class Architecture(object):
def __setattr__(self, name, value):
if ((name == "name") or (name == "endianness") or (name == "address_size") or
- (name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length")):
+ (name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length")):
raise AttributeError("attribute '%s' is read only" % name)
else:
try:
@@ -467,6 +467,8 @@ class Architecture(object):
token_buf[i].value = tokens[i].value
token_buf[i].size = tokens[i].size
token_buf[i].operand = tokens[i].operand
+ token_buf[i].context = tokens[i].context
+ token_buf[i].address = tokens[i].address
result[0] = token_buf
ptr = ctypes.cast(token_buf, ctypes.c_void_p)
self._pending_token_lists[ptr.value] = (ptr.value, token_buf)
@@ -1148,7 +1150,9 @@ class Architecture(object):
value = tokens[i].value
size = tokens[i].size
operand = tokens[i].operand
- result.append(function.InstructionTextToken(token_type, text, value, size, operand))
+ context = tokens[i].context
+ address = tokens[i].address
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
core.BNFreeInstructionText(tokens, count.value)
return result, length.value
@@ -1581,7 +1585,7 @@ class Architecture(object):
"""
core.BNSetBinaryViewTypeArchitectureConstant(self.handle, type_name, const_name, value)
- def parse_types_from_source(self, source, filename=None, include_dirs=[]):
+ def parse_types_from_source(self, source, filename=None, include_dirs=[], auto_type_source=None):
"""
``parse_types_from_source`` parses the source string and any needed headers searching for them in
the optional list of directories provided in ``include_dirs``.
@@ -1589,8 +1593,9 @@ class Architecture(object):
:param str source: source string to be parsed
:param str filename: optional source filename
:param list(str) include_dirs: optional list of string filename include directories
- :return: a tuple of py:class:`TypeParserResult` and error string
- :rtype: tuple(TypeParserResult,str)
+ :param str auto_type_source: optional source of types if used for automatically generated types
+ :return: py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
+ :rtype: TypeParserResult
:Example:
>>> arch.parse_types_from_source('int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n')
@@ -1606,32 +1611,37 @@ class Architecture(object):
dir_buf[i] = str(include_dirs[i])
parse = core.BNTypeParserResult()
errors = ctypes.c_char_p()
- result = core.BNParseTypesFromSource(self.handle, source, filename, parse, errors, dir_buf, len(include_dirs))
+ result = core.BNParseTypesFromSource(self.handle, source, filename, parse, errors, dir_buf,
+ len(include_dirs), auto_type_source)
error_str = errors.value
core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
if not result:
- return (None, error_str)
+ raise SyntaxError(error_str)
type_dict = {}
variables = {}
functions = {}
for i in xrange(0, parse.typeCount):
- types[parse.types[i].name] = types.Type(core.BNNewTypeReference(parse.types[i].type))
+ name = types.QualifiedName._from_core_struct(parse.types[i].name)
+ type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type))
for i in xrange(0, parse.variableCount):
- variables[parse.variables[i].name] = types.Type(core.BNNewTypeReference(parse.variables[i].type))
+ name = types.QualifiedName._from_core_struct(parse.variables[i].name)
+ variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type))
for i in xrange(0, parse.functionCount):
- functions[parse.functions[i].name] = types.Type(core.BNNewTypeReference(parse.functions[i].type))
+ name = types.QualifiedName._from_core_struct(parse.functions[i].name)
+ functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type))
core.BNFreeTypeParserResult(parse)
- return (types.TypeParserResult(type_dict, variables, functions), error_str)
+ return types.TypeParserResult(type_dict, variables, functions)
- def parse_types_from_source_file(self, filename, include_dirs=[]):
+ def parse_types_from_source_file(self, filename, include_dirs=[], auto_type_source=None):
"""
``parse_types_from_source_file`` parses the source file ``filename`` and any needed headers searching for them in
the optional list of directories provided in ``include_dirs``.
:param str filename: filename of file to be parsed
:param list(str) include_dirs: optional list of string filename include directories
- :return: a tuple of py:class:`TypeParserResult` and error string
- :rtype: tuple(TypeParserResult, str)
+ :param str auto_type_source: optional source of types if used for automatically generated types
+ :return: py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
+ :rtype: TypeParserResult
:Example:
>>> file = "/Users/binja/tmp.c"
@@ -1647,22 +1657,26 @@ class Architecture(object):
dir_buf[i] = str(include_dirs[i])
parse = core.BNTypeParserResult()
errors = ctypes.c_char_p()
- result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf, len(include_dirs))
+ result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf,
+ len(include_dirs), auto_type_source)
error_str = errors.value
core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
if not result:
- return (None, error_str)
+ raise SyntaxError(error_str)
type_dict = {}
variables = {}
functions = {}
for i in xrange(0, parse.typeCount):
- type_dict[parse.types[i].name] = types.Type(core.BNNewTypeReference(parse.types[i].type))
+ name = types.QualifiedName._from_core_struct(parse.types[i].name)
+ type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type))
for i in xrange(0, parse.variableCount):
- variables[parse.variables[i].name] = types.Type(core.BNNewTypeReference(parse.variables[i].type))
+ name = types.QualifiedName._from_core_struct(parse.variables[i].name)
+ variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type))
for i in xrange(0, parse.functionCount):
- functions[parse.functions[i].name] = types.Type(core.BNNewTypeReference(parse.functions[i].type))
+ name = types.QualifiedName._from_core_struct(parse.functions[i].name)
+ functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type))
core.BNFreeTypeParserResult(parse)
- return (types.TypeParserResult(type_dict, variables, functions), error_str)
+ return types.TypeParserResult(type_dict, variables, functions)
def register_calling_convention(self, cc):
"""
diff --git a/python/basicblock.py b/python/basicblock.py
index 02e6a2c5..f6dbd60d 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -200,7 +200,9 @@ class BasicBlock(object):
value = lines[i].tokens[j].value
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
- tokens.append(function.InstructionTextToken(token_type, text, value, size, operand))
+ context = lines[i].tokens[j].context
+ address = lines[i].tokens[j].address
+ tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
result.append(function.DisassemblyTextLine(addr, tokens))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
diff --git a/python/binaryview.py b/python/binaryview.py
index c021024f..9753b653 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -78,6 +78,12 @@ class BinaryDataNotification(object):
def string_removed(self, view, string_type, offset, length):
pass
+ def type_defined(self, view, name, type):
+ pass
+
+ def type_undefined(self, view, name, type):
+ pass
+
class StringReference(object):
def __init__(self, string_type, start, length):
@@ -157,6 +163,8 @@ class BinaryDataNotificationCallbacks(object):
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)
+ self._cb.typeDefined = self._cb.typeDefined.__class__(self._type_defined)
+ self._cb.typeUndefined = self._cb.typeUndefined.__class__(self._type_undefined)
def _register(self):
core.BNRegisterDataNotification(self.view.handle, self._cb)
@@ -239,6 +247,20 @@ class BinaryDataNotificationCallbacks(object):
except:
log.log_error(traceback.format_exc())
+ def _type_defined(self, ctxt, name, type_obj):
+ try:
+ qualified_name = types.QualifiedName._from_core_struct(name[0])
+ self.notify.type_defined(self.view, qualified_name, types.Type(core.BNNewTypeReference(type_obj)))
+ except:
+ log.log_error(traceback.format_exc())
+
+ def _type_undefined(self, ctxt, name, type_obj):
+ try:
+ qualified_name = types.QualifiedName._from_core_struct(name[0])
+ self.notify.type_undefined(self.view, qualified_name, types.Type(core.BNNewTypeReference(type_obj)))
+ except:
+ log.log_error(traceback.format_exc())
+
class _BinaryViewTypeMetaclass(type):
@property
@@ -825,7 +847,8 @@ class BinaryView(object):
type_list = core.BNGetAnalysisTypeList(self.handle, count)
result = {}
for i in xrange(0, count.value):
- result[type_list[i].name] = types.Type(core.BNNewTypeReference(type_list[i].type))
+ name = types.QualifiedName._from_core_struct(type_list[i].name)
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type))
core.BNFreeTypeList(type_list, count.value)
return result
@@ -1867,7 +1890,7 @@ class BinaryView(object):
var = core.BNDataVariable()
if not core.BNGetDataVariableAtAddress(self.handle, addr, var):
return None
- return DataVariable(var.address, type.Type(var.type), var.autoDiscovered)
+ return DataVariable(var.address, types.Type(var.type), var.autoDiscovered)
def get_function_at(self, addr, plat=None):
"""
@@ -2731,7 +2754,9 @@ class BinaryView(object):
value = lines[i].contents.tokens[j].value
size = lines[i].contents.tokens[j].size
operand = lines[i].contents.tokens[j].operand
- tokens.append(function.InstructionTextToken(token_type, text, value, size, operand))
+ context = lines[i].contents.tokens[j].context
+ address = lines[i].contents.tokens[j].address
+ tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
contents = function.DisassemblyTextLine(addr, tokens)
result.append(lineardisassembly.LinearDisassemblyLine(lines[i].type, func, block, lines[i].lineOffset, contents))
@@ -2831,51 +2856,117 @@ class BinaryView(object):
``parse_type_string`` converts `C-style` string into a :py:Class:`Type`.
:param str text: `C-style` string of type to create
- :return: A tuple of a :py:Class:`Type` and string type name
- :rtype: tuple(Type, str)
+ :return: A tuple of a :py:Class:`Type` and type name
+ :rtype: tuple(Type, QualifiedName)
:Example:
>>> bv.parse_type_string("int foo")
(<type: int32_t>, 'foo')
>>>
"""
- result = core.BNNameAndType()
+ result = core.BNQualifiedNameAndType()
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 = types.Type(core.BNNewTypeReference(result.type))
- name = result.name
- core.BNFreeNameAndType(result)
+ name = types.QualifiedName._from_core_struct(result.name)
+ core.BNFreeQualifiedNameAndType(result)
return type_obj, name
def get_type_by_name(self, name):
"""
``get_type_by_name`` returns the defined type whose name corresponds with the provided ``name``
- :param str name: Type name to lookup
+ :param QualifiedName name: Type name to lookup
:return: A :py:Class:`Type` or None if the type does not exist
:rtype: Type or None
:Example:
>>> type, name = bv.parse_type_string("int foo")
- >>> bv.define_type(name, type)
+ >>> bv.define_user_type(name, type)
>>> bv.get_type_by_name(name)
<type: int32_t>
>>>
"""
+ name = types.QualifiedName(name)._get_core_struct()
obj = core.BNGetAnalysisTypeByName(self.handle, name)
if not obj:
return None
return types.Type(obj)
+ def get_type_by_id(self, id):
+ """
+ ``get_type_by_id`` returns the defined type whose unique identifier corresponds with the provided ``id``
+
+ :param str id: Unique identifier to lookup
+ :return: A :py:Class:`Type` or None if the type does not exist
+ :rtype: Type or None
+ :Example:
+
+ >>> type, name = bv.parse_type_string("int foo")
+ >>> type_id = Type.generate_auto_type_id("source", name)
+ >>> bv.define_type(type_id, name, type)
+ >>> bv.get_type_by_id(type_id)
+ <type: int32_t>
+ >>>
+ """
+ obj = core.BNGetAnalysisTypeById(self.handle, id)
+ if not obj:
+ return None
+ return types.Type(obj)
+
+ def get_type_name_by_id(self, id):
+ """
+ ``get_type_name_by_id`` returns the defined type name whose unique identifier corresponds with the provided ``id``
+
+ :param str id: Unique identifier to lookup
+ :return: A QualifiedName or None if the type does not exist
+ :rtype: QualifiedName or None
+ :Example:
+
+ >>> type, name = bv.parse_type_string("int foo")
+ >>> type_id = Type.generate_auto_type_id("source", name)
+ >>> bv.define_type(type_id, name, type)
+ 'foo'
+ >>> bv.get_type_name_by_id(type_id)
+ 'foo'
+ >>>
+ """
+ name = core.BNGetAnalysisTypeNameById(self.handle, id)
+ result = types.QualifiedName._from_core_struct(name)
+ core.BNFreeQualifiedName(name)
+ if len(result) == 0:
+ return None
+ return result
+
+ def get_type_id(self, name):
+ """
+ ``get_type_id`` returns the unique indentifier of the defined type whose name corresponds with the
+ provided ``name``
+
+ :param QualifiedName name: Type name to lookup
+ :return: The unique identifier of the type
+ :rtype: str
+ :Example:
+
+ >>> type, name = bv.parse_type_string("int foo")
+ >>> type_id = Type.generate_auto_type_id("source", name)
+ >>> registered_name = bv.define_type(type_id, name, type)
+ >>> bv.get_type_id(registered_name) == type_id
+ True
+ >>>
+ """
+ name = types.QualifiedName(name)._get_core_struct()
+ return core.BNGetAnalysisTypeId(self.handle, name)
+
def is_type_auto_defined(self, name):
"""
``is_type_auto_defined`` queries the user type list of name. If name is not in the *user* type list then the name
is considered an *auto* type.
- :param str name: Name of type to query
+ :param QualifiedName name: Name of type to query
:return: True if the type is not a *user* type. False if the type is a *user* type.
:Example:
>>> bv.is_type_auto_defined("foo")
@@ -2885,31 +2976,38 @@ class BinaryView(object):
False
>>>
"""
+ name = types.QualifiedName(name)._get_core_struct()
return core.BNIsAnalysisTypeAutoDefined(self.handle, name)
- def define_type(self, name, type_obj):
+ def define_type(self, type_id, default_name, type_obj):
"""
``define_type`` registers a :py:Class:`Type` ``type_obj`` of the given ``name`` in the global list of types for
- the current :py:Class:`BinaryView`.
+ the current :py:Class:`BinaryView`. This method should only be used for automatically generated types.
- :param str name: Name of the type to be registered
+ :param str type_id: Unique identifier for the automatically generated type
+ :param QualifiedName default_name: Name of the type to be registered
:param Type type_obj: Type object to be registered
- :rtype: None
+ :return: Registered name of the type. May not be the same as the requested name if the user has renamed types.
+ :rtype: QualifiedName
:Example:
>>> type, name = bv.parse_type_string("int foo")
- >>> bv.define_type(name, type)
- >>> bv.get_type_by_name(name)
+ >>> registered_name = bv.define_type(Type.generate_auto_type_id("source", name), name, type)
+ >>> bv.get_type_by_name(registered_name)
<type: int32_t>
"""
- core.BNDefineAnalysisType(self.handle, name, type_obj.handle)
+ name = types.QualifiedName(default_name)._get_core_struct()
+ reg_name = core.BNDefineAnalysisType(self.handle, type_id, name, type_obj.handle)
+ result = types.QualifiedName._from_core_struct(reg_name)
+ core.BNFreeQualifiedName(reg_name)
+ return result
def define_user_type(self, name, type_obj):
"""
``define_user_type`` registers a :py:Class:`Type` ``type_obj`` of the given ``name`` in the global list of user
types for the current :py:Class:`BinaryView`.
- :param str name: Name of the user type to be registered
+ :param QualifiedName name: Name of the user type to be registered
:param Type type_obj: Type object to be registered
:rtype: None
:Example:
@@ -2919,45 +3017,86 @@ class BinaryView(object):
>>> bv.get_type_by_name(name)
<type: int32_t>
"""
+ name = types.QualifiedName(name)._get_core_struct()
core.BNDefineUserAnalysisType(self.handle, name, type_obj.handle)
- def undefine_type(self, name):
+ def undefine_type(self, type_id):
"""
``undefine_type`` removes a :py:Class:`Type` from the global list of types for the current :py:Class:`BinaryView`
- :param str name: Name of type to be undefined
+ :param str type_id: Unique identifier of type to be undefined
:rtype: None
:Example:
>>> type, name = bv.parse_type_string("int foo")
- >>> bv.define_type(name, type)
+ >>> type_id = Type.generate_auto_type_id("source", name)
+ >>> bv.define_type(type_id, name, type)
>>> bv.get_type_by_name(name)
<type: int32_t>
- >>> bv.undefine_type(name)
+ >>> bv.undefine_type(type_id)
>>> bv.get_type_by_name(name)
>>>
"""
- core.BNUndefineAnalysisType(self.handle, name)
+ core.BNUndefineAnalysisType(self.handle, type_id)
def undefine_user_type(self, name):
"""
``undefine_user_type`` removes a :py:Class:`Type` from the global list of user types for the current
:py:Class:`BinaryView`
- :param str name: Name of user type to be undefined
+ :param QualifiedName name: Name of user type to be undefined
:rtype: None
:Example:
>>> type, name = bv.parse_type_string("int foo")
- >>> bv.define_type(name, type)
+ >>> bv.define_user_type(name, type)
>>> bv.get_type_by_name(name)
<type: int32_t>
- >>> bv.undefine_type(name)
+ >>> bv.undefine_user_type(name)
>>> bv.get_type_by_name(name)
>>>
"""
+ name = types.QualifiedName(name)._get_core_struct()
core.BNUndefineUserAnalysisType(self.handle, name)
+ def rename_type(self, old_name, new_name):
+ """
+ ``rename_type`` renames a type in the global list of types for the current :py:Class:`BinaryView`
+
+ :param QualifiedName old_name: Existing name of type to be renamed
+ :param QualifiedName new_name: New name of type to be renamed
+ :rtype: None
+ :Example:
+
+ >>> type, name = bv.parse_type_string("int foo")
+ >>> bv.define_user_type(name, type)
+ >>> bv.get_type_by_name("foo")
+ <type: int32_t>
+ >>> bv.rename_type("foo", "bar")
+ >>> bv.get_type_by_name("bar")
+ <type: int32_t>
+ >>>
+ """
+ old_name = types.QualifiedName(old_name)._get_core_struct()
+ new_name = types.QualifiedName(new_name)._get_core_struct()
+ core.BNRenameAnalysisType(self.handle, old_name, new_name)
+
+ def register_platform_types(self, platform):
+ """
+ ``register_platform_types`` ensures that the platform-specific types for a :py:Class:`Platform` are available
+ for the current :py:Class:`BinaryView`. This is automatically performed when adding a new function or setting
+ the default platform.
+
+ :param Platform platform: Platform containing types to be registered
+ :rtype: None
+ :Example:
+
+ >>> platform = Platform["linux-x86"]
+ >>> bv.register_platform_types(platform)
+ >>>
+ """
+ core.BNRegisterPlatformTypes(self.handle, platform.handle)
+
def find_next_data(self, start, data, flags = 0):
"""
``find_next_data`` searchs for the bytes in data starting at the virtual address ``start`` either, case-sensitive,
@@ -3025,6 +3164,12 @@ class BinaryView(object):
segment.flags)
return result
+ def get_address_for_data_offset(self, offset):
+ address = ctypes.c_ulonglong()
+ if not core.BNGetAddressForDataOffset(self.handle, offset, address):
+ return None
+ return address.value
+
def add_auto_section(self, name, start, length, type = "", align = 1, entry_size = 1, linked_section = "",
info_section = "", info_data = 0):
core.BNAddAutoSection(self.handle, name, start, length, type, align, entry_size, linked_section,
diff --git a/python/function.py b/python/function.py
index 9b00eec2..3aeb8e22 100644
--- a/python/function.py
+++ b/python/function.py
@@ -26,7 +26,7 @@ import ctypes
import _binaryninjacore as core
from enums import (FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType,
HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend,
- DisassemblyOption, IntegerDisplayType)
+ DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext)
import architecture
import highlight
import associateddatastore
@@ -669,7 +669,9 @@ class Function(object):
value = lines[i].tokens[j].value
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
- tokens.append(InstructionTextToken(token_type, text, value, size, operand))
+ context = lines[i].tokens[j].context
+ address = lines[i].tokens[j].address
+ tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address))
result.append(tokens)
core.BNFreeInstructionTextLines(lines, count.value)
return result
@@ -920,7 +922,9 @@ class FunctionGraphBlock(object):
value = lines[i].tokens[j].value
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
- tokens.append(InstructionTextToken(token_type, text, value, size, operand))
+ context = lines[i].tokens[j].context
+ address = lines[i].tokens[j].address
+ tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address))
result.append(DisassemblyTextLine(addr, tokens))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
@@ -970,7 +974,9 @@ class FunctionGraphBlock(object):
value = lines[i].tokens[j].value
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
- tokens.append(InstructionTextToken(token_type, text, value, size, operand))
+ context = lines[i].tokens[j].context
+ address = lines[i].tokens[j].address
+ tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address))
yield DisassemblyTextLine(addr, tokens)
finally:
core.BNFreeDisassemblyTextLines(lines, count.value)
@@ -1241,12 +1247,15 @@ class InstructionTextToken(object):
========================== ============================================
"""
- def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff):
+ def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff,
+ context = InstructionTextTokenContext.NoTokenContext, address = 0):
self.type = InstructionTextTokenType(token_type)
self.text = text
self.value = value
self.size = size
self.operand = operand
+ self.context = InstructionTextTokenContext(context)
+ self.address = address
def __str__(self):
return self.text
diff --git a/python/generator.cpp b/python/generator.cpp
index d3725b6d..1c0e7b16 100644
--- a/python/generator.cpp
+++ b/python/generator.cpp
@@ -97,17 +97,19 @@ void OutputType(FILE* out, Type* type, bool isReturnType = false, bool isCallbac
else
fprintf(out, "ctypes.c_double");
break;
- case StructureTypeClass:
- fprintf(out, "%s", type->GetQualifiedName(type->GetStructure()->GetName()).c_str());
- break;
- case EnumerationTypeClass:
- {
- string name = type->GetQualifiedName(type->GetEnumeration()->GetName());
- if (name.size() > 2 && name.substr(0, 2) == "BN")
- name = name.substr(2);
- fprintf(out, "%sEnum", name.c_str());
+ case NamedTypeReferenceClass:
+ if (type->GetNamedTypeReference()->GetTypeClass() == EnumNamedTypeClass)
+ {
+ string name = type->GetNamedTypeReference()->GetName().GetString();
+ if (name.size() > 2 && name.substr(0, 2) == "BN")
+ name = name.substr(2);
+ fprintf(out, "%sEnum", name.c_str());
+ }
+ else
+ {
+ fprintf(out, "%s", type->GetNamedTypeReference()->GetName().GetString().c_str());
+ }
break;
- }
case PointerTypeClass:
if (isCallback || (type->GetChildType()->GetClass() == VoidTypeClass))
{
@@ -161,7 +163,7 @@ int main(int argc, char* argv[])
Architecture::Register(new GeneratorArchitecture());
// Parse API header to get type and function information
- map<string, Ref<Type>> types, vars, funcs;
+ map<QualifiedName, Ref<Type>> types, vars, funcs;
string errors;
bool ok = Architecture::GetByName("generator")->ParseTypesFromSourceFile(argv[1], types, vars, funcs, errors);
fprintf(stderr, "%s", errors.c_str());
@@ -195,14 +197,17 @@ int main(int argc, char* argv[])
fprintf(out, "# Type definitions\n");
for (auto& i : types)
{
+ string name;
+ if (i.first.size() != 1)
+ continue;
+ name = i.first[0];
if (i.second->GetClass() == StructureTypeClass)
{
- fprintf(out, "class %s(ctypes.Structure):\n", i.first.c_str());
+ fprintf(out, "class %s(ctypes.Structure):\n", name.c_str());
fprintf(out, "\tpass\n");
}
else if (i.second->GetClass() == EnumerationTypeClass)
{
- string name = i.first;
if (name.size() > 2 && name.substr(0, 2) == "BN")
name = name.substr(2);
@@ -217,7 +222,7 @@ int main(int argc, char* argv[])
else if ((i.second->GetClass() == BoolTypeClass) || (i.second->GetClass() == IntegerTypeClass) ||
(i.second->GetClass() == FloatTypeClass) || (i.second->GetClass() == ArrayTypeClass))
{
- fprintf(out, "%s = ", i.first.c_str());
+ fprintf(out, "%s = ", name.c_str());
OutputType(out, i.second);
fprintf(out, "\n");
}
@@ -227,9 +232,13 @@ int main(int argc, char* argv[])
fprintf(out, "\n# Structure definitions\n");
for (auto& i : types)
{
+ string name;
+ if (i.first.size() != 1)
+ continue;
+ name = i.first[0];
if ((i.second->GetClass() == StructureTypeClass) && (i.second->GetStructure()->GetMembers().size() != 0))
{
- fprintf(out, "%s._fields_ = [\n", i.first.c_str());
+ fprintf(out, "%s._fields_ = [\n", name.c_str());
for (auto& j : i.second->GetStructure()->GetMembers())
{
fprintf(out, "\t\t(\"%s\", ", j.name.c_str());
@@ -243,6 +252,11 @@ int main(int argc, char* argv[])
fprintf(out, "\n# Function definitions\n");
for (auto& i : funcs)
{
+ string name;
+ if (i.first.size() != 1)
+ continue;
+ name = i.first[0];
+
// Check for a string result, these will be automatically wrapped to free the string
// memory and return a Python string
bool stringResult = (i.second->GetChildType()->GetClass() == PointerTypeClass) &&
@@ -251,7 +265,7 @@ int main(int argc, char* argv[])
// Pointer returns will be automatically wrapped to return None on null pointer
bool pointerResult = (i.second->GetChildType()->GetClass() == PointerTypeClass);
bool callbackConvention = false;
- if (i.first == "BNAllocString")
+ if (name == "BNAllocString")
{
// Don't perform automatic wrapping of string allocation, and return a void
// pointer so that callback functions (which is the only valid use of BNAllocString)
@@ -260,11 +274,11 @@ int main(int argc, char* argv[])
callbackConvention = true;
}
- string funcName = i.first;
+ string funcName = name;
if (stringResult || pointerResult)
funcName = string("_") + funcName;
- fprintf(out, "%s = core.%s\n", funcName.c_str(), i.first.c_str());
+ fprintf(out, "%s = core.%s\n", funcName.c_str(), name.c_str());
fprintf(out, "%s.restype = ", funcName.c_str());
OutputType(out, i.second->GetChildType(), true, callbackConvention);
fprintf(out, "\n");
@@ -274,7 +288,7 @@ int main(int argc, char* argv[])
for (auto& j : i.second->GetParameters())
{
fprintf(out, "\t\t");
- if (i.first == "BNFreeString")
+ if (name == "BNFreeString")
{
// BNFreeString expects a pointer to a string allocated by the core, so do not use
// a c_char_p here, as that would be allocated by the Python runtime. This can
@@ -293,7 +307,7 @@ int main(int argc, char* argv[])
if (stringResult)
{
// Emit wrapper to get Python string and free native memory
- fprintf(out, "def %s(*args):\n", i.first.c_str());
+ fprintf(out, "def %s(*args):\n", name.c_str());
fprintf(out, "\tresult = %s(*args)\n", funcName.c_str());
fprintf(out, "\tstring = ctypes.cast(result, ctypes.c_char_p).value\n");
fprintf(out, "\tBNFreeString(result)\n");
@@ -302,7 +316,7 @@ int main(int argc, char* argv[])
else if (pointerResult)
{
// Emit wrapper to return None on null pointer
- fprintf(out, "def %s(*args):\n", i.first.c_str());
+ fprintf(out, "def %s(*args):\n", name.c_str());
fprintf(out, "\tresult = %s(*args)\n", funcName.c_str());
fprintf(out, "\tif not result:\n");
fprintf(out, "\t\treturn None\n");
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 419e8513..29b46b65 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -187,7 +187,9 @@ class LowLevelILInstruction(object):
value = tokens[i].value
size = tokens[i].size
operand = tokens[i].operand
- result.append(function.InstructionTextToken(token_type, text, value, size, operand))
+ context = tokens[i].context
+ address = tokens[i].address
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
core.BNFreeInstructionText(tokens, count.value)
return result
diff --git a/python/platform.py b/python/platform.py
index 04dce587..ccc80476 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -25,6 +25,7 @@ import _binaryninjacore as core
import startup
import architecture
import callingconvention
+import types
class _PlatformMetaClass(type):
@@ -215,6 +216,55 @@ class Platform(object):
core.BNFreeCallingConventionList(cc, count.value)
return result
+ @property
+ def types(self):
+ """List of platform-specific types (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ type_list = core.BNGetPlatformTypes(self.handle, count)
+ result = {}
+ for i in xrange(0, count.value):
+ name = types.QualifiedName._from_core_struct(type_list[i].name)
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type))
+ core.BNFreeTypeList(type_list, count.value)
+ return result
+
+ @property
+ def variables(self):
+ """List of platform-specific variable definitions (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ type_list = core.BNGetPlatformVariables(self.handle, count)
+ result = {}
+ for i in xrange(0, count.value):
+ name = types.QualifiedName._from_core_struct(type_list[i].name)
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type))
+ core.BNFreeTypeList(type_list, count.value)
+ return result
+
+ @property
+ def functions(self):
+ """List of platform-specific function definitions (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ type_list = core.BNGetPlatformFunctions(self.handle, count)
+ result = {}
+ for i in xrange(0, count.value):
+ name = types.QualifiedName._from_core_struct(type_list[i].name)
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type))
+ core.BNFreeTypeList(type_list, count.value)
+ return result
+
+ @property
+ def system_calls(self):
+ """List of system calls for this platform (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ call_list = core.BNGetPlatformSystemCalls(self.handle, count)
+ result = {}
+ for i in xrange(0, count.value):
+ name = types.QualifiedName._from_core_struct(call_list[i].name)
+ t = types.Type(core.BNNewTypeReference(call_list[i].type))
+ result[call_list[i].number] = (name, t)
+ core.BNFreeSystemCallList(call_list, count.value)
+ return result
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
@@ -259,3 +309,44 @@ class Platform(object):
new_addr.value = addr
result = core.BNGetAssociatedPlatformByAddress(self.handle, new_addr)
return Platform(None, handle = result), new_addr.value
+
+ def get_type_by_name(self, name):
+ name = types.QualifiedName(name)._get_core_struct()
+ obj = core.BNGetPlatformTypeByName(self.handle, name)
+ if not obj:
+ return None
+ return types.Type(obj)
+
+ def get_variable_by_name(self, name):
+ name = types.QualifiedName(name)._get_core_struct()
+ obj = core.BNGetPlatformVariableByName(self.handle, name)
+ if not obj:
+ return None
+ return types.Type(obj)
+
+ def get_function_by_name(self, name):
+ name = types.QualifiedName(name)._get_core_struct()
+ obj = core.BNGetPlatformFunctionByName(self.handle, name)
+ if not obj:
+ return None
+ return types.Type(obj)
+
+ def get_system_call_name(self, number):
+ return core.BNGetPlatformSystemCallName(self.handle, number)
+
+ def get_system_call_type(self, number):
+ obj = core.BNGetPlatformSystemCallType(self.handle, number)
+ if not obj:
+ return None
+ return types.Type(obj)
+
+ def generate_auto_platform_type_id(self, name):
+ name = types.QualifiedName(name)._get_core_struct()
+ return core.BNGenerateAutoPlatformTypeId(self.handle, name)
+
+ def generate_auto_platform_type_ref(self, type_class, name):
+ type_id = self.generate_auto_platform_type_id(name)
+ return types.NamedTypeReference(type_class, type_id, name)
+
+ def get_auto_platform_type_id_source(self):
+ return core.BNGetAutoPlatformTypeIdSource(self.handle)
diff --git a/python/types.py b/python/types.py
index 62a441cd..43aaa66f 100644
--- a/python/types.py
+++ b/python/types.py
@@ -22,9 +22,92 @@ import ctypes
# Binary Ninja components
import _binaryninjacore as core
-from enums import SymbolType, TypeClass
+from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType
import callingconvention
-import demangle
+import function
+
+
+class QualifiedName(object):
+ def __init__(self, name = []):
+ if isinstance(name, str):
+ self.name = [name]
+ elif isinstance(name, QualifiedName):
+ self.name = name.name
+ else:
+ self.name = name
+
+ def __str__(self):
+ return "::".join(self.name)
+
+ def __repr__(self):
+ return repr(str(self))
+
+ def __len__(self):
+ return len(self.name)
+
+ def __hash__(self):
+ return hash(str(self))
+
+ def __eq__(self, other):
+ if isinstance(other, str):
+ return str(self) == other
+ elif isinstance(other, list):
+ return self.name == other
+ elif isinstance(other, QualifiedName):
+ return self.name == other.name
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name < other.name
+ return False
+
+ def __le__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name <= other.name
+ return False
+
+ def __gt__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name > other.name
+ return False
+
+ def __ge__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name >= other.name
+ return False
+
+ def __cmp__(self, other):
+ if self == other:
+ return 0
+ if self < other:
+ return -1
+ return 1
+
+ def __getitem__(self, key):
+ return self.name[key]
+
+ def __iter__(self):
+ return iter(self.name)
+
+ def _get_core_struct(self):
+ result = core.BNQualifiedName()
+ name_list = (ctypes.c_char_p * len(self.name))()
+ for i in xrange(0, len(self.name)):
+ name_list[i] = self.name[i]
+ result.name = name_list
+ result.nameCount = len(self.name)
+ return result
+
+ @classmethod
+ def _from_core_struct(cls, name):
+ result = []
+ for i in xrange(0, name.nameCount):
+ result.append(name.name[i])
+ return QualifiedName(result)
class Symbol(object):
@@ -210,6 +293,14 @@ class Type(object):
return None
return Enumeration(result)
+ @property
+ def named_type_reference(self):
+ """Reference to a named type (read-only)"""
+ result = core.BNGetTypeNamedTypeReference(self.handle)
+ if result is None:
+ return None
+ return NamedTypeReference(handle = result)
+
@property
def count(self):
"""Type count (read-only)"""
@@ -227,6 +318,56 @@ class Type(object):
def get_string_after_name(self):
return core.BNGetTypeStringAfterName(self.handle)
+ @property
+ def tokens(self):
+ """Type string as a list of tokens (read-only)"""
+ count = ctypes.c_ulonglong()
+ tokens = core.BNGetTypeTokens(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ token_type = InstructionTextTokenType(tokens[i].type)
+ text = tokens[i].text
+ value = tokens[i].value
+ size = tokens[i].size
+ operand = tokens[i].operand
+ context = tokens[i].context
+ address = tokens[i].address
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ core.BNFreeTokenList(tokens, count.value)
+ return result
+
+ def get_tokens_before_name(self):
+ count = ctypes.c_ulonglong()
+ tokens = core.BNGetTypeTokensBeforeName(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ token_type = InstructionTextTokenType(tokens[i].type)
+ text = tokens[i].text
+ value = tokens[i].value
+ size = tokens[i].size
+ operand = tokens[i].operand
+ context = tokens[i].context
+ address = tokens[i].address
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ core.BNFreeTokenList(tokens, count.value)
+ return result
+
+ def get_tokens_after_name(self):
+ count = ctypes.c_ulonglong()
+ tokens = core.BNGetTypeTokensAfterName(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ token_type = InstructionTextTokenType(tokens[i].type)
+ text = tokens[i].text
+ value = tokens[i].value
+ size = tokens[i].size
+ operand = tokens[i].operand
+ context = tokens[i].context
+ address = tokens[i].address
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ core.BNFreeTokenList(tokens, count.value)
+ return result
+
@classmethod
def void(cls):
return Type(core.BNCreateVoidType())
@@ -254,8 +395,27 @@ class Type(object):
return Type(core.BNCreateStructureType(structure_type.handle))
@classmethod
- def unknown_type(self, unknown_type):
- return Type(core.BNCreateUnknownType(unknown_type.handle))
+ def named_type(self, named_type, width = 0, align = 1):
+ return Type(core.BNCreateNamedTypeReference(named_type.handle, width, align))
+
+ @classmethod
+ def named_type_from_type_and_id(self, type_id, name, t):
+ name = QualifiedName(name)._get_core_struct()
+ if t is not None:
+ t = t.handle
+ return Type(core.BNCreateNamedTypeReferenceFromTypeAndId(type_id, name, t))
+
+ @classmethod
+ def named_type_from_type(self, name, t):
+ name = QualifiedName(name)._get_core_struct()
+ if t is not None:
+ t = t.handle
+ return Type(core.BNCreateNamedTypeReferenceFromTypeAndId("", name, t))
+
+ @classmethod
+ def named_type_from_registered_type(self, view, name):
+ name = QualifiedName(name)._get_core_struct()
+ return Type(core.BNCreateNamedTypeReferenceFromType(view.handle, name))
@classmethod
def enumeration_type(self, arch, e, width=None):
@@ -294,6 +454,20 @@ class Type(object):
return Type(core.BNCreateFunctionType(ret.handle, calling_convention, param_buf, len(params),
variable_arguments))
+ @classmethod
+ def generate_auto_type_id(self, source, name):
+ name = QualifiedName(name)._get_core_struct()
+ return core.BNGenerateAutoTypeId(source, name)
+
+ @classmethod
+ def generate_auto_demangled_type_id(self, name):
+ name = QualifiedName(name)._get_core_struct()
+ return core.BNGenerateAutoDemangledTypeId(name)
+
+ @classmethod
+ def get_auto_demanged_type_id_source(self):
+ return core.BNGetAutoDemangledTypeIdSource()
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
@@ -301,28 +475,70 @@ class Type(object):
raise AttributeError("attribute '%s' is read only" % name)
-class UnknownType(object):
- def __init__(self, handle=None):
+class NamedTypeReference(object):
+ def __init__(self, type_class = NamedTypeReferenceClass.UnknownNamedTypeClass, type_id = None, name = None, handle = None):
if handle is None:
- self.handle = core.BNCreateUnknownType()
+ self.handle = core.BNCreateNamedType()
+ core.BNSetTypeReferenceClass(self.handle, type_class)
+ if type_id is not None:
+ core.BNSetTypeReferenceId(self.handle, type_id)
+ if name is not None:
+ name = QualifiedName(name)._get_core_struct()
+ core.BNSetTypeReferenceName(self.handle, name)
else:
self.handle = handle
def __del__(self):
- core.BNFreeUnknownType(self.handle)
+ core.BNFreeNamedTypeReference(self.handle)
+
+ @property
+ def type_class(self):
+ return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.handle))
+
+ @type_class.setter
+ def type_class(self, value):
+ core.BNSetTypeReferenceClass(self.handle, value)
+
+ @property
+ def type_id(self):
+ return core.BNGetTypeReferenceId(self.handle)
+
+ @type_id.setter
+ def type_id(self, value):
+ core.BNSetTypeReferenceId(self.handle, value)
@property
def name(self):
- count = ctypes.c_ulonglong()
- nameList = core.BNGetUnknownTypeName(self.handle, count)
- result = []
- for i in xrange(count.value):
- result.append(nameList[i])
- return demangle.get_qualified_name(result)
+ name = core.BNGetTypeReferenceName(self.handle)
+ result = QualifiedName._from_core_struct(name)
+ core.BNFreeQualifiedName(name)
+ return result
@name.setter
def name(self, value):
- core.BNSetUnknownTypeName(self.handle, value)
+ value = QualifiedName(value)._get_core_struct()
+ core.BNSetTypeReferenceName(self.handle, value)
+
+ def __repr__(self):
+ if self.type_class == NamedTypeReferenceClass.TypedefNamedTypeClass:
+ return "<named type: typedef %s>" % str(self.name)
+ if self.type_class == NamedTypeReferenceClass.StructNamedTypeClass:
+ return "<named type: struct %s>" % str(self.name)
+ if self.type_class == NamedTypeReferenceClass.UnionNamedTypeClass:
+ return "<named type: union %s>" % str(self.name)
+ if self.type_class == NamedTypeReferenceClass.EnumNamedTypeClass:
+ return "<named type: enum %s>" % str(self.name)
+ return "<named type: unknown %s>" % str(self.name)
+
+ @classmethod
+ def generate_auto_type_ref(self, type_class, source, name):
+ type_id = Type.generate_auto_type_id(source, name)
+ return NamedTypeReference(type_class, type_id, name)
+
+ @classmethod
+ def generate_auto_demangled_type_ref(self, type_class, name):
+ type_id = Type.generate_auto_demangled_type_id(name)
+ return NamedTypeReference(type_class, type_id, name)
class StructureMember(object):
@@ -349,19 +565,6 @@ class Structure(object):
core.BNFreeStructure(self.handle)
@property
- def name(self):
- count = ctypes.c_ulonglong()
- nameList = core.BNGetStructureName(self.handle, count)
- result = []
- for i in xrange(count.value):
- result.append(nameList[i])
- return demangle.get_qualified_name(result)
-
- @name.setter
- def name(self, value):
- core.BNSetStructureName(self.handle, value)
-
- @property
def members(self):
"""Structure member list (read-only)"""
count = ctypes.c_ulonglong()
@@ -375,14 +578,22 @@ class Structure(object):
@property
def width(self):
- """Structure width (read-only)"""
+ """Structure width"""
return core.BNGetStructureWidth(self.handle)
+ @width.setter
+ def width(self, new_width):
+ core.BNSetStructureWidth(self.handle, new_width)
+
@property
def alignment(self):
- """Structure alignment (read-only)"""
+ """Structure alignment"""
return core.BNGetStructureAlignment(self.handle)
+ @alignment.setter
+ def alignment(self, align):
+ core.BNSetStructureAlignment(self.handle, align)
+
@property
def packed(self):
return core.BNIsStructurePacked(self.handle)
@@ -406,8 +617,6 @@ class Structure(object):
raise AttributeError("attribute '%s' is read only" % name)
def __repr__(self):
- if len(self.name) > 0:
- return "<struct: %s>" % self.name
return "<struct: size %#x>" % self.width
def append(self, t, name = ""):
@@ -419,6 +628,9 @@ class Structure(object):
def remove(self, i):
core.BNRemoveStructureMember(self.handle, i)
+ def replace(self, i, t, name = ""):
+ core.BNReplaceStructureMember(self.handle, i, t.handle, name)
+
class EnumerationMember(object):
def __init__(self, name, value, default):
@@ -441,14 +653,6 @@ class Enumeration(object):
core.BNFreeEnumeration(self.handle)
@property
- def name(self):
- return core.BNGetEnumerationName(self.handle)
-
- @name.setter
- def name(self, value):
- core.BNSetEnumerationName(self.handle, value)
-
- @property
def members(self):
"""Enumeration member list (read-only)"""
count = ctypes.c_ulonglong()
@@ -466,8 +670,6 @@ class Enumeration(object):
raise AttributeError("attribute '%s' is read only" % name)
def __repr__(self):
- if len(self.name) > 0:
- return "<enum: %s>" % self.name
return "<enum: %s>" % repr(self.members)
def append(self, name, value = None):
@@ -476,6 +678,12 @@ class Enumeration(object):
else:
core.BNAddEnumerationMemberWithValue(self.handle, name, value)
+ def remove(self, i):
+ core.BNRemoveEnumerationMember(self.handle, i)
+
+ def replace(self, i, name, value):
+ core.BNReplaceEnumerationMember(self.handle, i, name, value)
+
class TypeParserResult(object):
def __init__(self, types, variables, functions):
diff --git a/type.cpp b/type.cpp
index e0235664..66138001 100644
--- a/type.cpp
+++ b/type.cpp
@@ -24,6 +24,219 @@ using namespace BinaryNinja;
using namespace std;
+QualifiedName::QualifiedName()
+{
+}
+
+
+QualifiedName::QualifiedName(const string& name)
+{
+ m_name.push_back(name);
+}
+
+
+QualifiedName::QualifiedName(const vector<string>& name): m_name(name)
+{
+}
+
+
+QualifiedName::QualifiedName(const QualifiedName& name): m_name(name.m_name)
+{
+}
+
+
+QualifiedName& QualifiedName::operator=(const string& name)
+{
+ m_name = vector<string>{name};
+ return *this;
+}
+
+
+QualifiedName& QualifiedName::operator=(const vector<string>& name)
+{
+ m_name = name;
+ return *this;
+}
+
+
+QualifiedName& QualifiedName::operator=(const QualifiedName& name)
+{
+ m_name = name.m_name;
+ return *this;
+}
+
+
+bool QualifiedName::operator==(const QualifiedName& other) const
+{
+ return m_name == other.m_name;
+}
+
+
+bool QualifiedName::operator!=(const QualifiedName& other) const
+{
+ return m_name != other.m_name;
+}
+
+
+bool QualifiedName::operator<(const QualifiedName& other) const
+{
+ return m_name < other.m_name;
+}
+
+
+QualifiedName QualifiedName::operator+(const QualifiedName& other) const
+{
+ QualifiedName result(*this);
+ result.m_name.insert(result.m_name.end(), other.m_name.begin(), other.m_name.end());
+ return result;
+}
+
+
+string& QualifiedName::operator[](size_t i)
+{
+ return m_name[i];
+}
+
+
+const string& QualifiedName::operator[](size_t i) const
+{
+ return m_name[i];
+}
+
+
+vector<string>::iterator QualifiedName::begin()
+{
+ return m_name.begin();
+}
+
+
+vector<string>::iterator QualifiedName::end()
+{
+ return m_name.end();
+}
+
+
+vector<string>::const_iterator QualifiedName::begin() const
+{
+ return m_name.begin();
+}
+
+
+vector<string>::const_iterator QualifiedName::end() const
+{
+ return m_name.end();
+}
+
+
+string& QualifiedName::front()
+{
+ return m_name.front();
+}
+
+
+const string& QualifiedName::front() const
+{
+ return m_name.front();
+}
+
+
+string& QualifiedName::back()
+{
+ return m_name.back();
+}
+
+
+const string& QualifiedName::back() const
+{
+ return m_name.back();
+}
+
+
+void QualifiedName::insert(vector<string>::iterator loc, const string& name)
+{
+ m_name.insert(loc, name);
+}
+
+
+void QualifiedName::insert(vector<string>::iterator loc, vector<string>::iterator b, vector<string>::iterator e)
+{
+ m_name.insert(loc, b, e);
+}
+
+
+void QualifiedName::erase(vector<string>::iterator i)
+{
+ m_name.erase(i);
+}
+
+
+void QualifiedName::clear()
+{
+ m_name.clear();
+}
+
+
+void QualifiedName::push_back(const string& name)
+{
+ m_name.push_back(name);
+}
+
+
+size_t QualifiedName::size() const
+{
+ return m_name.size();
+}
+
+
+string QualifiedName::GetString() const
+{
+ bool first = true;
+ string out;
+ for (auto &name : m_name)
+ {
+ if (!first)
+ {
+ out += "::" + name;
+ }
+ else
+ {
+ out += name;
+ }
+ if (name.length() != 0)
+ first = false;
+ }
+ return out;
+}
+
+
+BNQualifiedName QualifiedName::GetAPIObject() const
+{
+ BNQualifiedName result;
+ result.nameCount = m_name.size();
+ result.name = new char*[m_name.size()];
+ for (size_t i = 0; i < m_name.size(); i++)
+ result.name[i] = BNAllocString(m_name[i].c_str());
+ return result;
+}
+
+
+void QualifiedName::FreeAPIObject(BNQualifiedName* name)
+{
+ for (size_t i = 0; i < name->nameCount; i++)
+ BNFreeString(name->name[i]);
+ delete[] name->name;
+}
+
+
+QualifiedName QualifiedName::FromAPIObject(BNQualifiedName* name)
+{
+ QualifiedName result;
+ for (size_t i = 0; i < name->nameCount; i++)
+ result.push_back(name->name[i]);
+ return result;
+}
+
+
Type::Type(BNType* type)
{
m_object = type;
@@ -133,30 +346,18 @@ Ref<Enumeration> Type::GetEnumeration() const
}
-uint64_t Type::GetElementCount() const
+Ref<NamedTypeReference> Type::GetNamedTypeReference() const
{
- return BNGetTypeElementCount(m_object);
+ BNNamedTypeReference* ref = BNGetTypeNamedTypeReference(m_object);
+ if (ref)
+ return new NamedTypeReference(ref);
+ return nullptr;
}
-string Type::GetQualifiedName(const vector<string>& names)
+uint64_t Type::GetElementCount() const
{
- bool first = true;
- string out;
- for (auto &name : names)
- {
- if (!first)
- {
- out += "::" + name;
- }
- else
- {
- out += name;
- }
- if (name.length() != 0)
- first = false;
- }
- return out;
+ return BNGetTypeElementCount(m_object);
}
@@ -169,15 +370,11 @@ string Type::GetString() const
}
-string Type::GetTypeAndName(const vector<string>& nameList) const
+string Type::GetTypeAndName(const QualifiedName& nameList) const
{
- const char ** str = new const char*[nameList.size()];
- for (size_t i = 0; i < nameList.size(); i++)
- {
- str[i] = nameList[i].c_str();
- }
- char* outName = BNGetTypeAndName(m_object, str, nameList.size());
- delete [] str;
+ BNQualifiedName name = nameList.GetAPIObject();
+ char* outName = BNGetTypeAndName(m_object, &name);
+ QualifiedName::FreeAPIObject(&name);
return outName;
}
@@ -199,6 +396,78 @@ string Type::GetStringAfterName() const
}
+vector<InstructionTextToken> Type::GetTokens() const
+{
+ size_t count;
+ BNInstructionTextToken* tokens = BNGetTypeTokens(m_object, &count);
+
+ vector<InstructionTextToken> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ InstructionTextToken token;
+ token.type = tokens[i].type;
+ token.text = tokens[i].text;
+ token.value = tokens[i].value;
+ token.size = tokens[i].size;
+ token.operand = tokens[i].operand;
+ token.context = tokens[i].context;
+ token.address = tokens[i].address;
+ result.push_back(token);
+ }
+
+ BNFreeTokenList(tokens, count);
+ return result;
+}
+
+
+vector<InstructionTextToken> Type::GetTokensBeforeName() const
+{
+ size_t count;
+ BNInstructionTextToken* tokens = BNGetTypeTokensBeforeName(m_object, &count);
+
+ vector<InstructionTextToken> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ InstructionTextToken token;
+ token.type = tokens[i].type;
+ token.text = tokens[i].text;
+ token.value = tokens[i].value;
+ token.size = tokens[i].size;
+ token.operand = tokens[i].operand;
+ token.context = tokens[i].context;
+ token.address = tokens[i].address;
+ result.push_back(token);
+ }
+
+ BNFreeTokenList(tokens, count);
+ return result;
+}
+
+
+vector<InstructionTextToken> Type::GetTokensAfterName() const
+{
+ size_t count;
+ BNInstructionTextToken* tokens = BNGetTypeTokensAfterName(m_object, &count);
+
+ vector<InstructionTextToken> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ InstructionTextToken token;
+ token.type = tokens[i].type;
+ token.text = tokens[i].text;
+ token.value = tokens[i].value;
+ token.size = tokens[i].size;
+ token.operand = tokens[i].operand;
+ token.context = tokens[i].context;
+ token.address = tokens[i].address;
+ result.push_back(token);
+ }
+
+ BNFreeTokenList(tokens, count);
+ return result;
+}
+
+
Ref<Type> Type::Duplicate() const
{
return new Type(BNDuplicateType(m_object));
@@ -235,9 +504,34 @@ Ref<Type> Type::StructureType(Structure* strct)
}
-Ref<Type> Type::UnknownNamedType(UnknownType* unknwn)
+Ref<Type> Type::NamedType(NamedTypeReference* ref, size_t width, size_t align)
{
- return new Type(BNCreateUnknownNamedType(unknwn->GetObject()));
+ return new Type(BNCreateNamedTypeReference(ref->GetObject(), width, align));
+}
+
+
+Ref<Type> Type::NamedType(const QualifiedName& name, Type* type)
+{
+ return NamedType("", name, type);
+}
+
+
+Ref<Type> Type::NamedType(const string& id, const QualifiedName& name, Type* type)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ Type* result = new Type(BNCreateNamedTypeReferenceFromTypeAndId(id.c_str(), &nameObj,
+ type ? type->GetObject() : nullptr));
+ QualifiedName::FreeAPIObject(&nameObj);
+ return result;
+}
+
+
+Ref<Type> Type::NamedType(BinaryView* view, const QualifiedName& name)
+{
+ BNQualifiedName nameObj = name.GetAPIObject();
+ Type* result = new Type(BNCreateNamedTypeReferenceFromType(view->GetObject(), &nameObj));
+ QualifiedName::FreeAPIObject(&nameObj);
+ return result;
}
@@ -283,76 +577,129 @@ void Type::SetFunctionCanReturn(bool canReturn)
}
-UnknownType::UnknownType(BNUnknownType* ut, vector<string> names)
+string Type::GenerateAutoTypeId(const string& source, const QualifiedName& name)
{
- m_object = ut;
- const char ** nameList = new const char*[names.size()];
- for (size_t i = 0; i < names.size(); i++)
- {
- nameList[i] = names[i].c_str();
- }
- BNSetUnknownTypeName(ut, nameList, names.size());
- delete [] nameList;
+ BNQualifiedName nameObj = name.GetAPIObject();
+ char* str = BNGenerateAutoTypeId(source.c_str(), &nameObj);
+ string result = str;
+ QualifiedName::FreeAPIObject(&nameObj);
+ BNFreeString(str);
+ return result;
}
-void UnknownType::SetName(const vector<string>& names)
+string Type::GenerateAutoDemangledTypeId(const QualifiedName& name)
{
- const char ** nameList = new const char*[names.size()];
- for (size_t i = 0; i < names.size(); i++)
- {
- nameList[i] = names[i].c_str();
- }
- BNSetUnknownTypeName(m_object, nameList, names.size());
- delete [] nameList;
+ BNQualifiedName nameObj = name.GetAPIObject();
+ char* str = BNGenerateAutoDemangledTypeId(&nameObj);
+ string result = str;
+ QualifiedName::FreeAPIObject(&nameObj);
+ BNFreeString(str);
+ return result;
}
-vector<string> UnknownType::GetName() const
+string Type::GetAutoDemangledTypeIdSource()
{
- size_t size;
- char** name = BNGetUnknownTypeName(m_object, &size);
- vector<string> result;
- for (size_t i = 0; i < size; i++)
- {
- result.push_back(name[i]);
- BNFreeString(name[i]);
- }
- delete [] name;
+ char* str = BNGetAutoDemangledTypeIdSource();
+ string result = str;
+ BNFreeString(str);
return result;
}
-Structure::Structure(BNStructure* s)
+NamedTypeReference::NamedTypeReference(BNNamedTypeReference* nt)
{
- m_object = s;
+ m_object = nt;
}
-vector<string> Structure::GetName() const
+NamedTypeReference::NamedTypeReference(BNNamedTypeReferenceClass cls, const string& id, const QualifiedName& names)
{
- size_t size;
- char** name = BNGetStructureName(m_object, &size);
- vector<string> result;
- for (size_t i = 0; i < size; i++)
+ m_object = BNCreateNamedType();
+ BNSetTypeReferenceClass(m_object, cls);
+ if (id.size() != 0)
{
- result.push_back(name[i]);
- BNFreeString(name[i]);
+ BNSetTypeReferenceId(m_object, id.c_str());
}
- delete [] name;
+ if (names.size() != 0)
+ {
+ BNQualifiedName nameObj = names.GetAPIObject();
+ BNSetTypeReferenceName(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+ }
+}
+
+
+void NamedTypeReference::SetTypeClass(BNNamedTypeReferenceClass cls)
+{
+ BNSetTypeReferenceClass(m_object, cls);
+}
+
+
+BNNamedTypeReferenceClass NamedTypeReference::GetTypeClass() const
+{
+ return BNGetTypeReferenceClass(m_object);
+}
+
+
+string NamedTypeReference::GetTypeId() const
+{
+ char* str = BNGetTypeReferenceId(m_object);
+ string result = str;
+ BNFreeString(str);
return result;
}
-void Structure::SetName(const vector<string>& names)
+void NamedTypeReference::SetTypeId(const string& id)
{
- const char ** nameList = new const char*[names.size()];
- for (size_t i = 0; i < names.size(); i++)
- {
- nameList[i] = names[i].c_str();
- }
- BNSetStructureName(m_object, nameList, names.size());
- delete [] nameList;
+ BNSetTypeReferenceId(m_object, id.c_str());
+}
+
+
+void NamedTypeReference::SetName(const QualifiedName& names)
+{
+ BNQualifiedName nameObj = names.GetAPIObject();
+ BNSetTypeReferenceName(m_object, &nameObj);
+ QualifiedName::FreeAPIObject(&nameObj);
+}
+
+
+QualifiedName NamedTypeReference::GetName() const
+{
+ BNQualifiedName name = BNGetTypeReferenceName(m_object);
+ QualifiedName result = QualifiedName::FromAPIObject(&name);
+ BNFreeQualifiedName(&name);
+ return result;
+}
+
+
+Ref<NamedTypeReference> NamedTypeReference::GenerateAutoTypeReference(BNNamedTypeReferenceClass cls,
+ const string& source, const QualifiedName& name)
+{
+ string id = Type::GenerateAutoTypeId(source, name);
+ return new NamedTypeReference(cls, id, name);
+}
+
+
+Ref<NamedTypeReference> NamedTypeReference::GenerateAutoDemangledTypeReference(BNNamedTypeReferenceClass cls,
+ const QualifiedName& name)
+{
+ string id = Type::GenerateAutoDemangledTypeId(name);
+ return new NamedTypeReference(cls, id, name);
+}
+
+
+Structure::Structure()
+{
+ m_object = BNCreateStructure();
+}
+
+
+Structure::Structure(BNStructure* s)
+{
+ m_object = s;
}
@@ -382,12 +729,24 @@ uint64_t Structure::GetWidth() const
}
+void Structure::SetWidth(size_t width)
+{
+ BNSetStructureWidth(m_object, width);
+}
+
+
size_t Structure::GetAlignment() const
{
return BNGetStructureAlignment(m_object);
}
+void Structure::SetAlignment(size_t align)
+{
+ BNSetStructureAlignment(m_object, align);
+}
+
+
bool Structure::IsPacked() const
{
return BNIsStructurePacked(m_object);
@@ -430,35 +789,15 @@ void Structure::RemoveMember(size_t idx)
}
-Enumeration::Enumeration(BNEnumeration* e)
+void Structure::ReplaceMember(size_t idx, Type* type, const std::string& name)
{
- m_object = e;
+ BNReplaceStructureMember(m_object, idx, type->GetObject(), name.c_str());
}
-vector<string> Enumeration::GetName() const
-{
- vector<string> result;
- size_t size;
- char** name = BNGetEnumerationName(m_object, &size);
- for (size_t i = 0; i < size; i++)
- {
- result.push_back(name[i]);
- BNFreeString(name[i]);
- }
- delete [] name;
- return result;
-}
-
-void Enumeration::SetName(const vector<string>& names)
+Enumeration::Enumeration(BNEnumeration* e)
{
- const char **const nameList = new const char*[names.size()];
- for (size_t i = 0; i < names.size(); i++)
- {
- nameList[i] = names[i].c_str();
- }
- BNSetEnumerationName(m_object, nameList, names.size());
- delete [] nameList;
+ m_object = e;
}
@@ -494,6 +833,18 @@ void Enumeration::AddMemberWithValue(const string& name, uint64_t value)
}
+void Enumeration::RemoveMember(size_t idx)
+{
+ BNRemoveEnumerationMember(m_object, idx);
+}
+
+
+void Enumeration::ReplaceMember(size_t idx, const string& name, uint64_t value)
+{
+ BNReplaceEnumerationMember(m_object, idx, name.c_str(), value);
+}
+
+
bool BinaryNinja::PreprocessSource(const string& source, const string& fileName, string& output, string& errors,
const vector<string>& includeDirs)
{