summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h35
-rw-r--r--binaryninjacore.h6
-rw-r--r--python/typeprinter.py53
-rw-r--r--typeprinter.cpp93
4 files changed, 187 insertions, 0 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 8cb0a7b2..c59b554a 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -11766,6 +11766,8 @@ namespace BinaryNinja {
static bool GetTypeLinesCallback(void* ctxt, BNType* type, BNBinaryView* data,
BNQualifiedName* name, int lineWidth, bool collapsed,
BNTokenEscapingType escaping, BNTypeDefinitionLine** result, size_t* resultCount);
+ static bool PrintAllTypesCallback(void* ctxt, BNQualifiedName* names, BNType** types, size_t typeCount,
+ BNBinaryView* data, int lineWidth, BNTokenEscapingType escaping, char** result);
static void FreeTokensCallback(void* ctxt, BNInstructionTextToken* tokens, size_t count);
static void FreeStringCallback(void* ctxt, char* string);
static void FreeLinesCallback(void* ctxt, BNTypeDefinitionLine* lines, size_t count);
@@ -11890,6 +11892,37 @@ namespace BinaryNinja {
bool collapsed = false,
BNTokenEscapingType escaping = NoTokenEscapingType
) = 0;
+
+ /*!
+ Print all types to a single big string, including headers, sections, etc
+ \param types All types to print
+ \param data Binary View in which all the types are defined
+ \param lineWidth Maximum width of lines, in characters
+ \param escaping Style of escaping literals which may not be parsable
+ \return All the types in a string
+ */
+ virtual std::string PrintAllTypes(
+ const std::vector<std::pair<QualifiedName, Ref<Type>>>& types,
+ Ref<BinaryView> data,
+ int lineWidth = 80,
+ BNTokenEscapingType escaping = NoTokenEscapingType
+ );
+
+ /*!
+ Default implementation of PrintAllTypes
+ Print all types to a single big string, including headers, sections, etc
+ \param types All types to print
+ \param data Binary View in which all the types are defined
+ \param lineWidth Maximum width of lines, in characters
+ \param escaping Style of escaping literals which may not be parsable
+ \return All the types in a string
+ */
+ std::string DefaultPrintAllTypes(
+ const std::vector<std::pair<QualifiedName, Ref<Type>>>& types,
+ Ref<BinaryView> data,
+ int lineWidth = 80,
+ BNTokenEscapingType escaping = NoTokenEscapingType
+ );
};
/*!
@@ -11919,6 +11952,8 @@ namespace BinaryNinja {
virtual std::vector<TypeDefinitionLine> GetTypeLines(Ref<Type> type,
Ref<BinaryView> data, const QualifiedName& name, int lineWidth,
bool collapsed, BNTokenEscapingType escaping) override;
+ virtual std::string PrintAllTypes(const std::vector<std::pair<QualifiedName, Ref<Type>>>& types,
+ Ref<BinaryView> data, int lineWidth, BNTokenEscapingType escaping) override;
};
// DownloadProvider
diff --git a/binaryninjacore.h b/binaryninjacore.h
index b17af806..876ec84e 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -2572,6 +2572,8 @@ extern "C"
bool (*getTypeLines)(void* ctxt, BNType* type, BNBinaryView* data,
BNQualifiedName* name, int lineWidth, bool collapsed,
BNTokenEscapingType escaping, BNTypeDefinitionLine** result, size_t* resultCount);
+ bool (*printAllTypes)(void* ctxt, BNQualifiedName* names, BNType** types, size_t typeCount,
+ BNBinaryView* data, int lineWidth, BNTokenEscapingType escaping, char** result);
void (*freeTokens)(void* ctxt, BNInstructionTextToken* tokens, size_t count);
void (*freeString)(void* ctxt, char* string);
void (*freeLines)(void* ctxt, BNTypeDefinitionLine* lines, size_t count);
@@ -5550,6 +5552,10 @@ extern "C"
BNType* type, BNBinaryView* data,
BNQualifiedName* name, int lineWidth, bool collapsed,
BNTokenEscapingType escaping, BNTypeDefinitionLine** result, size_t* resultCount);
+ BINARYNINJACOREAPI bool BNTypePrinterPrintAllTypes(BNTypePrinter* printer, BNQualifiedName* names, BNType** types,
+ size_t typeCount, BNBinaryView* data, int lineWidth, BNTokenEscapingType escaping, char** result);
+ BINARYNINJACOREAPI bool BNTypePrinterDefaultPrintAllTypes(BNTypePrinter* printer, BNQualifiedName* names, BNType** types,
+ size_t typeCount, BNBinaryView* data, int lineWidth, BNTokenEscapingType escaping, char** result);
BINARYNINJACOREAPI void BNFreeTypeParserResult(BNTypeParserResult* result);
BINARYNINJACOREAPI void BNFreeTypeParserErrors(BNTypeParserError* errors, size_t count);
diff --git a/python/typeprinter.py b/python/typeprinter.py
index 354084dd..993ac5d0 100644
--- a/python/typeprinter.py
+++ b/python/typeprinter.py
@@ -96,6 +96,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass):
self._cb.getTypeStringBeforeName = self._cb.getTypeStringBeforeName.__class__(self._get_type_string_before_name)
self._cb.getTypeStringAfterName = self._cb.getTypeStringAfterName.__class__(self._get_type_string_after_name)
self._cb.getTypeLines = self._cb.getTypeLines.__class__(self._get_type_lines)
+ self._cb.printAllTypes = self._cb.printAllTypes.__class__(self._print_all_types)
self._cb.freeTokens = self._cb.freeTokens.__class__(self._free_tokens)
self._cb.freeString = self._cb.freeString.__class__(self._free_string)
self._cb.freeLines = self._cb.freeLines.__class__(self._free_lines)
@@ -235,6 +236,27 @@ class TypePrinter(metaclass=_TypePrinterMetaclass):
log_error(traceback.format_exc())
return False
+ def _print_all_types(self, ctxt, names, types_, type_count, data, line_width, escaping, result):
+ try:
+ types_py = []
+ for i in range(type_count):
+ types_py.append((
+ types.QualifiedName._from_core_struct(names[i]),
+ types.Type(handle=core.BNNewTypeReference(types_[i]))
+ ))
+
+ result_py = self.print_all_types(
+ types_py,
+ binaryview.BinaryView(handle=core.BNNewViewReference(data)),
+ line_width, escaping)
+
+ TypePrinter._cached_string = core.cstr(result_py)
+ result[0] = TypePrinter._cached_string
+ return True
+ except:
+ log_error(traceback.format_exc())
+ return False
+
def _free_tokens(self, ctxt, tokens, count):
try:
TypePrinter._cached_tokens = None
@@ -262,6 +284,20 @@ class TypePrinter(metaclass=_TypePrinterMetaclass):
log_error(traceback.format_exc())
return False
+ def _default_print_all_types(self, types_: List[Tuple[types.QualifiedNameType, types.Type]], data: binaryview.BinaryView, line_width = 80, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> str:
+ cpp_names = (core.BNQualifiedName * len(types_))()
+ cpp_types = (ctypes.POINTER(core.BNType) * len(types_))()
+
+ i = 0
+ for (name, type) in types_:
+ cpp_names[i] = types.QualifiedName(name)._to_core_struct()
+ cpp_types[i] = type.handle
+ i += 1
+
+ result = ctypes.c_char_p()
+ core.BNTypePrinterDefaultPrintAllTypes(self.handle, cpp_names, cpp_types, len(types_), data.handle, line_width, ctypes.c_int(escaping), result)
+ return core.pyNativeStr(result.value)
+
def get_type_tokens(self, type: types.Type, platform: Optional[_platform.Platform] = None, name: types.QualifiedNameType = "", base_confidence: int = core.max_confidence, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> List[_function.InstructionTextToken]:
raise NotImplementedError()
@@ -283,6 +319,9 @@ class TypePrinter(metaclass=_TypePrinterMetaclass):
def get_type_lines(self, type: types.Type, data: binaryview.BinaryView, name: types.QualifiedNameType, line_width = 80, collapsed = False, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> List[types.TypeDefinitionLine]:
raise NotImplementedError()
+ def print_all_types(self, types: List[Tuple[types.QualifiedNameType, types.Type]], data: binaryview.BinaryView, line_width = 80, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> str:
+ return self._default_print_all_types(types, data, line_width, escaping)
+
class CoreTypePrinter(TypePrinter):
@@ -388,3 +427,17 @@ class CoreTypePrinter(TypePrinter):
lines.append(line)
core.BNFreeTypeDefinitionLineList(core_lines, count.value)
return lines
+
+ def print_all_types(self, types_: List[Tuple[types.QualifiedNameType, types.Type]], data: binaryview.BinaryView, line_width = 80, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> str:
+ cpp_names = (core.BNQualifiedName * len(types_))()
+ cpp_types = (ctypes.POINTER(core.BNType) * len(types_))()
+
+ i = 0
+ for (name, type) in types_:
+ cpp_names[i] = types.QualifiedName(name)._to_core_struct()
+ cpp_types[i] = type.handle
+ i += 1
+
+ result = ctypes.c_char_p()
+ core.BNTypePrinterPrintAllTypes(self.handle, cpp_names, cpp_types, len(types_), data.handle, line_width, ctypes.c_int(escaping), result)
+ return core.pyNativeStr(result.value)
diff --git a/typeprinter.cpp b/typeprinter.cpp
index aed010b2..3242f323 100644
--- a/typeprinter.cpp
+++ b/typeprinter.cpp
@@ -116,6 +116,22 @@ bool TypePrinter::GetTypeLinesCallback(void* ctxt, BNType* type, BNBinaryView* d
}
+bool TypePrinter::PrintAllTypesCallback(void* ctxt, BNQualifiedName* names, BNType** types, size_t typeCount,
+ BNBinaryView* data, int lineWidth, BNTokenEscapingType escaping, char** result)
+{
+ TypePrinter* printer = (TypePrinter*)ctxt;
+ vector<pair<QualifiedName, Ref<Type>>> apiTypes;
+ for (size_t i = 0; i < typeCount; ++i)
+ {
+ apiTypes.push_back({QualifiedName::FromAPIObject(&names[i]), new Type(types[i])});
+ }
+
+ string resultStr = printer->PrintAllTypes(apiTypes, new BinaryView(data), lineWidth, escaping);
+ *result = BNAllocString(resultStr.c_str());
+ return true;
+}
+
+
void TypePrinter::FreeTokensCallback(void* ctxt, BNInstructionTextToken* tokens, size_t count)
{
InstructionTextToken::FreeInstructionTextTokenList(tokens, count);
@@ -246,6 +262,50 @@ std::string TypePrinter::GetTypeStringAfterName(
}
+std::string TypePrinter::PrintAllTypes(
+ const std::vector<std::pair<QualifiedName, Ref<Type>>>& types,
+ Ref<BinaryView> data,
+ int lineWidth,
+ BNTokenEscapingType escaping
+)
+{
+ return DefaultPrintAllTypes(types, data, lineWidth, escaping);
+}
+
+
+std::string TypePrinter::DefaultPrintAllTypes(
+ const std::vector<std::pair<QualifiedName, Ref<Type>>>& types,
+ Ref<BinaryView> data,
+ int lineWidth,
+ BNTokenEscapingType escaping
+)
+{
+ BNQualifiedName* apiNames = new BNQualifiedName[types.size()];
+ BNType** apiTypes = new BNType*[types.size()];
+
+ for (size_t i = 0; i < types.size(); i ++)
+ {
+ apiNames[i] = types[i].first.GetAPIObject();
+ apiTypes[i] = types[i].second->GetObject();
+ }
+
+ char* resultStr;
+ BNTypePrinterDefaultPrintAllTypes(m_object, apiNames, apiTypes, types.size(), data->GetObject(),
+ lineWidth, escaping, &resultStr);
+
+ for (size_t i = 0; i < types.size(); i ++)
+ {
+ QualifiedName::FreeAPIObject(&apiNames[i]);
+ }
+ delete[] apiTypes;
+ delete[] apiNames;
+
+ std::string result = resultStr;
+ BNFreeString(resultStr);
+ return result;
+}
+
+
CoreTypePrinter::CoreTypePrinter(BNTypePrinter* printer): TypePrinter(printer)
{
@@ -398,3 +458,36 @@ std::vector<TypeDefinitionLine> CoreTypePrinter::GetTypeLines(Ref<Type> type,
return cppLines;
}
+
+
+std::string CoreTypePrinter::PrintAllTypes(
+ const std::vector<std::pair<QualifiedName, Ref<Type>>>& types,
+ Ref<BinaryView> data,
+ int lineWidth,
+ BNTokenEscapingType escaping
+)
+{
+ BNQualifiedName* apiNames = new BNQualifiedName[types.size()];
+ BNType** apiTypes = new BNType*[types.size()];
+
+ for (size_t i = 0; i < types.size(); i ++)
+ {
+ apiNames[i] = types[i].first.GetAPIObject();
+ apiTypes[i] = types[i].second->GetObject();
+ }
+
+ char* resultStr;
+ BNTypePrinterPrintAllTypes(m_object, apiNames, apiTypes, types.size(), data->GetObject(),
+ lineWidth, escaping, &resultStr);
+
+ for (size_t i = 0; i < types.size(); i ++)
+ {
+ QualifiedName::FreeAPIObject(&apiNames[i]);
+ }
+ delete[] apiTypes;
+ delete[] apiNames;
+
+ std::string result = resultStr;
+ BNFreeString(resultStr);
+ return result;
+}