summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp85
-rw-r--r--binaryninjaapi.h81
-rw-r--r--binaryninjacore.h30
-rw-r--r--platform.cpp85
-rw-r--r--python/architecture.py93
-rw-r--r--python/binaryview.py22
-rw-r--r--python/function.py15
-rw-r--r--python/generator.cpp63
-rw-r--r--python/mediumlevelil.py5
-rw-r--r--python/platform.py109
-rw-r--r--python/types.py90
-rw-r--r--type.cpp47
12 files changed, 423 insertions, 302 deletions
diff --git a/architecture.cpp b/architecture.cpp
index 8fd38de2..eb588394 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -787,91 +787,6 @@ void Architecture::SetBinaryViewTypeConstant(const string& type, const string& n
}
-bool Architecture::ParseTypesFromSource(const string& source, 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;
- const char** includeDirList = new const char*[includeDirs.size()];
-
- for (size_t i = 0; i < includeDirs.size(); i++)
- includeDirList[i] = includeDirs[i].c_str();
-
- types.clear();
- variables.clear();
- functions.clear();
-
- bool ok = BNParseTypesFromSource(m_object, source.c_str(), fileName.c_str(), &result,
- &errorStr, includeDirList, includeDirs.size(), autoTypeSource.c_str());
- errors = errorStr;
- BNFreeString(errorStr);
- if (!ok)
- return false;
-
- for (size_t i = 0; i < result.typeCount; i++)
- {
- 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++)
- {
- 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++)
- {
- 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<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;
- const char** includeDirList = new const char*[includeDirs.size()];
-
- for (size_t i = 0; i < includeDirs.size(); i++)
- includeDirList[i] = includeDirs[i].c_str();
-
- types.clear();
- variables.clear();
- functions.clear();
-
- bool ok = BNParseTypesFromSourceFile(m_object, fileName.c_str(), &result, &errorStr,
- includeDirList, includeDirs.size(), autoTypeSource.c_str());
- errors = errorStr;
- BNFreeString(errorStr);
- if (!ok)
- return false;
-
- for (size_t i = 0; i < result.typeCount; i++)
- {
- 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++)
- {
- 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++)
- {
- QualifiedName name = QualifiedName::FromAPIObject(&result.functions[i].name);
- functions[name] = new Type(BNNewTypeReference(result.functions[i].type));
- }
- BNFreeTypeParserResult(&result);
- return true;
-}
-
-
void Architecture::RegisterCallingConvention(CallingConvention* cc)
{
BNRegisterCallingConvention(m_object, cc->GetObject());
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 63cab888..8213675d 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1743,19 +1743,6 @@ namespace BinaryNinja
uint64_t defaultValue = 0);
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<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();
Ref<CallingConvention> GetCallingConventionByName(const std::string& name);
@@ -1821,10 +1808,28 @@ namespace BinaryNinja
class NamedTypeReference;
class Enumeration;
- struct NameAndType
+ struct Variable: public BNVariable
+ {
+ Variable();
+ Variable(BNVariableSourceType type, uint32_t index, uint64_t storage);
+ Variable(const BNVariable& var);
+
+ Variable& operator=(const Variable& var);
+
+ bool operator==(const Variable& var) const;
+ bool operator!=(const Variable& var) const;
+ bool operator<(const Variable& var) const;
+
+ uint64_t ToIdentifier() const;
+ static Variable FromIdentifier(uint64_t id);
+ };
+
+ struct FunctionParameter
{
std::string name;
Confidence<Ref<Type>> type;
+ bool defaultLocation;
+ Variable location;
};
struct QualifiedNameAndType
@@ -1848,7 +1853,7 @@ namespace BinaryNinja
bool IsFloat() const;
Confidence<Ref<Type>> GetChildType() const;
Confidence<Ref<CallingConvention>> GetCallingConvention() const;
- std::vector<NameAndType> GetParameters() const;
+ std::vector<FunctionParameter> GetParameters() const;
Confidence<bool> HasVariableArguments() const;
Confidence<bool> CanReturn() const;
Ref<Structure> GetStructure() const;
@@ -1867,14 +1872,17 @@ namespace BinaryNinja
void SetFunctionCanReturn(const Confidence<bool>& canReturn);
- std::string GetString() const;
+ std::string GetString(Platform* platform = nullptr) const;
std::string GetTypeAndName(const QualifiedName& name) const;
- std::string GetStringBeforeName() const;
- std::string GetStringAfterName() const;
+ std::string GetStringBeforeName(Platform* platform = nullptr) const;
+ std::string GetStringAfterName(Platform* platform = nullptr) const;
- std::vector<InstructionTextToken> GetTokens() const;
- std::vector<InstructionTextToken> GetTokensBeforeName() const;
- std::vector<InstructionTextToken> GetTokensAfterName() const;
+ std::vector<InstructionTextToken> GetTokens(Platform* platform = nullptr,
+ uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
+ std::vector<InstructionTextToken> GetTokensBeforeName(Platform* platform = nullptr,
+ uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
+ std::vector<InstructionTextToken> GetTokensAfterName(Platform* platform = nullptr,
+ uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
Ref<Type> Duplicate() const;
@@ -1897,7 +1905,7 @@ namespace BinaryNinja
static Ref<Type> ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem);
static Ref<Type> FunctionType(const Confidence<Ref<Type>>& returnValue,
const Confidence<Ref<CallingConvention>>& callingConvention,
- const std::vector<NameAndType>& params, const Confidence<bool>& varArg = Confidence<bool>(false, 0));
+ const std::vector<FunctionParameter>& params, const Confidence<bool>& varArg = Confidence<bool>(false, 0));
static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name);
static std::string GenerateAutoDemangledTypeId(const QualifiedName& name);
@@ -2052,22 +2060,6 @@ namespace BinaryNinja
static bool IsBackEdge(BasicBlock* source, BasicBlock* target);
};
- struct Variable: public BNVariable
- {
- Variable();
- Variable(BNVariableSourceType type, uint32_t index, uint64_t storage);
- Variable(const BNVariable& var);
-
- Variable& operator=(const Variable& var);
-
- bool operator==(const Variable& var) const;
- bool operator!=(const Variable& var) const;
- bool operator<(const Variable& var) const;
-
- uint64_t ToIdentifier() const;
- static Variable FromIdentifier(uint64_t id);
- };
-
struct VariableNameAndType
{
Variable var;
@@ -3178,6 +3170,19 @@ namespace BinaryNinja
Ref<NamedTypeReference> GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls,
const QualifiedName& name);
std::string GetAutoPlatformTypeIdSource();
+
+ bool ParseTypesFromSource(const std::string& source, 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 = "");
+ 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 = "");
};
class ScriptingOutputListener
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 6b5d5acc..3c8757ed 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1132,11 +1132,13 @@ extern "C"
uint8_t confidence;
};
- struct BNNameAndType
+ struct BNFunctionParameter
{
char* name;
BNType* type;
uint8_t typeConfidence;
+ bool defaultLocation;
+ BNVariable location;
};
struct BNQualifiedNameAndType
@@ -2197,7 +2199,6 @@ extern "C"
BINARYNINJACOREAPI bool BNParseTypeString(BNBinaryView* view, const char* text,
BNQualifiedNameAndType* result, char** errors);
- BINARYNINJACOREAPI void BNFreeNameAndType(BNNameAndType* obj);
BINARYNINJACOREAPI void BNFreeQualifiedNameAndType(BNQualifiedNameAndType* obj);
BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count);
@@ -2602,7 +2603,7 @@ extern "C"
BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType);
BINARYNINJACOREAPI BNType* BNCreateArrayType(BNTypeWithConfidence* type, uint64_t elem);
BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNTypeWithConfidence* returnValue,
- BNCallingConventionWithConfidence* callingConvention, BNNameAndType* params,
+ BNCallingConventionWithConfidence* callingConvention, BNFunctionParameter* params,
size_t paramCount, BNBoolWithConfidence* varArg);
BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type);
BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type);
@@ -2620,8 +2621,8 @@ extern "C"
BINARYNINJACOREAPI bool BNIsTypeFloatingPoint(BNType* type);
BINARYNINJACOREAPI BNTypeWithConfidence BNGetChildType(BNType* type);
BINARYNINJACOREAPI BNCallingConventionWithConfidence BNGetTypeCallingConvention(BNType* type);
- BINARYNINJACOREAPI BNNameAndType* BNGetTypeParameters(BNType* type, size_t* count);
- BINARYNINJACOREAPI void BNFreeTypeParameterList(BNNameAndType* types, size_t count);
+ BINARYNINJACOREAPI BNFunctionParameter* BNGetTypeParameters(BNType* type, size_t* count);
+ BINARYNINJACOREAPI void BNFreeTypeParameterList(BNFunctionParameter* types, size_t count);
BINARYNINJACOREAPI BNBoolWithConfidence BNTypeHasVariableArguments(BNType* type);
BINARYNINJACOREAPI BNBoolWithConfidence BNFunctionTypeCanReturn(BNType* type);
BINARYNINJACOREAPI BNStructure* BNGetTypeStructure(BNType* type);
@@ -2637,12 +2638,15 @@ extern "C"
BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, BNBoolWithConfidence* cnst);
BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, BNBoolWithConfidence* vltl);
- 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 char* BNGetTypeString(BNType* type, BNPlatform* platform);
+ BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform);
+ BINARYNINJACOREAPI char* BNGetTypeStringAfterName(BNType* type, BNPlatform* platform);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokens(BNType* type, BNPlatform* platform,
+ uint8_t baseConfidence, size_t* count);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensBeforeName(BNType* type, BNPlatform* platform,
+ uint8_t baseConfidence, size_t* count);
+ BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensAfterName(BNType* type, BNPlatform* platform,
+ uint8_t baseConfidence, size_t* count);
BINARYNINJACOREAPI void BNFreeTokenList(BNInstructionTextToken* tokens, size_t count);
BINARYNINJACOREAPI BNType* BNCreateNamedTypeReference(BNNamedTypeReference* nt, size_t width, size_t align);
@@ -2698,10 +2702,10 @@ extern "C"
// Source code processing
BINARYNINJACOREAPI bool BNPreprocessSource(const char* source, const char* fileName, char** output, char** errors,
const char** includeDirs, size_t includeDirCount);
- BINARYNINJACOREAPI bool BNParseTypesFromSource(BNArchitecture* arch, const char* source, const char* fileName,
+ BINARYNINJACOREAPI bool BNParseTypesFromSource(BNPlatform* platform, const char* source, const char* fileName,
BNTypeParserResult* result, char** errors, const char** includeDirs, size_t includeDirCount,
const char* autoTypeSource);
- BINARYNINJACOREAPI bool BNParseTypesFromSourceFile(BNArchitecture* arch, const char* fileName,
+ BINARYNINJACOREAPI bool BNParseTypesFromSourceFile(BNPlatform* platform, const char* fileName,
BNTypeParserResult* result, char** errors, const char** includeDirs, size_t includeDirCount,
const char* autoTypeSource);
BINARYNINJACOREAPI void BNFreeTypeParserResult(BNTypeParserResult* result);
diff --git a/platform.cpp b/platform.cpp
index 2a095da2..a9ab888f 100644
--- a/platform.cpp
+++ b/platform.cpp
@@ -402,3 +402,88 @@ string Platform::GetAutoPlatformTypeIdSource()
BNFreeString(str);
return result;
}
+
+
+bool Platform::ParseTypesFromSource(const string& source, 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;
+ const char** includeDirList = new const char*[includeDirs.size()];
+
+ for (size_t i = 0; i < includeDirs.size(); i++)
+ includeDirList[i] = includeDirs[i].c_str();
+
+ types.clear();
+ variables.clear();
+ functions.clear();
+
+ bool ok = BNParseTypesFromSource(m_object, source.c_str(), fileName.c_str(), &result,
+ &errorStr, includeDirList, includeDirs.size(), autoTypeSource.c_str());
+ errors = errorStr;
+ BNFreeString(errorStr);
+ if (!ok)
+ return false;
+
+ for (size_t i = 0; i < result.typeCount; i++)
+ {
+ 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++)
+ {
+ 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++)
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.functions[i].name);
+ types[name] = new Type(BNNewTypeReference(result.functions[i].type));
+ }
+ BNFreeTypeParserResult(&result);
+ return true;
+}
+
+
+bool Platform::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;
+ const char** includeDirList = new const char*[includeDirs.size()];
+
+ for (size_t i = 0; i < includeDirs.size(); i++)
+ includeDirList[i] = includeDirs[i].c_str();
+
+ types.clear();
+ variables.clear();
+ functions.clear();
+
+ bool ok = BNParseTypesFromSourceFile(m_object, fileName.c_str(), &result, &errorStr,
+ includeDirList, includeDirs.size(), autoTypeSource.c_str());
+ errors = errorStr;
+ BNFreeString(errorStr);
+ if (!ok)
+ return false;
+
+ for (size_t i = 0; i < result.typeCount; i++)
+ {
+ 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++)
+ {
+ 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++)
+ {
+ QualifiedName name = QualifiedName::FromAPIObject(&result.functions[i].name);
+ functions[name] = new Type(BNNewTypeReference(result.functions[i].type));
+ }
+ BNFreeTypeParserResult(&result);
+ return true;
+}
diff --git a/python/architecture.py b/python/architecture.py
index 61559934..72403fec 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -1674,99 +1674,6 @@ class Architecture(object):
"""
core.BNSetBinaryViewTypeArchitectureConstant(self.handle, type_name, const_name, value)
- 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``.
-
- :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
- :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')
- ({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:{'bar':
- <type: int32_t(int32_t x)>}}, '')
- >>>
- """
-
- if filename is None:
- filename = "input"
- dir_buf = (ctypes.c_char_p * len(include_dirs))()
- for i in xrange(0, len(include_dirs)):
- 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), auto_type_source)
- error_str = errors.value
- core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
- if not result:
- raise SyntaxError(error_str)
- type_dict = {}
- variables = {}
- functions = {}
- for i in xrange(0, parse.typeCount):
- 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):
- 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):
- 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)
-
- 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
- :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"
- >>> open(file).read()
- 'int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n'
- >>> arch.parse_types_from_source_file(file)
- ({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:
- {'bar': <type: int32_t(int32_t x)>}}, '')
- >>>
- """
- dir_buf = (ctypes.c_char_p * len(include_dirs))()
- for i in xrange(0, len(include_dirs)):
- 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), auto_type_source)
- error_str = errors.value
- core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
- if not result:
- raise SyntaxError(error_str)
- type_dict = {}
- variables = {}
- functions = {}
- for i in xrange(0, parse.typeCount):
- 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):
- 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):
- 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)
-
def register_calling_convention(self, cc):
"""
``register_calling_convention`` registers a new calling convention for the Architecture.
diff --git a/python/binaryview.py b/python/binaryview.py
index a43bd5b5..bdba11af 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -217,7 +217,7 @@ class BinaryDataNotificationCallbacks(object):
def _data_var_added(self, ctxt, view, var):
try:
address = var[0].address
- var_type = types.Type(core.BNNewTypeReference(var[0].type), confidence = var[0].typeConfidence)
+ var_type = types.Type(core.BNNewTypeReference(var[0].type), platform = self.view.platform, confidence = var[0].typeConfidence)
auto_discovered = var[0].autoDiscovered
self.notify.data_var_added(self.view, DataVariable(address, var_type, auto_discovered))
except:
@@ -226,7 +226,7 @@ class BinaryDataNotificationCallbacks(object):
def _data_var_removed(self, ctxt, view, var):
try:
address = var[0].address
- var_type = types.Type(core.BNNewTypeReference(var[0].type), confidence = var[0].typeConfidence)
+ var_type = types.Type(core.BNNewTypeReference(var[0].type), platform = self.view.platform, confidence = var[0].typeConfidence)
auto_discovered = var[0].autoDiscovered
self.notify.data_var_removed(self.view, DataVariable(address, var_type, auto_discovered))
except:
@@ -235,7 +235,7 @@ class BinaryDataNotificationCallbacks(object):
def _data_var_updated(self, ctxt, view, var):
try:
address = var[0].address
- var_type = types.Type(core.BNNewTypeReference(var[0].type), confidence = var[0].typeConfidence)
+ var_type = types.Type(core.BNNewTypeReference(var[0].type), platform = self.view.platform, confidence = var[0].typeConfidence)
auto_discovered = var[0].autoDiscovered
self.notify.data_var_updated(self.view, DataVariable(address, var_type, auto_discovered))
except:
@@ -256,14 +256,14 @@ class BinaryDataNotificationCallbacks(object):
def _type_defined(self, ctxt, view, name, type_obj):
try:
qualified_name = types.QualifiedName._from_core_struct(name[0])
- self.notify.type_defined(view, qualified_name, types.Type(core.BNNewTypeReference(type_obj)))
+ self.notify.type_defined(view, qualified_name, types.Type(core.BNNewTypeReference(type_obj), platform = self.view.platform))
except:
log.log_error(traceback.format_exc())
def _type_undefined(self, ctxt, view, name, type_obj):
try:
qualified_name = types.QualifiedName._from_core_struct(name[0])
- self.notify.type_undefined(view, qualified_name, types.Type(core.BNNewTypeReference(type_obj)))
+ self.notify.type_undefined(view, qualified_name, types.Type(core.BNNewTypeReference(type_obj), platform = self.view.platform))
except:
log.log_error(traceback.format_exc())
@@ -860,7 +860,7 @@ class BinaryView(object):
result = {}
for i in xrange(0, count.value):
addr = var_list[i].address
- var_type = types.Type(core.BNNewTypeReference(var_list[i].type), confidence = var_list[i].typeConfidence)
+ var_type = types.Type(core.BNNewTypeReference(var_list[i].type), platform = self.platform, confidence = var_list[i].typeConfidence)
auto_discovered = var_list[i].autoDiscovered
result[addr] = DataVariable(addr, var_type, auto_discovered)
core.BNFreeDataVariables(var_list, count.value)
@@ -874,7 +874,7 @@ class BinaryView(object):
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))
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self.platform)
core.BNFreeTypeList(type_list, count.value)
return result
@@ -1915,7 +1915,7 @@ class BinaryView(object):
var = core.BNDataVariable()
if not core.BNGetDataVariableAtAddress(self.handle, addr, var):
return None
- return DataVariable(var.address, types.Type(var.type, confidence = var.typeConfidence), var.autoDiscovered)
+ return DataVariable(var.address, types.Type(var.type, platform = self.platform, confidence = var.typeConfidence), var.autoDiscovered)
def get_functions_containing(self, addr):
"""
@@ -2918,7 +2918,7 @@ class BinaryView(object):
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))
+ type_obj = types.Type(core.BNNewTypeReference(result.type), platform = self.platform)
name = types.QualifiedName._from_core_struct(result.name)
core.BNFreeQualifiedNameAndType(result)
return type_obj, name
@@ -2942,7 +2942,7 @@ class BinaryView(object):
obj = core.BNGetAnalysisTypeByName(self.handle, name)
if not obj:
return None
- return types.Type(obj)
+ return types.Type(obj, platform = self.platform)
def get_type_by_id(self, id):
"""
@@ -2963,7 +2963,7 @@ class BinaryView(object):
obj = core.BNGetAnalysisTypeById(self.handle, id)
if not obj:
return None
- return types.Type(obj)
+ return types.Type(obj, platform = self.platform)
def get_type_name_by_id(self, id):
"""
diff --git a/python/function.py b/python/function.py
index cf9bd759..55151e16 100644
--- a/python/function.py
+++ b/python/function.py
@@ -211,7 +211,7 @@ class Variable(object):
if var_type is None:
var_type_conf = core.BNGetVariableType(func.handle, var)
if var_type_conf.type:
- var_type = types.Type(var_type_conf.type, confidence = var_type_conf.confidence)
+ var_type = types.Type(var_type_conf.type, platform = func.platform, confidence = var_type_conf.confidence)
else:
var_type = None
@@ -443,7 +443,7 @@ class Function(object):
@property
def function_type(self):
"""Function type object"""
- return types.Type(core.BNGetFunctionType(self.handle))
+ return types.Type(core.BNGetFunctionType(self.handle), platform = self.platform)
@function_type.setter
def function_type(self, value):
@@ -457,7 +457,7 @@ class Function(object):
result = []
for i in xrange(0, count.value):
result.append(Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name,
- types.Type(handle = core.BNNewTypeReference(v[i].type), confidence = v[i].typeConfidence)))
+ types.Type(handle = core.BNNewTypeReference(v[i].type), platform = self.platform, confidence = v[i].typeConfidence)))
result.sort(key = lambda x: x.identifier)
core.BNFreeVariableList(v, count.value)
return result
@@ -470,7 +470,7 @@ class Function(object):
result = []
for i in xrange(0, count.value):
result.append(Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name,
- types.Type(handle = core.BNNewTypeReference(v[i].type), confidence = v[i].typeConfidence)))
+ types.Type(handle = core.BNNewTypeReference(v[i].type), platform = self.platform, confidence = v[i].typeConfidence)))
result.sort(key = lambda x: x.identifier)
core.BNFreeVariableList(v, count.value)
return result
@@ -518,7 +518,7 @@ class Function(object):
result = core.BNGetFunctionReturnType(self.handle)
if not result.type:
return None
- return types.Type(result.type, confidence = result.confidence)
+ return types.Type(result.type, platform = self.platform, confidence = result.confidence)
@return_type.setter
def return_type(self, value):
@@ -778,7 +778,7 @@ class Function(object):
refs = core.BNGetStackVariablesReferencedByInstruction(self.handle, arch.handle, addr, count)
result = []
for i in xrange(0, count.value):
- var_type = types.Type(core.BNNewTypeReference(refs[i].type), confidence = refs[i].typeConfidence)
+ var_type = types.Type(core.BNNewTypeReference(refs[i].type), platform = self.platform, confidence = refs[i].typeConfidence)
result.append(StackVariableReference(refs[i].sourceOperand, var_type,
refs[i].name, Variable.from_identifier(self, refs[i].varIdentifier, refs[i].name, var_type),
refs[i].referencedOffset, refs[i].size))
@@ -1132,7 +1132,8 @@ class Function(object):
if not core.BNGetStackVariableAtFrameOffset(self.handle, arch.handle, addr, offset, found_var):
return None
result = Variable(self, found_var.var.type, found_var.var.index, found_var.var.storage,
- found_var.name, types.Type(handle = core.BNNewTypeReference(found_var.type), confidence = found_var.typeConfidence))
+ found_var.name, types.Type(handle = core.BNNewTypeReference(found_var.type), platform = self.platform,
+ confidence = found_var.typeConfidence))
core.BNFreeVariableNameAndType(found_var)
return result
diff --git a/python/generator.cpp b/python/generator.cpp
index 554f82cd..f838b36d 100644
--- a/python/generator.cpp
+++ b/python/generator.cpp
@@ -172,7 +172,7 @@ int main(int argc, char* argv[])
return 1;
}
- bool ok = arch->ParseTypesFromSourceFile(argv[1], types, vars, funcs, errors);
+ bool ok = arch->GetStandalonePlatform()->ParseTypesFromSourceFile(argv[1], types, vars, funcs, errors);
fprintf(stderr, "Errors: %s", errors.c_str());
if (!ok)
return 1;
@@ -237,22 +237,61 @@ int main(int argc, char* argv[])
fprintf(out, "\n# Structure definitions\n");
+ set<QualifiedName> structsToProcess;
+ set<QualifiedName> finishedStructs;
for (auto& i : types)
+ structsToProcess.insert(i.first);
+ while (structsToProcess.size() != 0)
{
- string name;
- if (i.first.size() != 1)
- continue;
- name = i.first[0];
- if ((i.second->GetClass() == StructureTypeClass) && (i.second->GetStructure()->GetMembers().size() != 0))
+ set<QualifiedName> currentStructList = structsToProcess;
+ structsToProcess.clear();
+ bool processedSome = false;
+ for (auto& i : currentStructList)
{
- fprintf(out, "%s._fields_ = [\n", name.c_str());
- for (auto& j : i.second->GetStructure()->GetMembers())
+ string name;
+ if (i.size() != 1)
+ continue;
+ Ref<Type> type = types[i];
+ name = i[0];
+ if ((type->GetClass() == StructureTypeClass) && (type->GetStructure()->GetMembers().size() != 0))
{
- fprintf(out, "\t\t(\"%s\", ", j.name.c_str());
- OutputType(out, j.type);
- fprintf(out, "),\n");
+ bool requiresDependency = false;
+ for (auto& j : type->GetStructure()->GetMembers())
+ {
+ if ((j.type->GetClass() == NamedTypeReferenceClass) &&
+ (types[j.type->GetNamedTypeReference()->GetName()]->GetClass() == StructureTypeClass) &&
+ (finishedStructs.count(j.type->GetNamedTypeReference()->GetName()) == 0))
+ {
+ // This structure needs another structure that isn't fully defined yet, need to wait
+ // for the dependencies to be defined
+ structsToProcess.insert(i);
+ requiresDependency = true;
+ break;
+ }
+ }
+
+ if (requiresDependency)
+ continue;
+
+ fprintf(out, "%s._fields_ = [\n", name.c_str());
+ for (auto& j : type->GetStructure()->GetMembers())
+ {
+ fprintf(out, "\t\t(\"%s\", ", j.name.c_str());
+ OutputType(out, j.type);
+ fprintf(out, "),\n");
+ }
+ fprintf(out, "\t]\n");
+ finishedStructs.insert(i);
+ processedSome = true;
}
- fprintf(out, "\t]\n");
+ }
+
+ if (!processedSome)
+ {
+ fprintf(stderr, "Detected dependency cycle in structures\n");
+ for (auto& i : structsToProcess)
+ fprintf(stderr, "%s\n", i.GetString().c_str());
+ return 1;
}
}
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index c837aa42..3e7a6997 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -417,7 +417,10 @@ class MediumLevelILInstruction(object):
"""Type of expression"""
result = core.BNGetMediumLevelILExprType(self.function.handle, self.expr_index)
if result.type:
- return types.Type(result.type, confidence = result.confidence)
+ platform = None
+ if self.function.source_function:
+ platform = self.function.source_function.platform
+ return types.Type(result.type, platform = platform, confidence = result.confidence)
return None
def get_ssa_var_possible_values(self, ssa_var):
diff --git a/python/platform.py b/python/platform.py
index 1c2fdcd3..5e63d836 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -234,7 +234,7 @@ class Platform(object):
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))
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self)
core.BNFreeTypeList(type_list, count.value)
return result
@@ -246,7 +246,7 @@ class Platform(object):
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))
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self)
core.BNFreeTypeList(type_list, count.value)
return result
@@ -258,7 +258,7 @@ class Platform(object):
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))
+ result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self)
core.BNFreeTypeList(type_list, count.value)
return result
@@ -270,7 +270,7 @@ class Platform(object):
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))
+ t = types.Type(core.BNNewTypeReference(call_list[i].type), platform = self)
result[call_list[i].number] = (name, t)
core.BNFreeSystemCallList(call_list, count.value)
return result
@@ -325,21 +325,21 @@ class Platform(object):
obj = core.BNGetPlatformTypeByName(self.handle, name)
if not obj:
return None
- return types.Type(obj)
+ return types.Type(obj, platform = self)
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)
+ return types.Type(obj, platform = self)
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)
+ return types.Type(obj, platform = self)
def get_system_call_name(self, number):
return core.BNGetPlatformSystemCallName(self.handle, number)
@@ -348,7 +348,7 @@ class Platform(object):
obj = core.BNGetPlatformSystemCallType(self.handle, number)
if not obj:
return None
- return types.Type(obj)
+ return types.Type(obj, platform = self)
def generate_auto_platform_type_id(self, name):
name = types.QualifiedName(name)._get_core_struct()
@@ -360,3 +360,96 @@ class Platform(object):
def get_auto_platform_type_id_source(self):
return core.BNGetAutoPlatformTypeIdSource(self.handle)
+
+ 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``.
+
+ :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
+ :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:
+
+ >>> platform.parse_types_from_source('int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n')
+ ({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:{'bar':
+ <type: int32_t(int32_t x)>}}, '')
+ >>>
+ """
+
+ if filename is None:
+ filename = "input"
+ dir_buf = (ctypes.c_char_p * len(include_dirs))()
+ for i in xrange(0, len(include_dirs)):
+ 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), auto_type_source)
+ error_str = errors.value
+ core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
+ if not result:
+ raise SyntaxError(error_str)
+ type_dict = {}
+ variables = {}
+ functions = {}
+ for i in xrange(0, parse.typeCount):
+ name = types.QualifiedName._from_core_struct(parse.types[i].name)
+ type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self)
+ for i in xrange(0, parse.variableCount):
+ name = types.QualifiedName._from_core_struct(parse.variables[i].name)
+ variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self)
+ for i in xrange(0, parse.functionCount):
+ name = types.QualifiedName._from_core_struct(parse.functions[i].name)
+ functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self)
+ core.BNFreeTypeParserResult(parse)
+ return types.TypeParserResult(type_dict, variables, functions)
+
+ 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
+ :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"
+ >>> open(file).read()
+ 'int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n'
+ >>> platform.parse_types_from_source_file(file)
+ ({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:
+ {'bar': <type: int32_t(int32_t x)>}}, '')
+ >>>
+ """
+ dir_buf = (ctypes.c_char_p * len(include_dirs))()
+ for i in xrange(0, len(include_dirs)):
+ 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), auto_type_source)
+ error_str = errors.value
+ core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
+ if not result:
+ raise SyntaxError(error_str)
+ type_dict = {}
+ variables = {}
+ functions = {}
+ for i in xrange(0, parse.typeCount):
+ name = types.QualifiedName._from_core_struct(parse.types[i].name)
+ type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self)
+ for i in xrange(0, parse.variableCount):
+ name = types.QualifiedName._from_core_struct(parse.variables[i].name)
+ variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self)
+ for i in xrange(0, parse.functionCount):
+ name = types.QualifiedName._from_core_struct(parse.functions[i].name)
+ functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self)
+ core.BNFreeTypeParserResult(parse)
+ return types.TypeParserResult(type_dict, variables, functions)
diff --git a/python/types.py b/python/types.py
index e297ddd2..fd2ee27e 100644
--- a/python/types.py
+++ b/python/types.py
@@ -24,7 +24,7 @@ import ctypes
# Binary Ninja components
import _binaryninjacore as core
-from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType, ReferenceType
+from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType, ReferenceType, VariableSourceType
import callingconvention
import function
@@ -199,10 +199,23 @@ class Symbol(object):
raise AttributeError("attribute '%s' is read only" % name)
+class FunctionParameter(object):
+ def __init__(self, param_type, name = "", location = None):
+ self.type = param_type
+ self.name = name
+ self.location = location
+
+ def __repr__(self):
+ if (self.location is not None) and (self.location.name != self.name):
+ return "%s %s%s @ %s" % (self.type.get_string_before_name(), self.name, self.type.get_string_after_name(), self.location.name)
+ return "%s %s%s" % (self.type.get_string_before_name(), self.name, self.type.get_string_after_name())
+
+
class Type(object):
- def __init__(self, handle, confidence = max_confidence):
+ def __init__(self, handle, platform = None, confidence = max_confidence):
self.handle = handle
self.confidence = confidence
+ self.platform = platform
def __del__(self):
core.BNFreeType(self.handle)
@@ -255,7 +268,7 @@ class Type(object):
result = core.BNGetChildType(self.handle)
if not result.type:
return None
- return Type(result.type, confidence = result.confidence)
+ return Type(result.type, platform = self.platform, confidence = result.confidence)
@property
def element_type(self):
@@ -263,7 +276,7 @@ class Type(object):
result = core.BNGetChildType(self.handle)
if not result.type:
return None
- return Type(result.type, confidence = result.confidence)
+ return Type(result.type, platform = self.platform, confidence = result.confidence)
@property
def return_value(self):
@@ -271,7 +284,7 @@ class Type(object):
result = core.BNGetChildType(self.handle)
if not result.type:
return None
- return Type(result.type, confidence = result.confidence)
+ return Type(result.type, platform = self.platform, confidence = result.confidence)
@property
def calling_convention(self):
@@ -288,7 +301,18 @@ class Type(object):
params = core.BNGetTypeParameters(self.handle, count)
result = []
for i in xrange(0, count.value):
- result.append((Type(core.BNNewTypeReference(params[i].type), confidence = params[i].typeConfidence), params[i].name))
+ param_type = Type(core.BNNewTypeReference(params[i].type), platform = self.platform, confidence = params[i].typeConfidence)
+ if params[i].defaultLocation:
+ param_location = None
+ else:
+ name = params[i].name
+ if (params[i].location.type == VariableSourceType.RegisterVariableSourceType) and (self.platform is not None):
+ name = self.platform.arch.get_reg_name(params[i].location.storage)
+ elif params[i].location.type == VariableSourceType.StackVariableSourceType:
+ name = "arg_%x" % params[i].location.storage
+ param_location = function.Variable(None, params[i].location.type, params[i].location.index,
+ params[i].location.storage, name, param_type)
+ result.append(FunctionParameter(param_type, params[i].name, param_location))
core.BNFreeTypeParameterList(params, count.value)
return result
@@ -339,7 +363,10 @@ class Type(object):
return core.BNGetTypeOffset(self.handle)
def __str__(self):
- return core.BNGetTypeString(self.handle)
+ platform = None
+ if self.platform is not None:
+ platform = self.platform.handle
+ return core.BNGetTypeString(self.handle, platform)
def __repr__(self):
if self.confidence < max_confidence:
@@ -347,16 +374,28 @@ class Type(object):
return "<type: %s>" % str(self)
def get_string_before_name(self):
- return core.BNGetTypeStringBeforeName(self.handle)
+ platform = None
+ if self.platform is not None:
+ platform = self.platform.handle
+ return core.BNGetTypeStringBeforeName(self.handle, platform)
def get_string_after_name(self):
- return core.BNGetTypeStringAfterName(self.handle)
+ platform = None
+ if self.platform is not None:
+ platform = self.platform.handle
+ return core.BNGetTypeStringAfterName(self.handle, platform)
@property
def tokens(self):
"""Type string as a list of tokens (read-only)"""
+ return self.get_tokens()
+
+ def get_tokens(self, base_confidence = max_confidence):
count = ctypes.c_ulonglong()
- tokens = core.BNGetTypeTokens(self.handle, count)
+ platform = None
+ if self.platform is not None:
+ platform = self.platform.handle
+ tokens = core.BNGetTypeTokens(self.handle, platform, base_confidence, count)
result = []
for i in xrange(0, count.value):
token_type = InstructionTextTokenType(tokens[i].type)
@@ -371,9 +410,12 @@ class Type(object):
core.BNFreeTokenList(tokens, count.value)
return result
- def get_tokens_before_name(self):
+ def get_tokens_before_name(self, base_confidence = max_confidence):
count = ctypes.c_ulonglong()
- tokens = core.BNGetTypeTokensBeforeName(self.handle, count)
+ platform = None
+ if self.platform is not None:
+ platform = self.platform.handle
+ tokens = core.BNGetTypeTokensBeforeName(self.handle, platform, base_confidence, count)
result = []
for i in xrange(0, count.value):
token_type = InstructionTextTokenType(tokens[i].type)
@@ -388,9 +430,12 @@ class Type(object):
core.BNFreeTokenList(tokens, count.value)
return result
- def get_tokens_after_name(self):
+ def get_tokens_after_name(self, base_confidence = max_confidence):
count = ctypes.c_ulonglong()
- tokens = core.BNGetTypeTokensAfterName(self.handle, count)
+ platform = None
+ if self.platform is not None:
+ platform = self.platform.handle
+ tokens = core.BNGetTypeTokensAfterName(self.handle, platform, base_confidence, count)
result = []
for i in xrange(0, count.value):
token_type = InstructionTextTokenType(tokens[i].type)
@@ -515,16 +560,29 @@ class Type(object):
:param CallingConvention calling_convention: optional argument for function calling convention
:param bool variable_arguments: optional argument for functions that have a variable number of arguments
"""
- param_buf = (core.BNNameAndType * len(params))()
+ param_buf = (core.BNFunctionParameter * len(params))()
for i in xrange(0, len(params)):
if isinstance(params[i], Type):
param_buf[i].name = ""
param_buf[i].type = params[i].handle
param_buf[i].typeConfidence = params[i].confidence
+ param_buf[i].defaultLocation = True
+ elif isinstance(params[i], FunctionParameter):
+ param_buf[i].name = params[i].name
+ param_buf[i].type = params[i].type.handle
+ param_buf[i].typeConfidence = params[i].type.confidence
+ if params[i].location is None:
+ param_buf[i].defaultLocation = True
+ else:
+ param_buf[i].defaultLocation = False
+ param_buf[i].location.type = params[i].location.type
+ param_buf[i].location.index = params[i].location.index
+ param_buf[i].location.storage = params[i].location.storage
else:
param_buf[i].name = params[i][1]
param_buf[i].type = params[i][0].handle
param_buf[i].typeConfidence = params[i][0].confidence
+ param_buf[i].defaultLocation = True
ret_conf = core.BNTypeWithConfidence()
ret_conf.type = ret.handle
@@ -565,7 +623,7 @@ class Type(object):
return core.BNGetAutoDemangledTypeIdSource()
def with_confidence(self, confidence):
- return Type(handle = core.BNNewTypeReference(self.handle), confidence = confidence)
+ return Type(handle = core.BNNewTypeReference(self.handle), platform = self.platform, confidence = confidence)
def __setattr__(self, name, value):
try:
diff --git a/type.cpp b/type.cpp
index 398a7216..aa891557 100644
--- a/type.cpp
+++ b/type.cpp
@@ -349,17 +349,21 @@ Confidence<Ref<CallingConvention>> Type::GetCallingConvention() const
}
-vector<NameAndType> Type::GetParameters() const
+vector<FunctionParameter> Type::GetParameters() const
{
size_t count;
- BNNameAndType* types = BNGetTypeParameters(m_object, &count);
+ BNFunctionParameter* types = BNGetTypeParameters(m_object, &count);
- vector<NameAndType> result;
+ vector<FunctionParameter> result;
for (size_t i = 0; i < count; i++)
{
- NameAndType param;
+ FunctionParameter param;
param.name = types[i].name;
param.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(types[i].type)), types[i].typeConfidence);
+ param.defaultLocation = types[i].defaultLocation;
+ param.location.type = types[i].location.type;
+ param.location.index = types[i].location.index;
+ param.location.storage = types[i].location.storage;
result.push_back(param);
}
@@ -421,9 +425,9 @@ uint64_t Type::GetOffset() const
}
-string Type::GetString() const
+string Type::GetString(Platform* platform) const
{
- char* str = BNGetTypeString(m_object);
+ char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr);
string result = str;
BNFreeString(str);
return result;
@@ -438,28 +442,29 @@ string Type::GetTypeAndName(const QualifiedName& nameList) const
return outName;
}
-string Type::GetStringBeforeName() const
+string Type::GetStringBeforeName(Platform* platform) const
{
- char* str = BNGetTypeStringBeforeName(m_object);
+ char* str = BNGetTypeStringBeforeName(m_object, platform ? platform->GetObject() : nullptr);
string result = str;
BNFreeString(str);
return result;
}
-string Type::GetStringAfterName() const
+string Type::GetStringAfterName(Platform* platform) const
{
- char* str = BNGetTypeStringAfterName(m_object);
+ char* str = BNGetTypeStringAfterName(m_object, platform ? platform->GetObject() : nullptr);
string result = str;
BNFreeString(str);
return result;
}
-vector<InstructionTextToken> Type::GetTokens() const
+vector<InstructionTextToken> Type::GetTokens(Platform* platform, uint8_t baseConfidence) const
{
size_t count;
- BNInstructionTextToken* tokens = BNGetTypeTokens(m_object, &count);
+ BNInstructionTextToken* tokens = BNGetTypeTokens(m_object,
+ platform ? platform->GetObject() : nullptr, baseConfidence, &count);
vector<InstructionTextToken> result;
for (size_t i = 0; i < count; i++)
@@ -481,10 +486,11 @@ vector<InstructionTextToken> Type::GetTokens() const
}
-vector<InstructionTextToken> Type::GetTokensBeforeName() const
+vector<InstructionTextToken> Type::GetTokensBeforeName(Platform* platform, uint8_t baseConfidence) const
{
size_t count;
- BNInstructionTextToken* tokens = BNGetTypeTokensBeforeName(m_object, &count);
+ BNInstructionTextToken* tokens = BNGetTypeTokensBeforeName(m_object,
+ platform ? platform->GetObject() : nullptr, baseConfidence, &count);
vector<InstructionTextToken> result;
for (size_t i = 0; i < count; i++)
@@ -506,10 +512,11 @@ vector<InstructionTextToken> Type::GetTokensBeforeName() const
}
-vector<InstructionTextToken> Type::GetTokensAfterName() const
+vector<InstructionTextToken> Type::GetTokensAfterName(Platform* platform, uint8_t baseConfidence) const
{
size_t count;
- BNInstructionTextToken* tokens = BNGetTypeTokensAfterName(m_object, &count);
+ BNInstructionTextToken* tokens = BNGetTypeTokensAfterName(m_object,
+ platform ? platform->GetObject() : nullptr, baseConfidence, &count);
vector<InstructionTextToken> result;
for (size_t i = 0; i < count; i++)
@@ -656,7 +663,7 @@ Ref<Type> Type::ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem)
Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue,
const Confidence<Ref<CallingConvention>>& callingConvention,
- const std::vector<NameAndType>& params, const Confidence<bool>& varArg)
+ const std::vector<FunctionParameter>& params, const Confidence<bool>& varArg)
{
BNTypeWithConfidence returnValueConf;
returnValueConf.type = returnValue->GetObject();
@@ -666,12 +673,16 @@ Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue,
callingConventionConf.convention = callingConvention ? callingConvention->GetObject() : nullptr;
callingConventionConf.confidence = callingConvention.GetConfidence();
- BNNameAndType* paramArray = new BNNameAndType[params.size()];
+ BNFunctionParameter* paramArray = new BNFunctionParameter[params.size()];
for (size_t i = 0; i < params.size(); i++)
{
paramArray[i].name = (char*)params[i].name.c_str();
paramArray[i].type = params[i].type->GetObject();
paramArray[i].typeConfidence = params[i].type.GetConfidence();
+ paramArray[i].defaultLocation = params[i].defaultLocation;
+ paramArray[i].location.type = params[i].location.type;
+ paramArray[i].location.index = params[i].location.index;
+ paramArray[i].location.storage = params[i].location.storage;
}
BNBoolWithConfidence varArgConf;