diff options
| -rw-r--r-- | architecture.cpp | 88 | ||||
| -rw-r--r-- | basicblock.cpp | 15 | ||||
| -rw-r--r-- | binaryninjaapi.h | 10 | ||||
| -rw-r--r-- | binaryninjacore.h | 5 | ||||
| -rw-r--r-- | binaryview.cpp | 30 | ||||
| -rw-r--r-- | datarenderer.cpp | 56 | ||||
| -rw-r--r-- | flowgraphnode.cpp | 39 | ||||
| -rw-r--r-- | function.cpp | 34 | ||||
| -rw-r--r-- | lowlevelil.cpp | 16 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 16 | ||||
| -rw-r--r-- | python/architecture.py | 26 | ||||
| -rw-r--r-- | python/basicblock.py | 12 | ||||
| -rw-r--r-- | python/binaryview.py | 12 | ||||
| -rw-r--r-- | python/datarender.py | 27 | ||||
| -rw-r--r-- | python/flowgraph.py | 35 | ||||
| -rw-r--r-- | python/function.py | 71 | ||||
| -rw-r--r-- | python/lowlevelil.py | 12 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 12 | ||||
| -rw-r--r-- | python/types.py | 42 | ||||
| -rw-r--r-- | type.cpp | 28 |
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 @@ -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); } |
