summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-07-26 01:11:54 -0400
committerRusty Wagner <rusty@vector35.com>2017-07-26 01:11:54 -0400
commitd9c2c3d7c81863f37ccb3885f7c57376f40a2e5d (patch)
treef91ab2d030d5fa9e1e5ada36409a3645081f7f92
parentecfc609d7941694033971ae6b3f96830e7debd70 (diff)
parent24b090492a216278fbc0e43e8f01cec13fa59696 (diff)
Merge type propagation into dev
-rw-r--r--architecture.cpp18
-rw-r--r--basicblock.cpp1
-rw-r--r--binaryninjaapi.h259
-rw-r--r--binaryninjacore.h124
-rw-r--r--binaryview.cpp28
-rw-r--r--function.cpp49
-rw-r--r--functiongraphblock.cpp1
-rw-r--r--lowlevelil.cpp14
-rw-r--r--mediumlevelil.cpp39
-rw-r--r--python/architecture.py4
-rw-r--r--python/basicblock.py3
-rw-r--r--python/binaryview.py23
-rw-r--r--python/callingconvention.py9
-rw-r--r--python/function.py53
-rw-r--r--python/lowlevelil.py31
-rw-r--r--python/mediumlevelil.py43
-rw-r--r--python/types.py170
-rw-r--r--type.cpp181
18 files changed, 841 insertions, 209 deletions
diff --git a/architecture.cpp b/architecture.cpp
index eb70b16c..3e82ffd3 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -46,24 +46,31 @@ void InstructionInfo::AddBranch(BNBranchType type, uint64_t target, Architecture
}
-InstructionTextToken::InstructionTextToken(): type(TextToken), value(0)
+InstructionTextToken::InstructionTextToken(): type(TextToken), value(0), confidence(BN_FULL_CONFIDENCE)
{
}
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), context(NoTokenContext), address(0)
+ size_t s, size_t o, uint8_t c) : type(t), text(txt), value(val), size(s), operand(o), context(NoTokenContext),
+ confidence(c), 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)
+ const string& txt, uint64_t a, uint64_t val, size_t s, size_t o, uint8_t c):
+ type(t), text(txt), value(val), size(s), operand(o), context(ctxt), confidence(c), address(a)
{
}
+InstructionTextToken InstructionTextToken::WithConfidence(uint8_t conf)
+{
+ return InstructionTextToken(type, context, text, address, value, size, operand, conf);
+}
+
+
Architecture::Architecture(BNArchitecture* arch)
{
m_object = arch;
@@ -161,6 +168,7 @@ bool Architecture::GetInstructionTextCallback(void* ctxt, const uint8_t* data, u
(*result)[i].size = tokens[i].size;
(*result)[i].operand = tokens[i].operand;
(*result)[i].context = tokens[i].context;
+ (*result)[i].confidence = tokens[i].confidence;
(*result)[i].address = tokens[i].address;
}
return true;
@@ -990,7 +998,7 @@ 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].context, tokens[i].text, tokens[i].address,
- tokens[i].value, tokens[i].size, tokens[i].operand));
+ tokens[i].value, tokens[i].size, tokens[i].operand, tokens[i].confidence));
}
BNFreeInstructionText(tokens, count);
diff --git a/basicblock.cpp b/basicblock.cpp
index c2a2bddf..721f1ca6 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -276,6 +276,7 @@ vector<DisassemblyTextLine> BasicBlock::GetDisassemblyText(DisassemblySettings*
token.size = lines[i].tokens[j].size;
token.operand = lines[i].tokens[j].operand;
token.context = lines[i].tokens[j].context;
+ token.confidence = lines[i].tokens[j].confidence;
token.address = lines[i].tokens[j].address;
line.tokens.push_back(token);
}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index c4a54b79..62ebbd04 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -285,6 +285,174 @@ namespace BinaryNinja
}
};
+ class ConfidenceBase
+ {
+ protected:
+ uint8_t m_confidence;
+
+ public:
+ ConfidenceBase(): m_confidence(0)
+ {
+ }
+
+ ConfidenceBase(uint8_t conf): m_confidence(conf)
+ {
+ }
+
+ uint8_t GetConfidence() const { return m_confidence; }
+ void SetConfidence(uint8_t conf) { m_confidence = conf; }
+ bool IsUnknown() const { return m_confidence == 0; }
+ };
+
+ template <class T>
+ class Confidence: public ConfidenceBase
+ {
+ T m_value;
+
+ public:
+ Confidence()
+ {
+ }
+
+ Confidence(const T& value): ConfidenceBase(BN_FULL_CONFIDENCE), m_value(value)
+ {
+ }
+
+ Confidence(const T& value, uint8_t conf): ConfidenceBase(conf), m_value(value)
+ {
+ }
+
+ Confidence(const Confidence<T>& v): ConfidenceBase(v.m_confidence), m_value(v.m_value)
+ {
+ }
+
+ operator T() { return m_value; }
+ const operator T() const { return m_value; }
+ T* operator->() { return &m_value; }
+ const T* operator->() const { return &m_value; }
+
+ T& GetValue() { return m_value; }
+ const T& GetValue() const { return m_value; }
+ void SetValue(const T& value) { m_value = value; }
+
+ Confidence<T>& operator=(const Confidence<T>& v)
+ {
+ m_value = v.m_value;
+ m_confidence = v.m_confidence;
+ return *this;
+ }
+
+ Confidence<T>& operator=(const T& value)
+ {
+ m_value = value;
+ m_confidence = BN_FULL_CONFIDENCE;
+ return *this;
+ }
+
+ bool operator<(const Confidence<T>& a) const
+ {
+ if (m_value < a.m_value)
+ return true;
+ if (a.m_value < m_value)
+ return false;
+ return m_confidence < a.m_confidence;
+ }
+
+ bool operator==(const Confidence<T>& a) const
+ {
+ if (m_confidence != a.m_confidence)
+ return false;
+ return m_confidence == a.m_confidence;
+ }
+
+ bool operator!=(const Confidence<T>& a) const
+ {
+ return !(*this == a);
+ }
+ };
+
+ template <class T>
+ class Confidence<Ref<T>>: public ConfidenceBase
+ {
+ Ref<T> m_value;
+
+ public:
+ Confidence()
+ {
+ }
+
+ Confidence(T* value): ConfidenceBase(value ? BN_FULL_CONFIDENCE : 0), m_value(value)
+ {
+ }
+
+ Confidence(T* value, uint8_t conf): ConfidenceBase(conf), m_value(value)
+ {
+ }
+
+ Confidence(const Ref<T>& value): ConfidenceBase(value ? BN_FULL_CONFIDENCE : 0), m_value(value)
+ {
+ }
+
+ Confidence(const Ref<T>& value, uint8_t conf): ConfidenceBase(conf), m_value(value)
+ {
+ }
+
+ Confidence(const Confidence<Ref<T>>& v): ConfidenceBase(v.m_confidence), m_value(v.m_value)
+ {
+ }
+
+ operator Ref<T>() const { return m_value; }
+ operator T*() const { return m_value.GetPtr(); }
+ T* operator->() const { return m_value.GetPtr(); }
+ bool operator!() const { return !m_value; }
+
+ const Ref<T>& GetValue() const { return m_value; }
+ void SetValue(T* value) { m_value = value; }
+ void SetValue(const Ref<T>& value) { m_value = value; }
+
+ Confidence<Ref<T>>& operator=(const Confidence<Ref<T>>& v)
+ {
+ m_value = v.m_value;
+ m_confidence = v.m_confidence;
+ return *this;
+ }
+
+ Confidence<Ref<T>>& operator=(T* value)
+ {
+ m_value = value;
+ m_confidence = value ? BN_FULL_CONFIDENCE : 0;
+ return *this;
+ }
+
+ Confidence<Ref<T>>& operator=(const Ref<T>& value)
+ {
+ m_value = value;
+ m_confidence = value ? BN_FULL_CONFIDENCE : 0;
+ return *this;
+ }
+
+ bool operator<(const Confidence<Ref<T>>& a) const
+ {
+ if (m_value < a.m_value)
+ return true;
+ if (a.m_value < m_value)
+ return false;
+ return m_confidence < a.m_confidence;
+ }
+
+ bool operator==(const Confidence<Ref<T>>& a) const
+ {
+ if (m_confidence != a.m_confidence)
+ return false;
+ return m_confidence == a.m_confidence;
+ }
+
+ bool operator!=(const Confidence<Ref<T>>& a) const
+ {
+ return !(*this == a);
+ }
+ };
+
class LogListener
{
static void LogMessageCallback(void* ctxt, BNLogLevel level, const char* msg);
@@ -776,14 +944,17 @@ namespace BinaryNinja
uint64_t value;
size_t size, operand;
BNInstructionTextTokenContext context;
+ uint8_t confidence;
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);
+ size_t size = 0, size_t operand = BN_INVALID_OPERAND, uint8_t confidence = BN_FULL_CONFIDENCE);
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);
+ size_t operand = BN_INVALID_OPERAND, uint8_t confidence = BN_FULL_CONFIDENCE);
+
+ InstructionTextToken WithConfidence(uint8_t conf);
};
struct DisassemblyTextLine
@@ -827,7 +998,7 @@ namespace BinaryNinja
struct DataVariable
{
uint64_t address;
- Ref<Type> type;
+ Confidence<Ref<Type>> type;
bool autoDiscovered;
};
@@ -1006,8 +1177,8 @@ namespace BinaryNinja
void UpdateAnalysis();
void AbortAnalysis();
- void DefineDataVariable(uint64_t addr, Type* type);
- void DefineUserDataVariable(uint64_t addr, Type* type);
+ void DefineDataVariable(uint64_t addr, const Confidence<Ref<Type>>& type);
+ void DefineUserDataVariable(uint64_t addr, const Confidence<Ref<Type>>& type);
void UndefineDataVariable(uint64_t addr);
void UndefineUserDataVariable(uint64_t addr);
@@ -1635,7 +1806,7 @@ namespace BinaryNinja
struct NameAndType
{
std::string name;
- Ref<Type> type;
+ Confidence<Ref<Type>> type;
};
struct QualifiedNameAndType
@@ -1653,29 +1824,30 @@ namespace BinaryNinja
uint64_t GetWidth() const;
size_t GetAlignment() const;
QualifiedName GetTypeName() const;
- bool IsSigned() const;
- bool IsConst() const;
- bool IsVolatile() const;
+ Confidence<bool> IsSigned() const;
+ Confidence<bool> IsConst() const;
+ Confidence<bool> IsVolatile() const;
bool IsFloat() const;
- Ref<Type> GetChildType() const;
- Ref<CallingConvention> GetCallingConvention() const;
+ Confidence<Ref<Type>> GetChildType() const;
+ Confidence<Ref<CallingConvention>> GetCallingConvention() const;
std::vector<NameAndType> GetParameters() const;
bool HasVariableArguments() const;
- bool CanReturn() const;
+ Confidence<bool> CanReturn() const;
Ref<Structure> GetStructure() const;
Ref<Enumeration> GetEnumeration() const;
Ref<NamedTypeReference> GetNamedTypeReference() const;
- BNMemberScope GetScope() const;
- void SetScope(BNMemberScope scope);
- BNMemberAccess GetAccess() const;
- void SetAccess(BNMemberAccess access);
- void SetConst(bool cnst);
- void SetVolatile(bool vltl);
+ Confidence<BNMemberScope> GetScope() const;
+ void SetScope(const Confidence<BNMemberScope>& scope);
+ Confidence<BNMemberAccess> GetAccess() const;
+ void SetAccess(const Confidence<BNMemberAccess>& access);
+ void SetConst(const Confidence<bool>& cnst);
+ void SetVolatile(const Confidence<bool>& vltl);
void SetTypeName(const QualifiedName& name);
uint64_t GetElementCount() const;
+ uint64_t GetOffset() const;
- void SetFunctionCanReturn(bool canReturn);
+ void SetFunctionCanReturn(const Confidence<bool>& canReturn);
std::string GetString() const;
std::string GetTypeAndName(const QualifiedName& name) const;
@@ -1690,7 +1862,7 @@ namespace BinaryNinja
static Ref<Type> VoidType();
static Ref<Type> BoolType();
- static Ref<Type> IntegerType(size_t width, bool sign, const std::string& altName = "");
+ static Ref<Type> IntegerType(size_t width, const Confidence<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> NamedType(NamedTypeReference* ref, size_t width = 0, size_t align = 1);
@@ -1698,19 +1870,24 @@ namespace BinaryNinja
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);
- static Ref<Type> PointerType(size_t width, Type* type, bool cnst = false, bool vltl = false,
- BNReferenceType refType = PointerReferenceType);
- static Ref<Type> ArrayType(Type* type, uint64_t elem);
- static Ref<Type> FunctionType(Type* returnValue, CallingConvention* callingConvention,
- const std::vector<NameAndType>& params, bool varArg = false);
+ static Ref<Type> PointerType(Architecture* arch, const Confidence<Ref<Type>>& type,
+ const Confidence<bool>& cnst = Confidence<bool>(false, 0),
+ const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType);
+ static Ref<Type> PointerType(size_t width, const Confidence<Ref<Type>>& type,
+ const Confidence<bool>& cnst = Confidence<bool>(false, 0),
+ const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType);
+ 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, bool varArg = false);
static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name);
static std::string GenerateAutoDemangledTypeId(const QualifiedName& name);
static std::string GetAutoDemangledTypeIdSource();
static std::string GenerateAutoDebugTypeId(const QualifiedName& name);
static std::string GetAutoDebugTypeIdSource();
+
+ Confidence<Ref<Type>> WithConfidence(uint8_t conf);
};
class NamedTypeReference: public CoreRefCountObject<BNNamedTypeReference, BNNewNamedTypeReference,
@@ -1759,10 +1936,10 @@ namespace BinaryNinja
bool IsUnion() const;
void SetStructureType(BNStructureType type);
BNStructureType GetStructureType() const;
- void AddMember(Type* type, const std::string& name);
- void AddMemberAtOffset(Type* type, const std::string& name, uint64_t offset);
+ void AddMember(const Confidence<Ref<Type>>& type, const std::string& name);
+ void AddMemberAtOffset(const Confidence<Ref<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);
+ void ReplaceMember(size_t idx, const Confidence<Ref<Type>>& type, const std::string& name);
};
struct EnumerationMember
@@ -1876,7 +2053,7 @@ namespace BinaryNinja
struct VariableNameAndType
{
Variable var;
- Ref<Type> type;
+ Confidence<Ref<Type>> type;
std::string name;
bool autoDefined;
};
@@ -1884,10 +2061,11 @@ namespace BinaryNinja
struct StackVariableReference
{
uint32_t sourceOperand;
- Ref<Type> type;
+ Confidence<Ref<Type>> type;
std::string name;
Variable var;
int64_t referencedOffset;
+ size_t size;
};
struct IndirectBranchInfo
@@ -1993,20 +2171,20 @@ namespace BinaryNinja
Ref<FunctionGraph> CreateFunctionGraph();
std::map<int64_t, std::vector<VariableNameAndType>> GetStackLayout();
- void CreateAutoStackVariable(int64_t offset, Ref<Type> type, const std::string& name);
- void CreateUserStackVariable(int64_t offset, Ref<Type> type, const std::string& name);
+ void CreateAutoStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const std::string& name);
+ void CreateUserStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const std::string& name);
void DeleteAutoStackVariable(int64_t offset);
void DeleteUserStackVariable(int64_t offset);
bool GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, int64_t offset, VariableNameAndType& var);
std::map<Variable, VariableNameAndType> GetVariables();
- void CreateAutoVariable(const Variable& var, Ref<Type> type, const std::string& name,
+ void CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type, const std::string& name,
bool ignoreDisjointUses = false);
- void CreateUserVariable(const Variable& var, Ref<Type> type, const std::string& name,
+ void CreateUserVariable(const Variable& var, const Confidence<Ref<Type>>& type, const std::string& name,
bool ignoreDisjointUses = false);
void DeleteAutoVariable(const Variable& var);
void DeleteUserVariable(const Variable& var);
- Ref<Type> GetVariableType(const Variable& var);
+ Confidence<Ref<Type>> GetVariableType(const Variable& var);
std::string GetVariableName(const Variable& var);
void SetAutoIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector<ArchAndAddr>& branches);
@@ -2289,6 +2467,8 @@ namespace BinaryNinja
Ref<MediumLevelILFunction> GetMediumLevelIL() const;
Ref<MediumLevelILFunction> GetMappedMediumLevelIL() const;
+ size_t GetMediumLevelILInstructionIndex(size_t instr) const;
+ size_t GetMediumLevelILExprIndex(size_t expr) const;
size_t GetMappedMediumLevelILInstructionIndex(size_t instr) const;
size_t GetMappedMediumLevelILExprIndex(size_t expr) const;
};
@@ -2347,6 +2527,9 @@ namespace BinaryNinja
std::set<size_t> GetSSAVarUses(const Variable& var, size_t version) const;
std::set<size_t> GetSSAMemoryUses(size_t version) const;
+ std::set<size_t> GetVariableDefinitions(const Variable& var) const;
+ std::set<size_t> GetVariableUses(const Variable& var) const;
+
RegisterValue GetSSAVarValue(const Variable& var, size_t version);
RegisterValue GetExprValue(size_t expr);
PossibleValueSet GetPossibleSSAVarValues(const Variable& var, size_t version, size_t instr);
@@ -2377,6 +2560,8 @@ namespace BinaryNinja
Ref<LowLevelILFunction> GetLowLevelIL() const;
size_t GetLowLevelILInstructionIndex(size_t instr) const;
size_t GetLowLevelILExprIndex(size_t expr) const;
+
+ Confidence<Ref<Type>> GetExprType(size_t expr);
};
class FunctionRecognizer
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 1036e98c..e2eb0700 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -92,6 +92,8 @@
#define BN_MAX_VARIABLE_OFFSET 0x7fffffffffLL
#define BN_MAX_VARIABLE_INDEX 0xfffff
+#define BN_FULL_CONFIDENCE 255
+
#ifdef __cplusplus
extern "C"
{
@@ -414,6 +416,9 @@ extern "C"
ShowAddress = 0,
ShowOpcode = 1,
ExpandLongOpcode = 2,
+ ShowVariablesAtTopOfGraph = 3,
+ ShowVariableTypesWhenAssigned = 4,
+ ShowDefaultRegisterTypes = 5,
// Linear disassembly options
GroupLinearDisassemblyFunctions = 64,
@@ -714,6 +719,7 @@ extern "C"
uint64_t address;
BNType* type;
bool autoDiscovered;
+ uint8_t typeConfidence;
};
enum BNMediumLevelILOperation
@@ -723,7 +729,9 @@ extern "C"
MLIL_SET_VAR_FIELD, // Not valid in SSA form (see MLIL_SET_VAR_FIELD)
MLIL_SET_VAR_SPLIT, // Not valid in SSA form (see MLIL_SET_VAR_SPLIT_SSA)
MLIL_LOAD, // Not valid in SSA form (see MLIL_LOAD_SSA)
+ MLIL_LOAD_STRUCT, // Not valid in SSA form (see MLIL_LOAD_STRUCT_SSA)
MLIL_STORE, // Not valid in SSA form (see MLIL_STORE_SSA)
+ MLIL_STORE_STRUCT, // Not valid in SSA form (see MLIL_STORE_STRUCT_SSA)
MLIL_VAR, // Not valid in SSA form (see MLIL_VAR_SSA)
MLIL_VAR_FIELD, // Not valid in SSA form (see MLIL_VAR_SSA_FIELD)
MLIL_ADDRESS_OF,
@@ -808,7 +816,9 @@ extern "C"
MLIL_CALL_PARAM_SSA, // Only valid within the MLIL_CALL_SSA, MLIL_SYSCALL_SSA family instructions
MLIL_CALL_OUTPUT_SSA, // Only valid within the MLIL_CALL_SSA or MLIL_SYSCALL_SSA family instructions
MLIL_LOAD_SSA,
+ MLIL_LOAD_STRUCT_SSA,
MLIL_STORE_SSA,
+ MLIL_STORE_STRUCT_SSA,
MLIL_VAR_PHI,
MLIL_MEM_PHI
};
@@ -816,6 +826,7 @@ extern "C"
struct BNMediumLevelILInstruction
{
BNMediumLevelILOperation operation;
+ uint32_t sourceOperand;
size_t size;
uint64_t operands[5];
uint64_t address;
@@ -962,6 +973,7 @@ extern "C"
uint64_t value;
size_t size, operand;
BNInstructionTextTokenContext context;
+ uint8_t confidence;
uint64_t address;
};
@@ -1080,10 +1092,41 @@ extern "C"
char* (*serialize)(void* ctxt);
};
+ struct BNTypeWithConfidence
+ {
+ BNType* type;
+ uint8_t confidence;
+ };
+
+ struct BNCallingConventionWithConfidence
+ {
+ BNCallingConvention* convention;
+ uint8_t confidence;
+ };
+
+ struct BNBoolWithConfidence
+ {
+ bool value;
+ uint8_t confidence;
+ };
+
+ struct BNMemberScopeWithConfidence
+ {
+ BNMemberScope value;
+ uint8_t confidence;
+ };
+
+ struct BNMemberAccessWithConfidence
+ {
+ BNMemberAccess value;
+ uint8_t confidence;
+ };
+
struct BNNameAndType
{
char* name;
BNType* type;
+ uint8_t typeConfidence;
};
struct BNQualifiedNameAndType
@@ -1097,6 +1140,7 @@ extern "C"
BNType* type;
char* name;
uint64_t offset;
+ uint8_t typeConfidence;
};
struct BNEnumerationMember
@@ -1199,15 +1243,18 @@ extern "C"
BNType* type;
char* name;
bool autoDefined;
+ uint8_t typeConfidence;
};
struct BNStackVariableReference
{
uint32_t sourceOperand;
+ uint8_t typeConfidence;
BNType* type;
char* name;
uint64_t varIdentifier;
int64_t referencedOffset;
+ size_t size;
};
struct BNIndirectBranchInfo
@@ -2034,8 +2081,10 @@ extern "C"
BINARYNINJACOREAPI BNVariableNameAndType* BNGetStackLayout(BNFunction* func, size_t* count);
BINARYNINJACOREAPI void BNFreeVariableList(BNVariableNameAndType* vars, size_t count);
- BINARYNINJACOREAPI void BNCreateAutoStackVariable(BNFunction* func, int64_t offset, BNType* type, const char* name);
- BINARYNINJACOREAPI void BNCreateUserStackVariable(BNFunction* func, int64_t offset, BNType* type, const char* name);
+ BINARYNINJACOREAPI void BNCreateAutoStackVariable(BNFunction* func, int64_t offset,
+ BNTypeWithConfidence* type, const char* name);
+ BINARYNINJACOREAPI void BNCreateUserStackVariable(BNFunction* func, int64_t offset,
+ BNTypeWithConfidence* type, const char* name);
BINARYNINJACOREAPI void BNDeleteAutoStackVariable(BNFunction* func, int64_t offset);
BINARYNINJACOREAPI void BNDeleteUserStackVariable(BNFunction* func, int64_t offset);
BINARYNINJACOREAPI bool BNGetStackVariableAtFrameOffset(BNFunction* func, BNArchitecture* arch, uint64_t addr,
@@ -2043,13 +2092,13 @@ extern "C"
BINARYNINJACOREAPI void BNFreeVariableNameAndType(BNVariableNameAndType* var);
BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count);
- BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNType* type,
+ BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNTypeWithConfidence* type,
const char* name, bool ignoreDisjointUses);
- BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNType* type,
+ BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNTypeWithConfidence* type,
const char* name, bool ignoreDisjointUses);
BINARYNINJACOREAPI void BNDeleteAutoVariable(BNFunction* func, const BNVariable* var);
BINARYNINJACOREAPI void BNDeleteUserVariable(BNFunction* func, const BNVariable* var);
- BINARYNINJACOREAPI BNType* BNGetVariableType(BNFunction* func, const BNVariable* var);
+ BINARYNINJACOREAPI BNTypeWithConfidence BNGetVariableType(BNFunction* func, const BNVariable* var);
BINARYNINJACOREAPI char* BNGetVariableName(BNFunction* func, const BNVariable* var);
BINARYNINJACOREAPI uint64_t BNToVariableIdentifier(const BNVariable* var);
BINARYNINJACOREAPI BNVariable BNFromVariableIdentifier(uint64_t id);
@@ -2100,8 +2149,8 @@ extern "C"
BNLinearDisassemblyPosition* pos, BNDisassemblySettings* settings, size_t* count);
BINARYNINJACOREAPI void BNFreeLinearDisassemblyLines(BNLinearDisassemblyLine* lines, size_t count);
- BINARYNINJACOREAPI void BNDefineDataVariable(BNBinaryView* view, uint64_t addr, BNType* type);
- BINARYNINJACOREAPI void BNDefineUserDataVariable(BNBinaryView* view, uint64_t addr, BNType* type);
+ BINARYNINJACOREAPI void BNDefineDataVariable(BNBinaryView* view, uint64_t addr, BNTypeWithConfidence* type);
+ BINARYNINJACOREAPI void BNDefineUserDataVariable(BNBinaryView* view, uint64_t addr, BNTypeWithConfidence* type);
BINARYNINJACOREAPI void BNUndefineDataVariable(BNBinaryView* view, uint64_t addr);
BINARYNINJACOREAPI void BNUndefineUserDataVariable(BNBinaryView* view, uint64_t addr);
BINARYNINJACOREAPI BNDataVariable* BNGetDataVariables(BNBinaryView* view, size_t* count);
@@ -2344,6 +2393,8 @@ extern "C"
BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func);
BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func);
+ BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr);
+ BINARYNINJACOREAPI size_t BNGetMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr);
BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr);
@@ -2402,6 +2453,11 @@ extern "C"
BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAMemoryUses(BNMediumLevelILFunction* func,
size_t version, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableDefinitions(BNMediumLevelILFunction* func,
+ const BNVariable* var, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableUses(BNMediumLevelILFunction* func,
+ const BNVariable* var, size_t* count);
+
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func,
const BNVariable* var, size_t version);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr);
@@ -2455,20 +2511,23 @@ extern "C"
BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr);
BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr);
+ BINARYNINJACOREAPI BNTypeWithConfidence BNGetMediumLevelILExprType(BNMediumLevelILFunction* func, size_t expr);
+
// Types
BINARYNINJACOREAPI BNType* BNCreateVoidType(void);
BINARYNINJACOREAPI BNType* BNCreateBoolType(void);
- BINARYNINJACOREAPI BNType* BNCreateIntegerType(size_t width, bool sign, const char* altName);
+ BINARYNINJACOREAPI BNType* BNCreateIntegerType(size_t width, BNBoolWithConfidence* sign, const char* altName);
BINARYNINJACOREAPI BNType* BNCreateFloatType(size_t width, const char* altName);
BINARYNINJACOREAPI BNType* BNCreateStructureType(BNStructure* s);
BINARYNINJACOREAPI BNType* BNCreateEnumerationType(BNArchitecture* arch, BNEnumeration* e, size_t width, bool isSigned);
- BINARYNINJACOREAPI BNType* BNCreatePointerType(BNArchitecture* arch, BNType* type, bool cnst, bool vltl,
- BNReferenceType refType);
- BINARYNINJACOREAPI BNType* BNCreatePointerTypeOfWidth(size_t width, BNType* type, bool cnst, bool vltl,
- BNReferenceType refType);
- BINARYNINJACOREAPI BNType* BNCreateArrayType(BNType* type, uint64_t elem);
- BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNType* returnValue, BNCallingConvention* callingConvention,
- BNNameAndType* params, size_t paramCount, bool varArg);
+ BINARYNINJACOREAPI BNType* BNCreatePointerType(BNArchitecture* arch, BNTypeWithConfidence* type,
+ BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType);
+ BINARYNINJACOREAPI BNType* BNCreatePointerTypeOfWidth(size_t width, BNTypeWithConfidence* type,
+ BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType);
+ BINARYNINJACOREAPI BNType* BNCreateArrayType(BNTypeWithConfidence* type, uint64_t elem);
+ BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNTypeWithConfidence* returnValue,
+ BNCallingConventionWithConfidence* callingConvention, BNNameAndType* params,
+ size_t paramCount, bool varArg);
BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type);
BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type);
BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name);
@@ -2479,27 +2538,28 @@ extern "C"
BINARYNINJACOREAPI BNTypeClass BNGetTypeClass(BNType* type);
BINARYNINJACOREAPI uint64_t BNGetTypeWidth(BNType* type);
BINARYNINJACOREAPI size_t BNGetTypeAlignment(BNType* type);
- BINARYNINJACOREAPI bool BNIsTypeSigned(BNType* type);
- BINARYNINJACOREAPI bool BNIsTypeConst(BNType* type);
- BINARYNINJACOREAPI bool BNIsTypeVolatile(BNType* type);
+ BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeSigned(BNType* type);
+ BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeConst(BNType* type);
+ BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeVolatile(BNType* type);
BINARYNINJACOREAPI bool BNIsTypeFloatingPoint(BNType* type);
- BINARYNINJACOREAPI BNType* BNGetChildType(BNType* type);
- BINARYNINJACOREAPI BNCallingConvention* BNGetTypeCallingConvention(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 bool BNTypeHasVariableArguments(BNType* type);
- BINARYNINJACOREAPI bool BNFunctionTypeCanReturn(BNType* type);
+ BINARYNINJACOREAPI BNBoolWithConfidence 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 BNMemberScope BNTypeGetMemberScope(BNType* type);
- BINARYNINJACOREAPI void BNTypeSetMemberScope(BNType* type, BNMemberScope scope);
- BINARYNINJACOREAPI BNMemberAccess BNTypeGetMemberAccess(BNType* type);
- BINARYNINJACOREAPI void BNTypeSetMemberAccess(BNType* type, BNMemberAccess access);
- BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, bool cnst);
- BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, bool vltl);
+ BINARYNINJACOREAPI uint64_t BNGetTypeOffset(BNType* type);
+ BINARYNINJACOREAPI void BNSetFunctionCanReturn(BNType* type, BNBoolWithConfidence* canReturn);
+ BINARYNINJACOREAPI BNMemberScopeWithConfidence BNTypeGetMemberScope(BNType* type);
+ BINARYNINJACOREAPI void BNTypeSetMemberScope(BNType* type, BNMemberScopeWithConfidence* scope);
+ BINARYNINJACOREAPI BNMemberAccessWithConfidence BNTypeGetMemberAccess(BNType* type);
+ BINARYNINJACOREAPI void BNTypeSetMemberAccess(BNType* type, BNMemberAccessWithConfidence* access);
+ BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, BNBoolWithConfidence* cnst);
+ BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, BNBoolWithConfidence* vltl);
BINARYNINJACOREAPI char* BNGetTypeString(BNType* type);
BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type);
@@ -2540,10 +2600,12 @@ extern "C"
BINARYNINJACOREAPI void BNSetStructureType(BNStructure* s, BNStructureType type);
BINARYNINJACOREAPI BNStructureType BNGetStructureType(BNStructure* s);
- 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 BNAddStructureMember(BNStructure* s, BNTypeWithConfidence* type, const char* name);
+ BINARYNINJACOREAPI void BNAddStructureMemberAtOffset(BNStructure* s, BNTypeWithConfidence* 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 void BNReplaceStructureMember(BNStructure* s, size_t idx, BNTypeWithConfidence* type,
+ const char* name);
BINARYNINJACOREAPI BNEnumeration* BNCreateEnumeration(void);
BINARYNINJACOREAPI BNEnumeration* BNNewEnumerationReference(BNEnumeration* e);
diff --git a/binaryview.cpp b/binaryview.cpp
index 522dbe6a..23a62aec 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -84,7 +84,7 @@ void BinaryDataNotification::DataVariableAddedCallback(void* ctxt, BNBinaryView*
Ref<BinaryView> view = new BinaryView(BNNewViewReference(object));
DataVariable varObj;
varObj.address = var->address;
- varObj.type = new Type(BNNewTypeReference(var->type));
+ varObj.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(var->type)), var->typeConfidence);
varObj.autoDiscovered = var->autoDiscovered;
notify->OnDataVariableAdded(view, varObj);
}
@@ -96,7 +96,7 @@ void BinaryDataNotification::DataVariableRemovedCallback(void* ctxt, BNBinaryVie
Ref<BinaryView> view = new BinaryView(BNNewViewReference(object));
DataVariable varObj;
varObj.address = var->address;
- varObj.type = new Type(BNNewTypeReference(var->type));
+ varObj.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(var->type)), var->typeConfidence);
varObj.autoDiscovered = var->autoDiscovered;
notify->OnDataVariableRemoved(view, varObj);
}
@@ -108,7 +108,7 @@ void BinaryDataNotification::DataVariableUpdatedCallback(void* ctxt, BNBinaryVie
Ref<BinaryView> view = new BinaryView(BNNewViewReference(object));
DataVariable varObj;
varObj.address = var->address;
- varObj.type = new Type(BNNewTypeReference(var->type));
+ varObj.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(var->type)), var->typeConfidence);
varObj.autoDiscovered = var->autoDiscovered;
notify->OnDataVariableUpdated(view, varObj);
}
@@ -890,15 +890,21 @@ void BinaryView::AbortAnalysis()
}
-void BinaryView::DefineDataVariable(uint64_t addr, Type* type)
+void BinaryView::DefineDataVariable(uint64_t addr, const Confidence<Ref<Type>>& type)
{
- BNDefineDataVariable(m_object, addr, type->GetObject());
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNDefineDataVariable(m_object, addr, &tc);
}
-void BinaryView::DefineUserDataVariable(uint64_t addr, Type* type)
+void BinaryView::DefineUserDataVariable(uint64_t addr, const Confidence<Ref<Type>>& type)
{
- BNDefineUserDataVariable(m_object, addr, type->GetObject());
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNDefineUserDataVariable(m_object, addr, &tc);
}
@@ -924,7 +930,7 @@ map<uint64_t, DataVariable> BinaryView::GetDataVariables()
{
DataVariable var;
var.address = vars[i].address;
- var.type = new Type(BNNewTypeReference(vars[i].type));
+ var.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(vars[i].type)), vars[i].typeConfidence);
var.autoDiscovered = vars[i].autoDiscovered;
result[var.address] = var;
}
@@ -937,7 +943,7 @@ map<uint64_t, DataVariable> BinaryView::GetDataVariables()
bool BinaryView::GetDataVariableAtAddress(uint64_t addr, DataVariable& var)
{
var.address = 0;
- var.type = nullptr;
+ var.type = Confidence<Ref<Type>>(nullptr, 0);
var.autoDiscovered = false;
BNDataVariable result;
@@ -945,7 +951,7 @@ bool BinaryView::GetDataVariableAtAddress(uint64_t addr, DataVariable& var)
return false;
var.address = result.address;
- var.type = new Type(result.type);
+ var.type = Confidence<Ref<Type>>(new Type(result.type), result.typeConfidence);
var.autoDiscovered = result.autoDiscovered;
return true;
}
@@ -1398,6 +1404,7 @@ vector<LinearDisassemblyLine> BinaryView::GetPreviousLinearDisassemblyLines(Line
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.confidence = lines[i].contents.tokens[j].confidence;
token.address = lines[i].contents.tokens[j].address;
line.contents.tokens.push_back(token);
}
@@ -1443,6 +1450,7 @@ vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDi
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.confidence = lines[i].contents.tokens[j].confidence;
token.address = lines[i].contents.tokens[j].address;
line.contents.tokens.push_back(token);
}
diff --git a/function.cpp b/function.cpp
index b570499c..66b2aade 100644
--- a/function.cpp
+++ b/function.cpp
@@ -353,10 +353,12 @@ vector<StackVariableReference> Function::GetStackVariablesReferencedByInstructio
{
StackVariableReference ref;
ref.sourceOperand = refs[i].sourceOperand;
- ref.type = refs[i].type ? new Type(BNNewTypeReference(refs[i].type)) : nullptr;
+ ref.type = Confidence<Ref<Type>>(refs[i].type ? new Type(BNNewTypeReference(refs[i].type)) : nullptr,
+ refs[i].typeConfidence);
ref.name = refs[i].name;
ref.var = Variable::FromIdentifier(refs[i].varIdentifier);
ref.referencedOffset = refs[i].referencedOffset;
+ ref.size = refs[i].size;
result.push_back(ref);
}
@@ -491,7 +493,7 @@ map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout()
{
VariableNameAndType var;
var.name = vars[i].name;
- var.type = new Type(BNNewTypeReference(vars[i].type));
+ var.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(vars[i].type)), vars[i].typeConfidence);
var.var = vars[i].var;
var.autoDefined = vars[i].autoDefined;
result[vars[i].var.storage].push_back(var);
@@ -502,15 +504,21 @@ map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout()
}
-void Function::CreateAutoStackVariable(int64_t offset, Ref<Type> type, const string& name)
+void Function::CreateAutoStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const string& name)
{
- BNCreateAutoStackVariable(m_object, offset, type->GetObject(), name.c_str());
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNCreateAutoStackVariable(m_object, offset, &tc, name.c_str());
}
-void Function::CreateUserStackVariable(int64_t offset, Ref<Type> type, const string& name)
+void Function::CreateUserStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const string& name)
{
- BNCreateUserStackVariable(m_object, offset, type->GetObject(), name.c_str());
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNCreateUserStackVariable(m_object, offset, &tc, name.c_str());
}
@@ -533,7 +541,7 @@ bool Function::GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr,
if (!BNGetStackVariableAtFrameOffset(m_object, arch->GetObject(), addr, offset, &var))
return false;
- result.type = new Type(BNNewTypeReference(var.type));
+ result.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(var.type)), var.typeConfidence);
result.name = var.name;
result.var = var.var;
result.autoDefined = var.autoDefined;
@@ -553,7 +561,7 @@ map<Variable, VariableNameAndType> Function::GetVariables()
{
VariableNameAndType var;
var.name = vars[i].name;
- var.type = new Type(BNNewTypeReference(vars[i].type));
+ var.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(vars[i].type)), vars[i].typeConfidence);
var.var = vars[i].var;
var.autoDefined = vars[i].autoDefined;
result[vars[i].var] = var;
@@ -564,15 +572,23 @@ map<Variable, VariableNameAndType> Function::GetVariables()
}
-void Function::CreateAutoVariable(const Variable& var, Ref<Type> type, const string& name, bool ignoreDisjointUses)
+void Function::CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type,
+ const string& name, bool ignoreDisjointUses)
{
- BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses);
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNCreateAutoVariable(m_object, &var, &tc, name.c_str(), ignoreDisjointUses);
}
-void Function::CreateUserVariable(const Variable& var, Ref<Type> type, const string& name, bool ignoreDisjointUses)
+void Function::CreateUserVariable(const Variable& var, const Confidence<Ref<Type>>& type,
+ const string& name, bool ignoreDisjointUses)
{
- BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses);
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNCreateUserVariable(m_object, &var, &tc, name.c_str(), ignoreDisjointUses);
}
@@ -588,12 +604,12 @@ void Function::DeleteUserVariable(const Variable& var)
}
-Ref<Type> Function::GetVariableType(const Variable& var)
+Confidence<Ref<Type>> Function::GetVariableType(const Variable& var)
{
- BNType* type = BNGetVariableType(m_object, &var);
- if (!type)
+ BNTypeWithConfidence type = BNGetVariableType(m_object, &var);
+ if (!type.type)
return nullptr;
- return new Type(type);
+ return Confidence<Ref<Type>>(new Type(type.type), type.confidence);
}
@@ -694,6 +710,7 @@ vector<vector<InstructionTextToken>> Function::GetBlockAnnotations(Architecture*
token.size = lines[i].tokens[j].size;
token.operand = lines[i].tokens[j].operand;
token.context = lines[i].tokens[j].context;
+ token.confidence = lines[i].tokens[j].confidence;
token.address = lines[i].tokens[j].address;
line.push_back(token);
}
diff --git a/functiongraphblock.cpp b/functiongraphblock.cpp
index 938fb635..20b2515b 100644
--- a/functiongraphblock.cpp
+++ b/functiongraphblock.cpp
@@ -102,6 +102,7 @@ const vector<DisassemblyTextLine>& FunctionGraphBlock::GetLines()
token.size = lines[i].tokens[j].size;
token.operand = lines[i].tokens[j].operand;
token.context = lines[i].tokens[j].context;
+ token.confidence = lines[i].tokens[j].confidence;
token.address = lines[i].tokens[j].address;
line.tokens.push_back(token);
}
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index c48b5b92..0cb733ac 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -658,6 +658,7 @@ bool LowLevelILFunction::GetExprText(Architecture* arch, ExprId expr, vector<Ins
token.size = list[i].size;
token.operand = list[i].operand;
token.context = list[i].context;
+ token.confidence = list[i].confidence;
token.address = list[i].address;
tokens.push_back(token);
}
@@ -686,6 +687,7 @@ bool LowLevelILFunction::GetInstructionText(Function* func, Architecture* arch,
token.size = list[i].size;
token.operand = list[i].operand;
token.context = list[i].context;
+ token.confidence = list[i].confidence;
token.address = list[i].address;
tokens.push_back(token);
}
@@ -953,6 +955,18 @@ Ref<MediumLevelILFunction> LowLevelILFunction::GetMappedMediumLevelIL() const
}
+size_t LowLevelILFunction::GetMediumLevelILInstructionIndex(size_t instr) const
+{
+ return BNGetMediumLevelILInstructionIndex(m_object, instr);
+}
+
+
+size_t LowLevelILFunction::GetMediumLevelILExprIndex(size_t expr) const
+{
+ return BNGetMediumLevelILExprIndex(m_object, expr);
+}
+
+
size_t LowLevelILFunction::GetMappedMediumLevelILInstructionIndex(size_t instr) const
{
return BNGetMappedMediumLevelILInstructionIndex(m_object, instr);
diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp
index 75c99a54..b4abaa72 100644
--- a/mediumlevelil.cpp
+++ b/mediumlevelil.cpp
@@ -178,6 +178,7 @@ bool MediumLevelILFunction::GetExprText(Architecture* arch, ExprId expr, vector<
token.size = list[i].size;
token.operand = list[i].operand;
token.context = list[i].context;
+ token.confidence = list[i].confidence;
token.address = list[i].address;
tokens.push_back(token);
}
@@ -206,6 +207,7 @@ bool MediumLevelILFunction::GetInstructionText(Function* func, Architecture* arc
token.size = list[i].size;
token.operand = list[i].operand;
token.context = list[i].context;
+ token.confidence = list[i].confidence;
token.address = list[i].address;
tokens.push_back(token);
}
@@ -311,6 +313,34 @@ set<size_t> MediumLevelILFunction::GetSSAMemoryUses(size_t version) const
}
+set<size_t> MediumLevelILFunction::GetVariableDefinitions(const Variable& var) const
+{
+ size_t count;
+ size_t* instrs = BNGetMediumLevelILVariableDefinitions(m_object, &var, &count);
+
+ set<size_t> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(instrs[i]);
+
+ BNFreeILInstructionList(instrs);
+ return result;
+}
+
+
+set<size_t> MediumLevelILFunction::GetVariableUses(const Variable& var) const
+{
+ size_t count;
+ size_t* instrs = BNGetMediumLevelILVariableUses(m_object, &var, &count);
+
+ set<size_t> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(instrs[i]);
+
+ BNFreeILInstructionList(instrs);
+ return result;
+}
+
+
RegisterValue MediumLevelILFunction::GetSSAVarValue(const Variable& var, size_t version)
{
BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var, version);
@@ -492,3 +522,12 @@ size_t MediumLevelILFunction::GetLowLevelILExprIndex(size_t expr) const
{
return BNGetLowLevelILExprIndex(m_object, expr);
}
+
+
+Confidence<Ref<Type>> MediumLevelILFunction::GetExprType(size_t expr)
+{
+ BNTypeWithConfidence result = BNGetMediumLevelILExprType(m_object, expr);
+ if (!result.type)
+ return nullptr;
+ return Confidence<Ref<Type>>(new Type(result.type), result.confidence);
+}
diff --git a/python/architecture.py b/python/architecture.py
index 416fa362..fa235985 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -478,6 +478,7 @@ class Architecture(object):
token_buf[i].size = tokens[i].size
token_buf[i].operand = tokens[i].operand
token_buf[i].context = tokens[i].context
+ token_buf[i].confidence = tokens[i].confidence
token_buf[i].address = tokens[i].address
result[0] = token_buf
ptr = ctypes.cast(token_buf, ctypes.c_void_p)
@@ -1163,8 +1164,9 @@ class Architecture(object):
size = tokens[i].size
operand = tokens[i].operand
context = tokens[i].context
+ confidence = tokens[i].confidence
address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
core.BNFreeInstructionText(tokens, count.value)
return result, length.value
diff --git a/python/basicblock.py b/python/basicblock.py
index 178e473a..4a5caa14 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -308,8 +308,9 @@ class BasicBlock(object):
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
context = lines[i].tokens[j].context
+ confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
- tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
result.append(function.DisassemblyTextLine(addr, tokens))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
diff --git a/python/binaryview.py b/python/binaryview.py
index c2163162..31fb8d73 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))
+ var_type = types.Type(core.BNNewTypeReference(var[0].type), 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))
+ var_type = types.Type(core.BNNewTypeReference(var[0].type), 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))
+ var_type = types.Type(core.BNNewTypeReference(var[0].type), confidence = var[0].typeConfidence)
auto_discovered = var[0].autoDiscovered
self.notify.data_var_updated(self.view, DataVariable(address, var_type, auto_discovered))
except:
@@ -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))
+ var_type = types.Type(core.BNNewTypeReference(var_list[i].type), 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)
@@ -1846,7 +1846,10 @@ class BinaryView(object):
>>> bv.define_data_var(bv.entry_point, t[0])
>>>
"""
- core.BNDefineDataVariable(self.handle, addr, var_type.handle)
+ tc = core.BNTypeWithConfidence()
+ tc.type = var_type.handle
+ tc.confidence = var_type.confidence
+ core.BNDefineDataVariable(self.handle, addr, tc)
def define_user_data_var(self, addr, var_type):
"""
@@ -1863,7 +1866,10 @@ class BinaryView(object):
>>> bv.define_user_data_var(bv.entry_point, t[0])
>>>
"""
- core.BNDefineUserDataVariable(self.handle, addr, var_type.handle)
+ tc = core.BNTypeWithConfidence()
+ tc.type = var_type.handle
+ tc.confidence = var_type.confidence
+ core.BNDefineUserDataVariable(self.handle, addr, tc)
def undefine_data_var(self, addr):
"""
@@ -1909,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), var.autoDiscovered)
+ return DataVariable(var.address, types.Type(var.type, confidence = var.typeConfidence), var.autoDiscovered)
def get_functions_containing(self, addr):
"""
@@ -2796,8 +2802,9 @@ class BinaryView(object):
size = lines[i].contents.tokens[j].size
operand = lines[i].contents.tokens[j].operand
context = lines[i].contents.tokens[j].context
+ confidence = lines[i].contents.tokens[j].confidence
address = lines[i].contents.tokens[j].address
- tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
contents = function.DisassemblyTextLine(addr, tokens)
result.append(lineardisassembly.LinearDisassemblyLine(lines[i].type, func, block, lines[i].lineOffset, contents))
diff --git a/python/callingconvention.py b/python/callingconvention.py
index e9825642..21c8c95a 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -25,6 +25,7 @@ import ctypes
import _binaryninjacore as core
import architecture
import log
+import types
class CallingConvention(object):
@@ -40,7 +41,7 @@ class CallingConvention(object):
_registered_calling_conventions = []
- def __init__(self, arch=None, name=None, handle=None):
+ def __init__(self, arch=None, name=None, handle=None, confidence=types.max_confidence):
if handle is None:
if arch is None or name is None:
raise ValueError("Must specify either handle or architecture and name")
@@ -111,6 +112,8 @@ class CallingConvention(object):
else:
self.__dict__["float_return_reg"] = self.arch.get_reg_name(reg)
+ self.confidence = confidence
+
def __del__(self):
core.BNFreeCallingConvention(self.handle)
@@ -222,3 +225,7 @@ class CallingConvention(object):
def __str__(self):
return self.name
+
+ def with_confidence(self, confidence):
+ return CallingConvention(self.arch, handle = core.BNNewCallingConventionReference(self.handle),
+ confidence = confidence)
diff --git a/python/function.py b/python/function.py
index 398bc652..f0b6faee 100644
--- a/python/function.py
+++ b/python/function.py
@@ -148,12 +148,13 @@ class PossibleValueSet(object):
class StackVariableReference(object):
- def __init__(self, src_operand, t, name, var, ref_ofs):
+ def __init__(self, src_operand, t, name, var, ref_ofs, size):
self.source_operand = src_operand
self.type = t
self.name = name
self.var = var
self.referenced_offset = ref_ofs
+ self.size = size
if self.source_operand == 0xffffffff:
self.source_operand = None
@@ -183,9 +184,11 @@ class Variable(object):
if name is None:
name = core.BNGetVariableName(func.handle, var)
if var_type is None:
- var_type = core.BNGetVariableType(func.handle, var)
- if var_type:
- var_type = types.Type(var_type)
+ 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)
+ else:
+ var_type = None
self.name = name
self.type = var_type
@@ -399,7 +402,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))))
+ types.Type(handle = core.BNNewTypeReference(v[i].type), confidence = v[i].typeConfidence)))
result.sort(key = lambda x: x.identifier)
core.BNFreeVariableList(v, count.value)
return result
@@ -412,7 +415,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))))
+ types.Type(handle = core.BNNewTypeReference(v[i].type), confidence = v[i].typeConfidence)))
result.sort(key = lambda x: x.identifier)
core.BNFreeVariableList(v, count.value)
return result
@@ -629,10 +632,10 @@ 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))
+ var_type = types.Type(core.BNNewTypeReference(refs[i].type), 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].referencedOffset, refs[i].size))
core.BNFreeStackVariableReferenceList(refs, count.value)
return result
@@ -743,8 +746,9 @@ class Function(object):
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
context = lines[i].tokens[j].context
+ confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
- tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address))
+ tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
result.append(tokens)
core.BNFreeInstructionTextLines(lines, count.value)
return result
@@ -866,10 +870,16 @@ class Function(object):
core.BNSetUserInstructionHighlight(self.handle, arch.handle, addr, color._get_core_struct())
def create_auto_stack_var(self, offset, var_type, name):
- core.BNCreateAutoStackVariable(self.handle, offset, var_type.handle, name)
+ tc = core.BNTypeWithConfidence()
+ tc.type = var_type.handle
+ tc.confidence = var_type.confidence
+ core.BNCreateAutoStackVariable(self.handle, offset, tc, name)
def create_user_stack_var(self, offset, var_type, name):
- core.BNCreateUserStackVariable(self.handle, offset, var_type.handle, name)
+ tc = core.BNTypeWithConfidence()
+ tc.type = var_type.handle
+ tc.confidence = var_type.confidence
+ core.BNCreateUserStackVariable(self.handle, offset, tc, name)
def delete_auto_stack_var(self, offset):
core.BNDeleteAutoStackVariable(self.handle, offset)
@@ -882,14 +892,20 @@ class Function(object):
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
- core.BNCreateAutoVariable(self.handle, var_data, var_type.handle, name, ignore_disjoint_uses)
+ tc = core.BNTypeWithConfidence()
+ tc.type = var_type.handle
+ tc.confidence = var_type.confidence
+ core.BNCreateAutoVariable(self.handle, var_data, tc, name, ignore_disjoint_uses)
def create_user_var(self, var, var_type, name, ignore_disjoint_uses = False):
var_data = core.BNVariable()
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
- core.BNCreateUserVariable(self.handle, var_data, var_type.handle, name, ignore_disjoint_uses)
+ tc = core.BNTypeWithConfidence()
+ tc.type = var_type.handle
+ tc.confidence = var_type.confidence
+ core.BNCreateUserVariable(self.handle, var_data, tc, name, ignore_disjoint_uses)
def delete_auto_var(self, var):
var_data = core.BNVariable()
@@ -912,7 +928,7 @@ 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)))
+ found_var.name, types.Type(handle = core.BNNewTypeReference(found_var.type), confidence = found_var.typeConfidence))
core.BNFreeVariableNameAndType(found_var)
return result
@@ -1056,8 +1072,9 @@ class FunctionGraphBlock(object):
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
context = lines[i].tokens[j].context
+ confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
- tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address))
+ tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
result.append(DisassemblyTextLine(addr, tokens))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
@@ -1114,8 +1131,9 @@ class FunctionGraphBlock(object):
size = lines[i].tokens[j].size
operand = lines[i].tokens[j].operand
context = lines[i].tokens[j].context
+ confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
- tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address))
+ tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
yield DisassemblyTextLine(addr, tokens)
finally:
core.BNFreeDisassemblyTextLines(lines, count.value)
@@ -1397,13 +1415,14 @@ class InstructionTextToken(object):
"""
def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff,
- context = InstructionTextTokenContext.NoTokenContext, address = 0):
+ context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence):
self.type = InstructionTextTokenType(token_type)
self.text = text
self.value = value
self.size = size
self.operand = operand
self.context = InstructionTextTokenContext(context)
+ self.confidence = confidence
self.address = address
def __str__(self):
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 33a85a97..9f532e6f 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -309,8 +309,9 @@ class LowLevelILInstruction(object):
size = tokens[i].size
operand = tokens[i].operand
context = tokens[i].context
+ confidence = tokens[i].confidence
address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
core.BNFreeInstructionText(tokens, count.value)
return result
@@ -327,8 +328,16 @@ class LowLevelILInstruction(object):
core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index))
@property
+ def medium_level_il(self):
+ """Gets the medium level IL expression corresponding to this expression (may be None for eliminated instructions)"""
+ expr = self.function.get_medium_level_il_expr_index(self.expr_index)
+ if expr is None:
+ return None
+ return mediumlevelil.MediumLevelILInstruction(self.function.medium_level_il, expr)
+
+ @property
def mapped_medium_level_il(self):
- """Gets the medium level IL expression corresponding to this expression"""
+ """Gets the mapped medium level IL expression corresponding to this expression"""
expr = self.function.get_mapped_medium_level_il_expr_index(self.expr_index)
if expr is None:
return None
@@ -1652,6 +1661,24 @@ class LowLevelILFunction(object):
result = function.RegisterValue(self.arch, value)
return result
+ def get_medium_level_il_instruction_index(self, instr):
+ med_il = self.medium_level_il
+ if med_il is None:
+ return None
+ result = core.BNGetMediumLevelILInstructionIndex(self.handle, instr)
+ if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle):
+ return None
+ return result
+
+ def get_medium_level_il_expr_index(self, expr):
+ med_il = self.medium_level_il
+ if med_il is None:
+ return None
+ result = core.BNGetMediumLevelILExprIndex(self.handle, expr)
+ if result >= core.BNGetMediumLevelILExprCount(med_il.handle):
+ return None
+ return result
+
def get_mapped_medium_level_il_instruction_index(self, instr):
med_il = self.mapped_medium_level_il
if med_il is None:
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 5b5617aa..eefbe787 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -26,6 +26,7 @@ from .enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDep
import function
import basicblock
import lowlevelil
+import types
class SSAVariable(object):
@@ -79,7 +80,9 @@ class MediumLevelILInstruction(object):
MediumLevelILOperation.MLIL_SET_VAR_FIELD: [("dest", "var"), ("offset", "int"), ("src", "expr")],
MediumLevelILOperation.MLIL_SET_VAR_SPLIT: [("high", "var"), ("low", "var"), ("src", "expr")],
MediumLevelILOperation.MLIL_LOAD: [("src", "expr")],
+ MediumLevelILOperation.MLIL_LOAD_STRUCT: [("src", "expr"), ("offset", "int")],
MediumLevelILOperation.MLIL_STORE: [("dest", "expr"), ("src", "expr")],
+ MediumLevelILOperation.MLIL_STORE_STRUCT: [("dest", "expr"), ("offset", "int"), ("src", "expr")],
MediumLevelILOperation.MLIL_VAR: [("src", "var")],
MediumLevelILOperation.MLIL_VAR_FIELD: [("src", "var"), ("offset", "int")],
MediumLevelILOperation.MLIL_ADDRESS_OF: [("src", "var")],
@@ -162,7 +165,9 @@ class MediumLevelILInstruction(object):
MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "var_ssa_list")],
MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src_memory", "int"), ("src", "var_ssa_list")],
MediumLevelILOperation.MLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")],
+ MediumLevelILOperation.MLIL_LOAD_STRUCT_SSA: [("src", "expr"), ("offset", "int"), ("src_memory", "int")],
MediumLevelILOperation.MLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
+ MediumLevelILOperation.MLIL_STORE_STRUCT_SSA: [("dest", "expr"), ("offset", "int"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var_ssa"), ("src", "var_ssa_list")],
MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")]
}
@@ -178,6 +183,7 @@ class MediumLevelILInstruction(object):
self.operation = MediumLevelILOperation(instr.operation)
self.size = instr.size
self.address = instr.address
+ self.source_operand = instr.sourceOperand
operands = MediumLevelILInstruction.ILOperations[instr.operation]
self.operands = []
i = 0
@@ -274,8 +280,9 @@ class MediumLevelILInstruction(object):
size = tokens[i].size
operand = tokens[i].operand
context = tokens[i].context
+ confidence = tokens[i].confidence
address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
core.BNFreeInstructionText(tokens, count.value)
return result
@@ -405,6 +412,14 @@ class MediumLevelILInstruction(object):
result += operand.vars_read
return result
+ @property
+ def expr_type(self):
+ """Type of expression"""
+ result = core.BNGetMediumLevelILExprType(self.function.handle, self.expr_index)
+ if result.type:
+ return types.Type(result.type, confidence = result.confidence)
+ return None
+
def get_ssa_var_possible_values(self, ssa_var):
var_data = core.BNVariable()
var_data.type = ssa_var.var.source_type
@@ -792,6 +807,32 @@ class MediumLevelILFunction(object):
core.BNFreeILInstructionList(instrs)
return result
+ def get_var_definitions(self, var):
+ count = ctypes.c_ulonglong()
+ var_data = core.BNVariable()
+ var_data.type = var.source_type
+ var_data.index = var.index
+ var_data.storage = var.storage
+ instrs = core.BNGetMediumLevelILVariableDefinitions(self.handle, var_data, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(instrs[i])
+ core.BNFreeILInstructionList(instrs)
+ return result
+
+ def get_var_uses(self, var):
+ count = ctypes.c_ulonglong()
+ var_data = core.BNVariable()
+ var_data.type = var.source_type
+ var_data.index = var.index
+ var_data.storage = var.storage
+ instrs = core.BNGetMediumLevelILVariableUses(self.handle, var_data, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(instrs[i])
+ core.BNFreeILInstructionList(instrs)
+ return result
+
def get_ssa_var_value(self, ssa_var):
var_data = core.BNVariable()
var_data.type = ssa_var.var.source_type
diff --git a/python/types.py b/python/types.py
index 84f38c91..47d99bee 100644
--- a/python/types.py
+++ b/python/types.py
@@ -18,11 +18,13 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+max_confidence = 255
+
import ctypes
# Binary Ninja components
import _binaryninjacore as core
-from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType
+from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType, ReferenceType
import callingconvention
import function
@@ -198,8 +200,9 @@ class Symbol(object):
class Type(object):
- def __init__(self, handle):
+ def __init__(self, handle, confidence = max_confidence):
self.handle = handle
+ self.confidence = confidence
def __del__(self):
core.BNFreeType(self.handle)
@@ -232,12 +235,14 @@ class Type(object):
@property
def signed(self):
"""Wether type is signed (read-only)"""
- return core.BNIsTypeSigned(self.handle)
+ result = core.BNIsTypeSigned(self.handle)
+ return BoolWithConfidence(result.value, confidence = result.confidence)
@property
def const(self):
"""Whether type is const (read-only)"""
- return core.BNIsTypeConst(self.handle)
+ result = core.BNIsTypeConst(self.handle)
+ return BoolWithConfidence(result.value, confidence = result.confidence)
@property
def modified(self):
@@ -248,33 +253,33 @@ class Type(object):
def target(self):
"""Target (read-only)"""
result = core.BNGetChildType(self.handle)
- if result is None:
+ if not result.type:
return None
- return Type(result)
+ return Type(result.type, confidence = result.confidence)
@property
def element_type(self):
"""Target (read-only)"""
result = core.BNGetChildType(self.handle)
- if result is None:
+ if not result.type:
return None
- return Type(result)
+ return Type(result.type, confidence = result.confidence)
@property
def return_value(self):
"""Return value (read-only)"""
result = core.BNGetChildType(self.handle)
- if result is None:
+ if not result.type:
return None
- return Type(result)
+ return Type(result.type, confidence = result.confidence)
@property
def calling_convention(self):
"""Calling convention (read-only)"""
result = core.BNGetTypeCallingConvention(self.handle)
- if result is None:
+ if not result.convention:
return None
- return callingconvention.CallingConvention(handle=result)
+ return callingconvention.CallingConvention(None, handle = result, confidence = result.confidence)
@property
def parameters(self):
@@ -283,7 +288,7 @@ 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)), params[i].name))
+ result.append((Type(core.BNNewTypeReference(params[i].type), confidence = params[i].typeConfidence), params[i].name))
core.BNFreeTypeParameterList(params, count.value)
return result
@@ -295,7 +300,8 @@ class Type(object):
@property
def can_return(self):
"""Whether type can return (read-only)"""
- return core.BNFunctionTypeCanReturn(self.handle)
+ result = core.BNFunctionTypeCanReturn(self.handle)
+ return BoolWithConfidence(result.value, confidence = result.confidence)
@property
def structure(self):
@@ -326,10 +332,17 @@ class Type(object):
"""Type count (read-only)"""
return core.BNGetTypeElementCount(self.handle)
+ @property
+ def offset(self):
+ """Offset into structure (read-only)"""
+ return core.BNGetTypeOffset(self.handle)
+
def __str__(self):
return core.BNGetTypeString(self.handle)
def __repr__(self):
+ if self.confidence < max_confidence:
+ return "<type: %s, %d%% confidence>" % (str(self), (self.confidence * 100) / max_confidence)
return "<type: %s>" % str(self)
def get_string_before_name(self):
@@ -351,8 +364,9 @@ class Type(object):
size = tokens[i].size
operand = tokens[i].operand
context = tokens[i].context
+ confidence = tokens[i].confidence
address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
core.BNFreeTokenList(tokens, count.value)
return result
@@ -367,8 +381,9 @@ class Type(object):
size = tokens[i].size
operand = tokens[i].operand
context = tokens[i].context
+ confidence = tokens[i].confidence
address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
core.BNFreeTokenList(tokens, count.value)
return result
@@ -383,8 +398,9 @@ class Type(object):
size = tokens[i].size
operand = tokens[i].operand
context = tokens[i].context
+ confidence = tokens[i].confidence
address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
core.BNFreeTokenList(tokens, count.value)
return result
@@ -397,14 +413,23 @@ class Type(object):
return Type(core.BNCreateBoolType())
@classmethod
- def int(self, width, sign = True, altname=""):
+ def int(self, width, sign = None, altname=""):
"""
``int`` class method for creating an int Type.
:param int width: width of the integer in bytes
:param bool sign: optional variable representing signedness
"""
- return Type(core.BNCreateIntegerType(width, sign, altname))
+ if sign is None:
+ sign = BoolWithConfidence(True, confidence = 0)
+ elif not isinstance(sign, BoolWithConfidence):
+ sign = BoolWithConfidence(sign)
+
+ sign_conf = core.BNBoolWithConfidence()
+ sign_conf.value = sign.value
+ sign_conf.confidence = sign.confidence
+
+ return Type(core.BNCreateIntegerType(width, sign_conf, altname))
@classmethod
def float(self, width):
@@ -444,12 +469,40 @@ class Type(object):
return Type(core.BNCreateEnumerationType(e.handle, width))
@classmethod
- def pointer(self, arch, t, const=False):
- return Type(core.BNCreatePointerType(arch.handle, t.handle, const))
+ def pointer(self, arch, t, const=None, volatile=None, ref_type=None):
+ if const is None:
+ const = BoolWithConfidence(False, confidence = 0)
+ elif not isinstance(const, BoolWithConfidence):
+ const = BoolWithConfidence(const)
+
+ if volatile is None:
+ volatile = BoolWithConfidence(False, confidence = 0)
+ elif not isinstance(volatile, BoolWithConfidence):
+ volatile = BoolWithConfidence(volatile)
+
+ if ref_type is None:
+ ref_type = ReferenceType.PointerReferenceType
+
+ type_conf = core.BNTypeWithConfidence()
+ type_conf.type = t.handle
+ type_conf.confidence = t.confidence
+
+ const_conf = core.BNBoolWithConfidence()
+ const_conf.value = const.value
+ const_conf.confidence = const.confidence
+
+ volatile_conf = core.BNBoolWithConfidence()
+ volatile_conf.value = volatile.value
+ volatile_conf.confidence = volatile.confidence
+
+ return Type(core.BNCreatePointerType(arch.handle, type_conf, const_conf, volatile_conf, ref_type))
@classmethod
def array(self, t, count):
- return Type(core.BNCreateArrayType(t.handle, count))
+ type_conf = core.BNTypeWithConfidence()
+ type_conf.type = t.handle
+ type_conf.confidence = t.confidence
+ return Type(core.BNCreateArrayType(type_conf, count))
@classmethod
def function(self, ret, params, calling_convention=None, variable_arguments=False):
@@ -466,13 +519,26 @@ class Type(object):
if isinstance(params[i], Type):
param_buf[i].name = ""
param_buf[i].type = params[i].handle
+ param_buf[i].typeConfidence = params[i].confidence
else:
param_buf[i].name = params[i][1]
- param_buf[i].type = params[i][0]
- if calling_convention is not None:
- calling_convention = calling_convention.handle
- return Type(core.BNCreateFunctionType(ret.handle, calling_convention, param_buf, len(params),
- variable_arguments))
+ param_buf[i].type = params[i][0].handle
+ param_buf[i].typeConfidence = params[i][0].confidence
+
+ ret_conf = core.BNTypeWithConfidence()
+ ret_conf.type = ret.handle
+ ret_conf.confidence = ret.confidence
+
+ conv_conf = core.BNCallingConventionWithConfidence()
+ if calling_convention is None:
+ conv_conf.convention = None
+ conv_conf.confidence = 0
+ else:
+ conv_conf.convention = calling_convention.handle
+ conv_conf.confidence = calling_convention.confidence
+
+ return Type(core.BNCreateFunctionType(ret_conf, conv_conf, param_buf, len(params),
+ variable_arguments))
@classmethod
def generate_auto_type_id(self, source, name):
@@ -488,6 +554,9 @@ class Type(object):
def get_auto_demanged_type_id_source(self):
return core.BNGetAutoDemangledTypeIdSource()
+ def with_confidence(self, confidence):
+ return Type(handle = core.BNNewTypeReference(self.handle), confidence = confidence)
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
@@ -495,6 +564,36 @@ class Type(object):
raise AttributeError("attribute '%s' is read only" % name)
+class BoolWithConfidence(object):
+ def __init__(self, value, confidence = max_confidence):
+ self.value = value
+ self.confidence = confidence
+
+ def __str__(self):
+ return str(self.value)
+
+ def __repr__(self):
+ return repr(self.value)
+
+ def __bool__(self):
+ return self.value
+
+ def __nonzero__(self):
+ return self.value
+
+
+class ReferenceTypeWithConfidence(object):
+ def __init__(self, value, confidence = max_confidence):
+ self.value = value
+ self.confidence = confidence
+
+ def __str__(self):
+ return str(self.value)
+
+ def __repr__(self):
+ return repr(self.value)
+
+
class NamedTypeReference(object):
def __init__(self, type_class = NamedTypeReferenceClass.UnknownNamedTypeClass, type_id = None, name = None, handle = None):
if handle is None:
@@ -611,7 +710,7 @@ class Structure(object):
members = core.BNGetStructureMembers(self.handle, count)
result = []
for i in xrange(0, count.value):
- result.append(StructureMember(Type(core.BNNewTypeReference(members[i].type)),
+ result.append(StructureMember(Type(core.BNNewTypeReference(members[i].type), confidence = members[i].typeConfidence),
members[i].name, members[i].offset))
core.BNFreeStructureMemberList(members, count.value)
return result
@@ -664,16 +763,25 @@ class Structure(object):
return "<struct: size %#x>" % self.width
def append(self, t, name = ""):
- core.BNAddStructureMember(self.handle, t.handle, name)
+ tc = core.BNTypeWithConfidence()
+ tc.type = t.handle
+ tc.confidence = t.confidence
+ core.BNAddStructureMember(self.handle, tc, name)
def insert(self, offset, t, name = ""):
- core.BNAddStructureMemberAtOffset(self.handle, t.handle, name, offset)
+ tc = core.BNTypeWithConfidence()
+ tc.type = t.handle
+ tc.confidence = t.confidence
+ core.BNAddStructureMemberAtOffset(self.handle, tc, name, offset)
def remove(self, i):
core.BNRemoveStructureMember(self.handle, i)
def replace(self, i, t, name = ""):
- core.BNReplaceStructureMember(self.handle, i, t.handle, name)
+ tc = core.BNTypeWithConfidence()
+ tc.type = t.handle
+ tc.confidence = t.confidence
+ core.BNReplaceStructureMember(self.handle, i, tc, name)
class EnumerationMember(object):
diff --git a/type.cpp b/type.cpp
index 6e55bb69..19624cdd 100644
--- a/type.cpp
+++ b/type.cpp
@@ -261,15 +261,17 @@ size_t Type::GetAlignment() const
}
-bool Type::IsSigned() const
+Confidence<bool> Type::IsSigned() const
{
- return BNIsTypeSigned(m_object);
+ BNBoolWithConfidence result = BNIsTypeSigned(m_object);
+ return Confidence<bool>(result.value, result.confidence);
}
-bool Type::IsConst() const
+Confidence<bool> Type::IsConst() const
{
- return BNIsTypeConst(m_object);
+ BNBoolWithConfidence result = BNIsTypeConst(m_object);
+ return Confidence<bool>(result.value, result.confidence);
}
@@ -279,56 +281,70 @@ bool Type::IsFloat() const
}
-BNMemberScope Type::GetScope() const
+Confidence<BNMemberScope> Type::GetScope() const
{
- return BNTypeGetMemberScope(m_object);
+ BNMemberScopeWithConfidence result = BNTypeGetMemberScope(m_object);
+ return Confidence<BNMemberScope>(result.value, result.confidence);
}
-void Type::SetScope(BNMemberScope scope)
+void Type::SetScope(const Confidence<BNMemberScope>& scope)
{
- return BNTypeSetMemberScope(m_object, scope);
+ BNMemberScopeWithConfidence mc;
+ mc.value = scope.GetValue();
+ mc.confidence = scope.GetConfidence();
+ return BNTypeSetMemberScope(m_object, &mc);
}
-BNMemberAccess Type::GetAccess() const
+Confidence<BNMemberAccess> Type::GetAccess() const
{
- return BNTypeGetMemberAccess(m_object);
+ BNMemberAccessWithConfidence result = BNTypeGetMemberAccess(m_object);
+ return Confidence<BNMemberAccess>(result.value, result.confidence);
}
-void Type::SetAccess(BNMemberAccess access)
+void Type::SetAccess(const Confidence<BNMemberAccess>& access)
{
- return BNTypeSetMemberAccess(m_object, access);
+ BNMemberAccessWithConfidence mc;
+ mc.value = access.GetValue();
+ mc.confidence = access.GetConfidence();
+ return BNTypeSetMemberAccess(m_object, &mc);
}
-void Type::SetConst(bool cnst)
+void Type::SetConst(const Confidence<bool>& cnst)
{
- BNTypeSetConst(m_object, cnst);
+ BNBoolWithConfidence bc;
+ bc.value = cnst.GetValue();
+ bc.confidence = cnst.GetConfidence();
+ BNTypeSetConst(m_object, &bc);
}
-void Type::SetVolatile(bool vltl)
+void Type::SetVolatile(const Confidence<bool>& vltl)
{
- BNTypeSetVolatile(m_object, vltl);
+ BNBoolWithConfidence bc;
+ bc.value = vltl.GetValue();
+ bc.confidence = vltl.GetConfidence();
+ BNTypeSetVolatile(m_object, &bc);
}
-Ref<Type> Type::GetChildType() const
+Confidence<Ref<Type>> Type::GetChildType() const
{
- BNType* type = BNGetChildType(m_object);
- if (type)
- return new Type(type);
+ BNTypeWithConfidence type = BNGetChildType(m_object);
+ if (type.type)
+ return Confidence<Ref<Type>>(new Type(type.type), type.confidence);
return nullptr;
}
-Ref<CallingConvention> Type::GetCallingConvention() const
+Confidence<Ref<CallingConvention>> Type::GetCallingConvention() const
{
- BNCallingConvention* cc = BNGetTypeCallingConvention(m_object);
- if (cc)
- return new CoreCallingConvention(cc);
+ BNCallingConventionWithConfidence cc = BNGetTypeCallingConvention(m_object);
+ if (cc.convention)
+ return Confidence<Ref<CallingConvention>>(new CoreCallingConvention(cc.convention), cc.confidence);
return nullptr;
}
@@ -343,7 +359,7 @@ vector<NameAndType> Type::GetParameters() const
{
NameAndType param;
param.name = types[i].name;
- param.type = new Type(BNNewTypeReference(types[i].type));
+ param.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(types[i].type)), types[i].typeConfidence);
result.push_back(param);
}
@@ -358,9 +374,10 @@ bool Type::HasVariableArguments() const
}
-bool Type::CanReturn() const
+Confidence<bool> Type::CanReturn() const
{
- return BNFunctionTypeCanReturn(m_object);
+ BNBoolWithConfidence result = BNFunctionTypeCanReturn(m_object);
+ return Confidence<bool>(result.value, result.confidence);
}
@@ -397,6 +414,12 @@ uint64_t Type::GetElementCount() const
}
+uint64_t Type::GetOffset() const
+{
+ return BNGetTypeOffset(m_object);
+}
+
+
string Type::GetString() const
{
char* str = BNGetTypeString(m_object);
@@ -447,6 +470,7 @@ vector<InstructionTextToken> Type::GetTokens() const
token.size = tokens[i].size;
token.operand = tokens[i].operand;
token.context = tokens[i].context;
+ token.confidence = tokens[i].confidence;
token.address = tokens[i].address;
result.push_back(token);
}
@@ -471,6 +495,7 @@ vector<InstructionTextToken> Type::GetTokensBeforeName() const
token.size = tokens[i].size;
token.operand = tokens[i].operand;
token.context = tokens[i].context;
+ token.confidence = tokens[i].confidence;
token.address = tokens[i].address;
result.push_back(token);
}
@@ -495,6 +520,7 @@ vector<InstructionTextToken> Type::GetTokensAfterName() const
token.size = tokens[i].size;
token.operand = tokens[i].operand;
token.context = tokens[i].context;
+ token.confidence = tokens[i].confidence;
token.address = tokens[i].address;
result.push_back(token);
}
@@ -522,9 +548,12 @@ Ref<Type> Type::BoolType()
}
-Ref<Type> Type::IntegerType(size_t width, bool sign, const string& altName)
+Ref<Type> Type::IntegerType(size_t width, const Confidence<bool>& sign, const string& altName)
{
- return new Type(BNCreateIntegerType(width, sign, altName.c_str()));
+ BNBoolWithConfidence bc;
+ bc.value = sign.GetValue();
+ bc.confidence = sign.GetConfidence();
+ return new Type(BNCreateIntegerType(width, &bc, altName.c_str()));
}
@@ -577,45 +606,86 @@ Ref<Type> Type::EnumerationType(Architecture* arch, Enumeration* enm, size_t wid
}
-Ref<Type> Type::PointerType(Architecture* arch, Type* type, bool cnst, bool vltl, BNReferenceType refType)
+Ref<Type> Type::PointerType(Architecture* arch, const Confidence<Ref<Type>>& type,
+ const Confidence<bool>& cnst, const Confidence<bool>& vltl, BNReferenceType refType)
{
- return new Type(BNCreatePointerType(arch->GetObject(), type->GetObject(), cnst, vltl, refType));
+ BNTypeWithConfidence typeConf;
+ typeConf.type = type->GetObject();
+ typeConf.confidence = type.GetConfidence();
+
+ BNBoolWithConfidence cnstConf;
+ cnstConf.value = cnst.GetValue();
+ cnstConf.confidence = cnst.GetConfidence();
+
+ BNBoolWithConfidence vltlConf;
+ vltlConf.value = vltl.GetValue();
+ vltlConf.confidence = vltl.GetConfidence();
+
+ return new Type(BNCreatePointerType(arch->GetObject(), &typeConf, &cnstConf, &vltlConf, refType));
}
-Ref<Type> Type::PointerType(size_t width, Type* type, bool cnst, bool vltl, BNReferenceType refType)
+Ref<Type> Type::PointerType(size_t width, const Confidence<Ref<Type>>& type,
+ const Confidence<bool>& cnst, const Confidence<bool>& vltl, BNReferenceType refType)
{
- return new Type(BNCreatePointerTypeOfWidth(width, type->GetObject(), cnst, vltl, refType));
+ BNTypeWithConfidence typeConf;
+ typeConf.type = type->GetObject();
+ typeConf.confidence = type.GetConfidence();
+
+ BNBoolWithConfidence cnstConf;
+ cnstConf.value = cnst.GetValue();
+ cnstConf.confidence = cnst.GetConfidence();
+
+ BNBoolWithConfidence vltlConf;
+ vltlConf.value = vltl.GetValue();
+ vltlConf.confidence = vltl.GetConfidence();
+
+ return new Type(BNCreatePointerTypeOfWidth(width, &typeConf, &cnstConf, &vltlConf, refType));
}
-Ref<Type> Type::ArrayType(Type* type, uint64_t elem)
+Ref<Type> Type::ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem)
{
- return new Type(BNCreateArrayType(type->GetObject(), elem));
+ BNTypeWithConfidence typeConf;
+ typeConf.type = type->GetObject();
+ typeConf.confidence = type.GetConfidence();
+ return new Type(BNCreateArrayType(&typeConf, elem));
}
-Ref<Type> Type::FunctionType(Type* returnValue, CallingConvention* callingConvention,
- const std::vector<NameAndType>& params, bool varArg)
+Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue,
+ const Confidence<Ref<CallingConvention>>& callingConvention,
+ const std::vector<NameAndType>& params, bool varArg)
{
+ BNTypeWithConfidence returnValueConf;
+ returnValueConf.type = returnValue->GetObject();
+ returnValueConf.confidence = returnValue.GetConfidence();
+
+ BNCallingConventionWithConfidence callingConventionConf;
+ callingConventionConf.convention = callingConvention ? callingConvention->GetObject() : nullptr;
+ callingConventionConf.confidence = callingConvention.GetConfidence();
+
BNNameAndType* paramArray = new BNNameAndType[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();
}
- Type* type = new Type(BNCreateFunctionType(returnValue->GetObject(),
- callingConvention ? callingConvention->GetObject() : nullptr,
- paramArray, params.size(), varArg));
+ Type* type = new Type(BNCreateFunctionType(&returnValueConf, &callingConventionConf,
+ paramArray, params.size(), varArg));
delete[] paramArray;
return type;
}
-void Type::SetFunctionCanReturn(bool canReturn)
+void Type::SetFunctionCanReturn(const Confidence<bool>& canReturn)
{
- BNSetFunctionCanReturn(m_object, canReturn);
+ BNBoolWithConfidence bc;
+ bc.value = canReturn.GetValue();
+ bc.confidence = canReturn.GetConfidence();
+ BNSetFunctionCanReturn(m_object, &bc);
}
@@ -687,6 +757,12 @@ void Type::SetTypeName(const QualifiedName& names)
}
+Confidence<Ref<Type>> Type::WithConfidence(uint8_t conf)
+{
+ return Confidence<Ref<Type>>(this, conf);
+}
+
+
NamedTypeReference::NamedTypeReference(BNNamedTypeReference* nt)
{
m_object = nt;
@@ -870,15 +946,21 @@ BNStructureType Structure::GetStructureType() const
}
-void Structure::AddMember(Type* type, const string& name)
+void Structure::AddMember(const Confidence<Ref<Type>>& type, const string& name)
{
- BNAddStructureMember(m_object, type->GetObject(), name.c_str());
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNAddStructureMember(m_object, &tc, name.c_str());
}
-void Structure::AddMemberAtOffset(Type* type, const string& name, uint64_t offset)
+void Structure::AddMemberAtOffset(const Confidence<Ref<Type>>& type, const string& name, uint64_t offset)
{
- BNAddStructureMemberAtOffset(m_object, type->GetObject(), name.c_str(), offset);
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNAddStructureMemberAtOffset(m_object, &tc, name.c_str(), offset);
}
@@ -888,9 +970,12 @@ void Structure::RemoveMember(size_t idx)
}
-void Structure::ReplaceMember(size_t idx, Type* type, const std::string& name)
+void Structure::ReplaceMember(size_t idx, const Confidence<Ref<Type>>& type, const std::string& name)
{
- BNReplaceStructureMember(m_object, idx, type->GetObject(), name.c_str());
+ BNTypeWithConfidence tc;
+ tc.type = type->GetObject();
+ tc.confidence = type.GetConfidence();
+ BNReplaceStructureMember(m_object, idx, &tc, name.c_str());
}