summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp88
-rw-r--r--basicblock.cpp15
-rw-r--r--binaryninjaapi.h10
-rw-r--r--binaryninjacore.h5
-rw-r--r--binaryview.cpp30
-rw-r--r--datarenderer.cpp56
-rw-r--r--flowgraphnode.cpp39
-rw-r--r--function.cpp34
-rw-r--r--lowlevelil.cpp16
-rw-r--r--mediumlevelil.cpp16
-rw-r--r--python/architecture.py26
-rw-r--r--python/basicblock.py12
-rw-r--r--python/binaryview.py12
-rw-r--r--python/datarender.py27
-rw-r--r--python/flowgraph.py35
-rw-r--r--python/function.py71
-rw-r--r--python/lowlevelil.py12
-rw-r--r--python/mediumlevelil.py12
-rw-r--r--python/types.py42
-rw-r--r--type.cpp28
20 files changed, 154 insertions, 432 deletions
diff --git a/architecture.cpp b/architecture.cpp
index d7ab348b..334fda27 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <cstdint>
#include <inttypes.h>
+#include <vector>
#include "binaryninjaapi.h"
using namespace BinaryNinja;
@@ -54,22 +55,73 @@ InstructionTextToken::InstructionTextToken(): type(TextToken), value(0), confide
InstructionTextToken::InstructionTextToken(BNInstructionTextTokenType t, const std::string& txt, uint64_t val,
- 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)
+ size_t s, size_t o, uint8_t c, const vector<string>& n) : type(t), text(txt), value(val), size(s), operand(o), context(NoTokenContext),
+ confidence(c), address(0), typeNames(n)
{
}
InstructionTextToken::InstructionTextToken(BNInstructionTextTokenType t, BNInstructionTextTokenContext ctxt,
- 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)
+ const string& txt, uint64_t a, uint64_t val, size_t s, size_t o, uint8_t c, const vector<string>& n):
+ type(t), text(txt), value(val), size(s), operand(o), context(ctxt), confidence(c), address(a), typeNames(n)
{
}
InstructionTextToken InstructionTextToken::WithConfidence(uint8_t conf)
{
- return InstructionTextToken(type, context, text, address, value, size, operand, conf);
+ return InstructionTextToken(type, context, text, address, value, size, operand, conf, typeNames);
+}
+
+
+static void ConvertInstructionTextToken(const InstructionTextToken& token, BNInstructionTextToken* result)
+{
+ result->type = token.type;
+ result->text = BNAllocString(token.text.c_str());
+ result->value = token.value;
+ result->size = token.size;
+ result->operand = token.operand;
+ result->context = token.context;
+ result->confidence = token.confidence;
+ result->address = token.address;
+ result->typeNames = new char*[token.typeNames.size()];
+ for (size_t i = 0; i < token.typeNames.size(); i++)
+ result->typeNames[i] = BNAllocString(token.typeNames[i].c_str());
+ result->namesCount = token.typeNames.size();
+}
+
+
+BNInstructionTextToken* InstructionTextToken::CreateInstructionTextTokenList(const vector<InstructionTextToken>& tokens)
+{
+ BNInstructionTextToken* result = new BNInstructionTextToken[tokens.size()];
+ for (size_t i = 0; i < tokens.size(); i++)
+ ConvertInstructionTextToken(tokens[i], &result[i]);
+ return result;
+}
+
+
+vector<InstructionTextToken> InstructionTextToken::ConvertAndFreeInstructionTextTokenList(BNInstructionTextToken* tokens, size_t count)
+{
+ auto result = ConvertInstructionTextTokenList(tokens, count);
+ BNFreeInstructionText(tokens, count);
+ return result;
+}
+
+
+vector<InstructionTextToken> InstructionTextToken::ConvertInstructionTextTokenList(const BNInstructionTextToken* tokens, size_t count)
+{
+ vector<InstructionTextToken> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ vector<string> names;
+ names.reserve(tokens[i].namesCount);
+ for (size_t j = 0; j < tokens[i].namesCount; j++)
+ names.push_back(tokens[i].typeNames[j]);
+ result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address, tokens[i].value, tokens[i].size,
+ tokens[i].operand, tokens[i].confidence, names);
+ }
+ return result;
}
@@ -168,27 +220,14 @@ bool Architecture::GetInstructionTextCallback(void* ctxt, const uint8_t* data, u
}
*count = tokens.size();
- *result = new BNInstructionTextToken[tokens.size()];
- for (size_t i = 0; i < tokens.size(); i++)
- {
- (*result)[i].type = tokens[i].type;
- (*result)[i].text = BNAllocString(tokens[i].text.c_str());
- (*result)[i].value = tokens[i].value;
- (*result)[i].size = tokens[i].size;
- (*result)[i].operand = tokens[i].operand;
- (*result)[i].context = tokens[i].context;
- (*result)[i].confidence = tokens[i].confidence;
- (*result)[i].address = tokens[i].address;
- }
+ *result = InstructionTextToken::CreateInstructionTextTokenList(tokens);
return true;
}
void Architecture::FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count)
{
- for (size_t i = 0; i < count; i++)
- BNFreeString(tokens[i].text);
- delete[] tokens;
+ BNFreeInstructionText(tokens, count);
}
@@ -1312,14 +1351,7 @@ bool CoreArchitecture::GetInstructionText(const uint8_t* data, uint64_t addr, si
if (!BNGetInstructionText(m_object, data, addr, &len, &tokens, &count))
return false;
- result.reserve(count);
- for (size_t i = 0; i < count; i++)
- {
- result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address,
- tokens[i].value, tokens[i].size, tokens[i].operand, tokens[i].confidence);
- }
-
- BNFreeInstructionText(tokens, count);
+ result = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count);
return true;
}
diff --git a/basicblock.cpp b/basicblock.cpp
index c0ab0c9c..ae92a55d 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -295,20 +295,7 @@ vector<DisassemblyTextLine> BasicBlock::GetDisassemblyText(DisassemblySettings*
line.addr = lines[i].addr;
line.instrIndex = lines[i].instrIndex;
line.highlight = lines[i].highlight;
- line.tokens.reserve(lines[i].count);
- for (size_t j = 0; j < lines[i].count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].tokens[j].type;
- token.text = lines[i].tokens[j].text;
- token.value = lines[i].tokens[j].value;
- token.size = lines[i].tokens[j].size;
- token.operand = lines[i].tokens[j].operand;
- token.context = lines[i].tokens[j].context;
- token.confidence = lines[i].tokens[j].confidence;
- token.address = lines[i].tokens[j].address;
- line.tokens.push_back(token);
- }
+ line.tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(lines[i].tokens, lines[i].count);
result.push_back(line);
}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 18bc4b76..a750cfbb 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1037,18 +1037,24 @@ namespace BinaryNinja
BNInstructionTextTokenContext context;
uint8_t confidence;
uint64_t address;
+ std::vector<std::string> typeNames;
InstructionTextToken();
InstructionTextToken(uint8_t confidence, BNInstructionTextTokenType t, const std::string& txt);
InstructionTextToken(BNInstructionTextTokenType type, const std::string& text, uint64_t value = 0,
- size_t size = 0, size_t operand = BN_INVALID_OPERAND, uint8_t confidence = BN_FULL_CONFIDENCE);
+ size_t size = 0, size_t operand = BN_INVALID_OPERAND, uint8_t confidence = BN_FULL_CONFIDENCE,
+ const std::vector<std::string>& typeName={});
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, uint8_t confidence = BN_FULL_CONFIDENCE);
+ size_t operand = BN_INVALID_OPERAND, uint8_t confidence = BN_FULL_CONFIDENCE, const std::vector<std::string>& typeName={});
InstructionTextToken WithConfidence(uint8_t conf);
+ static BNInstructionTextToken* CreateInstructionTextTokenList(const std::vector<InstructionTextToken>& tokens);
+ static std::vector<InstructionTextToken> ConvertAndFreeInstructionTextTokenList(BNInstructionTextToken* tokens, size_t count);
+ static std::vector<InstructionTextToken> ConvertInstructionTextTokenList(const BNInstructionTextToken* tokens, size_t count);
};
+
struct DisassemblyTextLine
{
uint64_t addr;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index c06d8f8e..5b9bcb03 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1172,6 +1172,8 @@ extern "C"
BNInstructionTextTokenContext context;
uint8_t confidence;
uint64_t address;
+ char** typeNames;
+ size_t namesCount;
};
struct BNInstructionTextLine
@@ -2347,6 +2349,7 @@ extern "C"
BINARYNINJACOREAPI bool BNGetInstructionLowLevelIL(BNArchitecture* arch, const uint8_t* data, uint64_t addr,
size_t* len, BNLowLevelILFunction* il);
BINARYNINJACOREAPI void BNFreeInstructionText(BNInstructionTextToken* tokens, size_t count);
+ BINARYNINJACOREAPI void BNFreeInstructionTextLines(BNInstructionTextLine* lines, size_t count);
BINARYNINJACOREAPI char* BNGetArchitectureRegisterName(BNArchitecture* arch, uint32_t reg);
BINARYNINJACOREAPI char* BNGetArchitectureFlagName(BNArchitecture* arch, uint32_t flag);
BINARYNINJACOREAPI char* BNGetArchitectureFlagWriteTypeName(BNArchitecture* arch, uint32_t flags);
@@ -2677,7 +2680,6 @@ extern "C"
BINARYNINJACOREAPI BNInstructionTextLine* BNGetFunctionBlockAnnotations(BNFunction* func, BNArchitecture* arch,
uint64_t addr, size_t* count);
- BINARYNINJACOREAPI void BNFreeInstructionTextLines(BNInstructionTextLine* lines, size_t count);
BINARYNINJACOREAPI BNIntegerDisplayType BNGetIntegerConstantDisplayType(BNFunction* func, BNArchitecture* arch,
uint64_t instrAddr, uint64_t value, size_t operand);
@@ -3222,7 +3224,6 @@ extern "C"
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);
BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromTypeAndId(const char* id, BNQualifiedName* name, BNType* type);
diff --git a/binaryview.cpp b/binaryview.cpp
index bc8f5050..c8c9d760 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -1772,20 +1772,7 @@ vector<LinearDisassemblyLine> BinaryView::GetPreviousLinearDisassemblyLines(Line
line.contents.addr = lines[i].contents.addr;
line.contents.instrIndex = lines[i].contents.instrIndex;
line.contents.highlight = lines[i].contents.highlight;
- line.contents.tokens.reserve(lines[i].contents.count);
- for (size_t j = 0; j < lines[i].contents.count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].contents.tokens[j].type;
- token.text = lines[i].contents.tokens[j].text;
- token.value = lines[i].contents.tokens[j].value;
- 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);
- }
+ line.contents.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].contents.tokens, lines[i].contents.count);
result.push_back(line);
}
@@ -1822,20 +1809,7 @@ vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDi
line.contents.addr = lines[i].contents.addr;
line.contents.instrIndex = lines[i].contents.instrIndex;
line.contents.highlight = lines[i].contents.highlight;
- line.contents.tokens.reserve(lines[i].contents.count);
- for (size_t j = 0; j < lines[i].contents.count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].contents.tokens[j].type;
- token.text = lines[i].contents.tokens[j].text;
- token.value = lines[i].contents.tokens[j].value;
- 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);
- }
+ line.contents.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].contents.tokens, lines[i].contents.count);
result.push_back(line);
}
diff --git a/datarenderer.cpp b/datarenderer.cpp
index 1fce92a7..fee457e8 100644
--- a/datarenderer.cpp
+++ b/datarenderer.cpp
@@ -59,13 +59,8 @@ BNDisassemblyTextLine* DataRenderer::GetLinesForDataCallback(void* ctxt, BNBinar
DataRenderer* renderer = (DataRenderer*)ctxt;
Ref<BinaryView> viewObj = new BinaryView(BNNewViewReference(view));
Ref<Type> typeObj = new Type(BNNewTypeReference(type));
- vector<InstructionTextToken> prefixes;
- prefixes.reserve(prefixCount);
- for (size_t i = 0; i < prefixCount; i++)
- {
- prefixes.emplace_back(prefix[i].type, prefix[i].context, prefix[i].text, prefix[i].address,
- prefix[i].value, prefix[i].size, prefix[i].operand, prefix[i].confidence);
- }
+ vector<InstructionTextToken> prefixes = InstructionTextToken::ConvertInstructionTextTokenList(prefix, prefixCount);
+
vector<Type*> context;
context.reserve(ctxCount);
for (size_t i = 0; i < ctxCount; i++)
@@ -79,20 +74,8 @@ BNDisassemblyTextLine* DataRenderer::GetLinesForDataCallback(void* ctxt, BNBinar
buf[i].addr = line.addr;
buf[i].instrIndex = line.instrIndex;
buf[i].highlight = line.highlight;
- buf[i].tokens = new BNInstructionTextToken[line.tokens.size()];
+ buf[i].tokens = InstructionTextToken::CreateInstructionTextTokenList(line.tokens);
buf[i].count = line.tokens.size();
- for (size_t j = 0; j < line.tokens.size(); j++)
- {
- const InstructionTextToken& token = line.tokens[j];
- buf[i].tokens[j].type = token.type;
- buf[i].tokens[j].text = BNAllocString(token.text.c_str());
- buf[i].tokens[j].value = token.value;
- buf[i].tokens[j].size = token.size;
- buf[i].tokens[j].operand = token.operand;
- buf[i].tokens[j].context = token.context;
- buf[i].tokens[j].confidence = token.confidence;
- buf[i].tokens[j].address = token.address;
- }
}
return buf;
}
@@ -119,18 +102,7 @@ bool DataRenderer::IsValidForData(BinaryView* data, uint64_t addr, Type* type, v
vector<DisassemblyTextLine> DataRenderer::GetLinesForData(BinaryView* data, uint64_t addr, Type* type,
const std::vector<InstructionTextToken>& prefix, size_t width, vector<Type*>& context)
{
- BNInstructionTextToken* prefixes = new BNInstructionTextToken[prefix.size()];
- for (size_t i = 0; i < prefix.size(); i++)
- {
- prefixes[i].type = prefix[i].type;
- prefixes[i].text = BNAllocString(prefix[i].text.c_str());
- prefixes[i].value = prefix[i].value;
- prefixes[i].size = prefix[i].size;
- prefixes[i].operand = prefix[i].operand;
- prefixes[i].context = prefix[i].context;
- prefixes[i].confidence = prefix[i].confidence;
- prefixes[i].address = prefix[i].address;
- }
+ BNInstructionTextToken* prefixes = InstructionTextToken::CreateInstructionTextTokenList(prefix);
BNType** typeCtx = new BNType*[context.size()];
for (size_t i = 0; i < context.size(); i++)
typeCtx[i] = context[i]->GetObject();
@@ -140,10 +112,7 @@ vector<DisassemblyTextLine> DataRenderer::GetLinesForData(BinaryView* data, uint
prefix.size(), width, &count, typeCtx, context.size());
delete[] typeCtx;
- for (size_t i = 0; i < prefix.size(); i++)
- BNFreeString(prefixes[i].text);
-
- delete[] prefixes;
+ BNFreeInstructionText(prefixes, prefix.size());
vector<DisassemblyTextLine> result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
@@ -152,20 +121,7 @@ vector<DisassemblyTextLine> DataRenderer::GetLinesForData(BinaryView* data, uint
line.addr = lines[i].addr;
line.instrIndex = lines[i].instrIndex;
line.highlight = lines[i].highlight;
- line.tokens.reserve(lines[i].count);
- for (size_t j = 0; j < lines[i].count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].tokens[j].type;
- token.text = lines[i].tokens[j].text;
- token.value = lines[i].tokens[j].value;
- token.size = lines[i].tokens[j].size;
- token.operand = lines[i].tokens[j].operand;
- token.context = lines[i].tokens[j].context;
- token.confidence = lines[i].tokens[j].confidence;
- token.address = lines[i].tokens[j].address;
- line.tokens.push_back(token);
- }
+ line.tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(lines[i].tokens, lines[i].count);
result.push_back(line);
}
return result;
diff --git a/flowgraphnode.cpp b/flowgraphnode.cpp
index 60912df1..649e4941 100644
--- a/flowgraphnode.cpp
+++ b/flowgraphnode.cpp
@@ -95,26 +95,12 @@ const vector<DisassemblyTextLine>& FlowGraphNode::GetLines()
line.addr = lines[i].addr;
line.instrIndex = lines[i].instrIndex;
line.highlight = lines[i].highlight;
- line.tokens.reserve(lines[i].count);
- for (size_t j = 0; j < lines[i].count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].tokens[j].type;
- token.text = lines[i].tokens[j].text;
- token.value = lines[i].tokens[j].value;
- token.size = lines[i].tokens[j].size;
- token.operand = lines[i].tokens[j].operand;
- token.context = lines[i].tokens[j].context;
- token.confidence = lines[i].tokens[j].confidence;
- token.address = lines[i].tokens[j].address;
- line.tokens.push_back(token);
- }
+ line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
result.push_back(line);
}
BNFreeDisassemblyTextLines(lines, count);
m_cachedLines = result;
- m_cachedLinesValid = true;
return m_cachedLines;
}
@@ -128,31 +114,12 @@ void FlowGraphNode::SetLines(const vector<DisassemblyTextLine>& lines)
buf[i].addr = line.addr;
buf[i].instrIndex = line.instrIndex;
buf[i].highlight = line.highlight;
- buf[i].tokens = new BNInstructionTextToken[line.tokens.size()];
+ buf[i].tokens = InstructionTextToken::CreateInstructionTextTokenList(line.tokens);
buf[i].count = line.tokens.size();
- for (size_t j = 0; j < line.tokens.size(); j++)
- {
- const InstructionTextToken& token = line.tokens[j];
- buf[i].tokens[j].type = token.type;
- buf[i].tokens[j].text = BNAllocString(token.text.c_str());
- buf[i].tokens[j].value = token.value;
- buf[i].tokens[j].size = token.size;
- buf[i].tokens[j].operand = token.operand;
- buf[i].tokens[j].context = token.context;
- buf[i].tokens[j].confidence = token.confidence;
- buf[i].tokens[j].address = token.address;
- }
}
BNSetFlowGraphNodeLines(m_object, buf, lines.size());
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- for (size_t j = 0; j < buf[i].count; j++)
- BNFreeString(buf[i].tokens[j].text);
- delete[] buf[i].tokens;
- }
- delete[] buf;
+ BNFreeDisassemblyTextLines(buf, lines.size());
m_cachedLines = lines;
m_cachedLinesValid = true;
diff --git a/function.cpp b/function.cpp
index e17166ff..119ce526 100644
--- a/function.cpp
+++ b/function.cpp
@@ -1132,24 +1132,7 @@ vector<vector<InstructionTextToken>> Function::GetBlockAnnotations(Architecture*
vector<vector<InstructionTextToken>> result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
- {
- vector<InstructionTextToken> line;
- line.reserve(lines[i].count);
- for (size_t j = 0; j < lines[i].count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].tokens[j].type;
- token.text = lines[i].tokens[j].text;
- token.value = lines[i].tokens[j].value;
- token.size = lines[i].tokens[j].size;
- token.operand = lines[i].tokens[j].operand;
- token.context = lines[i].tokens[j].context;
- token.confidence = lines[i].tokens[j].confidence;
- token.address = lines[i].tokens[j].address;
- line.push_back(token);
- }
- result.push_back(line);
- }
+ result.push_back(InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count));
BNFreeInstructionTextLines(lines, count);
return result;
@@ -1353,20 +1336,7 @@ vector<DisassemblyTextLine> Function::GetTypeTokens(DisassemblySettings* setting
line.addr = lines[i].addr;
line.instrIndex = lines[i].instrIndex;
line.highlight = lines[i].highlight;
- line.tokens.reserve(lines[i].count);
- for (size_t j = 0; j < lines[i].count; j++)
- {
- InstructionTextToken token;
- token.type = lines[i].tokens[j].type;
- token.text = lines[i].tokens[j].text;
- token.value = lines[i].tokens[j].value;
- token.size = lines[i].tokens[j].size;
- token.operand = lines[i].tokens[j].operand;
- token.context = lines[i].tokens[j].context;
- token.confidence = lines[i].tokens[j].confidence;
- token.address = lines[i].tokens[j].address;
- line.tokens.push_back(token);
- }
+ line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
result.push_back(line);
}
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index 3e09e085..f710e08f 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -433,13 +433,7 @@ bool LowLevelILFunction::GetExprText(Architecture* arch, ExprId expr, vector<Ins
if (!BNGetLowLevelILExprText(m_object, arch->GetObject(), expr, &list, &count))
return false;
- tokens.clear();
- tokens.reserve(count);
- for (size_t i = 0; i < count; i++)
- tokens.emplace_back(list[i].type, list[i].context, list[i].text, list[i].address, list[i].value, list[i].size,
- list[i].operand, list[i].confidence);
-
- BNFreeInstructionText(list, count);
+ tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, count);
return true;
}
@@ -453,13 +447,7 @@ bool LowLevelILFunction::GetInstructionText(Function* func, Architecture* arch,
instr, &list, &count))
return false;
- tokens.clear();
- tokens.reserve(count);
- for (size_t i = 0; i < count; i++)
- tokens.emplace_back(list[i].type, list[i].context, list[i].text, list[i].address, list[i].value, list[i].size,
- list[i].operand, list[i].confidence);
-
- BNFreeInstructionText(list, count);
+ tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, count);
return true;
}
diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp
index 2d1fe904..b4e648c0 100644
--- a/mediumlevelil.cpp
+++ b/mediumlevelil.cpp
@@ -338,13 +338,7 @@ bool MediumLevelILFunction::GetExprText(Architecture* arch, ExprId expr, vector<
if (!BNGetMediumLevelILExprText(m_object, arch->GetObject(), expr, &list, &count))
return false;
- tokens.clear();
- tokens.reserve(count);
- for (size_t i = 0; i < count; i++)
- tokens.emplace_back(list[i].type, list[i].context, list[i].text, list[i].address, list[i].value, list[i].size,
- list[i].operand, list[i].confidence);
-
- BNFreeInstructionText(list, count);
+ tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, count);
return true;
}
@@ -358,13 +352,7 @@ bool MediumLevelILFunction::GetInstructionText(Function* func, Architecture* arc
instr, &list, &count))
return false;
- tokens.clear();
- tokens.reserve(count);
- for (size_t i = 0; i < count; i++)
- tokens.emplace_back(list[i].type, list[i].context, list[i].text, list[i].address, list[i].value, list[i].size,
- list[i].operand, list[i].confidence);
-
- BNFreeInstructionText(list, count);
+ tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, count);
return true;
}
diff --git a/python/architecture.py b/python/architecture.py
index 7bef1b67..b5daaa6d 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -533,19 +533,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
tokens = info[0]
length[0] = info[1]
count[0] = len(tokens)
- token_buf = (core.BNInstructionTextToken * len(tokens))()
- for i in range(0, len(tokens)):
- if isinstance(tokens[i].type, str):
- token_buf[i].type = InstructionTextTokenType[tokens[i].type]
- else:
- token_buf[i].type = tokens[i].type
- token_buf[i].text = tokens[i].text
- token_buf[i].value = tokens[i].value
- token_buf[i].size = tokens[i].size
- token_buf[i].operand = tokens[i].operand
- token_buf[i].context = tokens[i].context
- token_buf[i].confidence = tokens[i].confidence
- token_buf[i].address = tokens[i].address
+ token_buf = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens)
result[0] = token_buf
ptr = ctypes.cast(token_buf, ctypes.c_void_p)
self._pending_token_lists[ptr.value] = (ptr.value, token_buf)
@@ -2328,17 +2316,7 @@ class CoreArchitecture(Architecture):
tokens = ctypes.POINTER(core.BNInstructionTextToken)()
if not core.BNGetInstructionText(self.handle, buf, addr, length, tokens, count):
return None, 0
- result = []
- for i in range(0, count.value):
- token_type = InstructionTextTokenType(tokens[i].type)
- text = tokens[i].text
- value = tokens[i].value
- size = tokens[i].size
- operand = tokens[i].operand
- context = tokens[i].context
- confidence = tokens[i].confidence
- address = tokens[i].address
- result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
+ result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
core.BNFreeInstructionText(tokens, count.value)
return result, length.value
diff --git a/python/basicblock.py b/python/basicblock.py
index d66a41c2..d68189ab 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -338,17 +338,7 @@ class BasicBlock(object):
else:
il_instr = None
color = highlight.HighlightColor._from_core_struct(lines[i].highlight)
- tokens = []
- for j in range(0, lines[i].count):
- token_type = InstructionTextTokenType(lines[i].tokens[j].type)
- text = lines[i].tokens[j].text
- value = lines[i].tokens[j].value
- 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(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
+ tokens = binaryninja.function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
result.append(binaryninja.function.DisassemblyTextLine(tokens, addr, il_instr, color))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
diff --git a/python/binaryview.py b/python/binaryview.py
index 612632d3..cefe6481 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -3271,17 +3271,7 @@ class BinaryView(object):
block = basicblock.BasicBlock(self, core.BNNewBasicBlockReference(lines[i].block))
color = highlight.HighlightColor._from_core_struct(lines[i].contents.highlight)
addr = lines[i].contents.addr
- tokens = []
- for j in range(0, lines[i].contents.count):
- token_type = InstructionTextTokenType(lines[i].contents.tokens[j].type)
- text = lines[i].contents.tokens[j].text
- value = lines[i].contents.tokens[j].value
- 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(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
+ tokens = binaryninja.function.InstructionTextToken.get_instruction_lines(lines[i].contents.tokens, lines[i].contents.count)
contents = binaryninja.function.DisassemblyTextLine(tokens, addr, color = color)
result.append(lineardisassembly.LinearDisassemblyLine(lines[i].type, func, block, lines[i].lineOffset, contents))
diff --git a/python/datarender.py b/python/datarender.py
index db60f42e..c0a1dd3b 100644
--- a/python/datarender.py
+++ b/python/datarender.py
@@ -112,18 +112,7 @@ class DataRenderer(object):
view = BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(view))
type = Type(handle=core.BNNewTypeReference(type))
- prefixTokens = []
- for i in range(prefixCount):
- token_type = InstructionTextTokenType(prefix[i].type)
- text = prefix[i].text
- value = prefix[i].value
- size = prefix[i].size
- operand = prefix[i].operand
- context = prefix[i].context
- address = prefix[i].address
- confidence = prefix[i].confidence
- prefixTokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
-
+ prefixTokens = InstructionTextToken.get_instruction_lines(prefix, prefixCount)
pycontext = []
for i in range(ctxCount):
pycontext.append(Type(core.BNNewTypeReference(typeCtx[i])))
@@ -140,8 +129,6 @@ class DataRenderer(object):
if isinstance(color, HighlightStandardColor):
color = highlight.HighlightColor(color)
line_buf[i].highlight = color._get_core_struct()
- line_buf[i].count = len(line.tokens)
- line_buf[i].tokens = (core.BNInstructionTextToken * len(line.tokens))()
if line.address is None:
if len(line.tokens) > 0:
line_buf[i].addr = line.tokens[0].address
@@ -153,15 +140,9 @@ class DataRenderer(object):
line_buf[i].instrIndex = line.il_instruction.instr_index
else:
line_buf[i].instrIndex = 0xffffffffffffffff
- for j in range(len(line.tokens)):
- line_buf[i].tokens[j].type = line.tokens[j].type
- line_buf[i].tokens[j].text = line.tokens[j].text
- line_buf[i].tokens[j].value = line.tokens[j].value
- line_buf[i].tokens[j].size = line.tokens[j].size
- line_buf[i].tokens[j].operand = line.tokens[j].operand
- line_buf[i].tokens[j].context = line.tokens[j].context
- line_buf[i].tokens[j].confidence = line.tokens[j].confidence
- line_buf[i].tokens[j].address = line.tokens[j].address
+
+ line_buf[i].count = len(line.tokens)
+ line_buf[i].tokens = InstructionTextToken.get_instruction_lines(line.tokens)
return ctypes.cast(line_buf, ctypes.c_void_p).value
except:
diff --git a/python/flowgraph.py b/python/flowgraph.py
index 79351838..9d786704 100644
--- a/python/flowgraph.py
+++ b/python/flowgraph.py
@@ -128,17 +128,7 @@ class FlowGraphNode(object):
else:
il_instr = None
color = highlight.HighlightColor._from_core_struct(lines[i].highlight)
- tokens = []
- for j in range(0, lines[i].count):
- token_type = InstructionTextTokenType(lines[i].tokens[j].type)
- text = lines[i].tokens[j].text
- value = lines[i].tokens[j].value
- 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, confidence))
+ tokens = function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
result.append(function.DisassemblyTextLine(tokens, addr, il_instr, color))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
@@ -172,16 +162,7 @@ class FlowGraphNode(object):
color = highlight.HighlightColor(color)
line_buf[i].highlight = color._get_core_struct()
line_buf[i].count = len(line.tokens)
- line_buf[i].tokens = (core.BNInstructionTextToken * len(line.tokens))()
- for j in range(0, len(line.tokens)):
- line_buf[i].tokens[j].type = line.tokens[j].type
- line_buf[i].tokens[j].text = line.tokens[j].text
- line_buf[i].tokens[j].value = line.tokens[j].value
- line_buf[i].tokens[j].size = line.tokens[j].size
- line_buf[i].tokens[j].operand = line.tokens[j].operand
- line_buf[i].tokens[j].context = line.tokens[j].context
- line_buf[i].tokens[j].confidence = line.tokens[j].confidence
- line_buf[i].tokens[j].address = line.tokens[j].address
+ line_buf[i].tokens = function.InstructionTextToken.get_instruction_lines(line.tokens)
core.BNSetFlowGraphNodeLines(self.handle, line_buf, len(lines))
@property
@@ -244,17 +225,7 @@ class FlowGraphNode(object):
il_instr = block.il_function[lines[i].instrIndex]
else:
il_instr = None
- tokens = []
- for j in range(0, lines[i].count):
- token_type = InstructionTextTokenType(lines[i].tokens[j].type)
- text = lines[i].tokens[j].text
- value = lines[i].tokens[j].value
- 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, confidence))
+ tokens = function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
yield function.DisassemblyTextLine(tokens, addr, il_instr)
finally:
core.BNFreeDisassemblyTextLines(lines, count.value)
diff --git a/python/function.py b/python/function.py
index bda06091..d1899d18 100644
--- a/python/function.py
+++ b/python/function.py
@@ -1164,7 +1164,7 @@ class Function(object):
count = ctypes.c_ulonglong()
branches = core.BNGetIndirectBranchesAt(self.handle, arch.handle, addr, count)
result = []
- for i in range(0, count.value):
+ for i in range(count.value):
result.append(IndirectBranchInfo(binaryninja.architecture.CoreArchitecture._from_cache(branches[i].sourceArch), branches[i].sourceAddr, binaryninja.architecture.CoreArchitecture._from_cache(branches[i].destArch), branches[i].destAddr, branches[i].autoDefined))
core.BNFreeIndirectBranchList(branches)
return result
@@ -1175,21 +1175,8 @@ class Function(object):
count = ctypes.c_ulonglong(0)
lines = core.BNGetFunctionBlockAnnotations(self.handle, arch.handle, addr, count)
result = []
- for i in range(0, count.value):
- tokens = []
- for j in range(0, lines[i].count):
- token_type = InstructionTextTokenType(lines[i].tokens[j].type)
- text = lines[i].tokens[j].text
- if not isinstance(text, str):
- text = text.encode("charmap")
- value = lines[i].tokens[j].value
- 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, confidence))
- result.append(tokens)
+ for i in range(count.value):
+ result.append(InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count))
core.BNFreeInstructionTextLines(lines, count.value)
return result
@@ -1487,17 +1474,7 @@ class Function(object):
for i in range(0, count.value):
addr = lines[i].addr
color = highlight.HighlightColor._from_core_struct(lines[i].highlight)
- tokens = []
- for j in range(0, lines[i].count):
- token_type = InstructionTextTokenType(lines[i].tokens[j].type)
- text = lines[i].tokens[j].text
- value = lines[i].tokens[j].value
- 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, confidence))
+ tokens = InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
result.append(DisassemblyTextLine(tokens, addr, color = color))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
@@ -1815,7 +1792,7 @@ class InstructionTextToken(object):
"""
def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff,
- context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence):
+ context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence, typeName=""):
self.type = InstructionTextTokenType(token_type)
self.text = text
self.value = value
@@ -1824,6 +1801,44 @@ class InstructionTextToken(object):
self.context = InstructionTextTokenContext(context)
self.confidence = confidence
self.address = address
+ self.typeName = typeName
+
+ @classmethod
+ def get_instruction_lines(cls, tokens, count=0):
+ """ Helper method for converting between core.BNInstructionTextToken and InstructionTextToken lists """
+ if isinstance(tokens, list):
+ result = (core.BNInstructionTextToken * len(tokens))()
+ for j in range(len(tokens)):
+ result.type = tokens[j].type
+ result.text = tokens[j].text
+ result.value = tokens[j].value
+ result.size = tokens[j].size
+ result.operand = tokens[j].operand
+ result.context = tokens[j].context
+ result.confidence = tokens[j].confidence
+ result.address = tokens[j].address
+ result.typeName = tokens[j].typeName
+ return result
+
+ if not isinstance(tokens, core.BNInstructionTextToken):
+ raise TypeError("tokens is not of type core.BNInstructionTextToken")
+ result = []
+ for j in range(count):
+ token_type = InstructionTextTokenType(tokens[j].type)
+ text = tokens[j].text
+ if not isinstance(text, str):
+ text = text.encode("charmap")
+ value = tokens[j].value
+ size = tokens[j].size
+ operand = tokens[j].operand
+ context = tokens[j].context
+ confidence = tokens[j].confidence
+ address = tokens[j].address
+ typeName = tokens[j].typeName
+ if not isinstance(typeName, str):
+ typeName = typeName.encode("charmap")
+ result.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence, typeName))
+ return result
def __str__(self):
return self.text
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index a98de6d3..2a8ba5d0 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -524,17 +524,7 @@ class LowLevelILInstruction(object):
if not core.BNGetLowLevelILExprText(self.function.handle, self.function.arch.handle,
self.expr_index, tokens, count):
return None
- result = []
- for i in range(0, count.value):
- token_type = InstructionTextTokenType(tokens[i].type)
- text = tokens[i].text
- value = tokens[i].value
- size = tokens[i].size
- operand = tokens[i].operand
- context = tokens[i].context
- confidence = tokens[i].confidence
- address = tokens[i].address
- result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
+ result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
core.BNFreeInstructionText(tokens, count.value)
return result
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index c88ab6b8..2dae008a 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -331,17 +331,7 @@ class MediumLevelILInstruction(object):
if not core.BNGetMediumLevelILExprText(self.function.handle, self.function.arch.handle,
self.expr_index, tokens, count):
return None
- result = []
- for i in range(0, count.value):
- token_type = InstructionTextTokenType(tokens[i].type)
- text = tokens[i].text
- value = tokens[i].value
- size = tokens[i].size
- operand = tokens[i].operand
- context = tokens[i].context
- confidence = tokens[i].confidence
- address = tokens[i].address
- result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
+ result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
core.BNFreeInstructionText(tokens, count.value)
return result
diff --git a/python/types.py b/python/types.py
index 05e531e1..e6913f93 100644
--- a/python/types.py
+++ b/python/types.py
@@ -455,18 +455,8 @@ class Type(object):
if self.platform is not None:
platform = self.platform.handle
tokens = core.BNGetTypeTokens(self.handle, platform, base_confidence, count)
- result = []
- for i in range(0, count.value):
- token_type = InstructionTextTokenType(tokens[i].type)
- text = tokens[i].text
- value = tokens[i].value
- size = tokens[i].size
- operand = tokens[i].operand
- context = tokens[i].context
- confidence = tokens[i].confidence
- address = tokens[i].address
- result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
- core.BNFreeTokenList(tokens, count.value)
+ result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
+ core.BNFreeInstructionText(tokens, count.value)
return result
def get_tokens_before_name(self, base_confidence = max_confidence):
@@ -475,18 +465,8 @@ class Type(object):
if self.platform is not None:
platform = self.platform.handle
tokens = core.BNGetTypeTokensBeforeName(self.handle, platform, base_confidence, count)
- result = []
- for i in range(0, count.value):
- token_type = InstructionTextTokenType(tokens[i].type)
- text = tokens[i].text
- value = tokens[i].value
- size = tokens[i].size
- operand = tokens[i].operand
- context = tokens[i].context
- confidence = tokens[i].confidence
- address = tokens[i].address
- result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
- core.BNFreeTokenList(tokens, count.value)
+ result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
+ core.BNFreeInstructionText(tokens, count.value)
return result
def get_tokens_after_name(self, base_confidence = max_confidence):
@@ -495,18 +475,8 @@ class Type(object):
if self.platform is not None:
platform = self.platform.handle
tokens = core.BNGetTypeTokensAfterName(self.handle, platform, base_confidence, count)
- result = []
- for i in range(0, count.value):
- token_type = InstructionTextTokenType(tokens[i].type)
- text = tokens[i].text
- value = tokens[i].value
- size = tokens[i].size
- operand = tokens[i].operand
- context = tokens[i].context
- confidence = tokens[i].confidence
- address = tokens[i].address
- result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
- core.BNFreeTokenList(tokens, count.value)
+ result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
+ core.BNFreeInstructionText(tokens, count.value)
return result
@classmethod
diff --git a/type.cpp b/type.cpp
index ef9036aa..d7c65897 100644
--- a/type.cpp
+++ b/type.cpp
@@ -684,14 +684,7 @@ vector<InstructionTextToken> Type::GetTokens(Platform* platform, uint8_t baseCon
BNInstructionTextToken* tokens = BNGetTypeTokens(m_object,
platform ? platform->GetObject() : nullptr, baseConfidence, &count);
- vector<InstructionTextToken> result;
- result.reserve(count);
- for (size_t i = 0; i < count; i++)
- result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address, tokens[i].value, tokens[i].size,
- tokens[i].operand, tokens[i].confidence);
-
- BNFreeTokenList(tokens, count);
- return result;
+ return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count);
}
@@ -700,15 +693,7 @@ vector<InstructionTextToken> Type::GetTokensBeforeName(Platform* platform, uint8
size_t count;
BNInstructionTextToken* tokens = BNGetTypeTokensBeforeName(m_object,
platform ? platform->GetObject() : nullptr, baseConfidence, &count);
-
- vector<InstructionTextToken> result;
- result.reserve(count);
- for (size_t i = 0; i < count; i++)
- result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address, tokens[i].value, tokens[i].size,
- tokens[i].operand, tokens[i].confidence);
-
- BNFreeTokenList(tokens, count);
- return result;
+ return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count);
}
@@ -718,14 +703,7 @@ vector<InstructionTextToken> Type::GetTokensAfterName(Platform* platform, uint8_
BNInstructionTextToken* tokens = BNGetTypeTokensAfterName(m_object,
platform ? platform->GetObject() : nullptr, baseConfidence, &count);
- vector<InstructionTextToken> result;
- result.reserve(count);
- for (size_t i = 0; i < count; i++)
- result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address, tokens[i].value, tokens[i].size,
- tokens[i].operand, tokens[i].confidence);
-
- BNFreeTokenList(tokens, count);
- return result;
+ return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count);
}