diff options
| author | Brian Potchik <brian@vector35.com> | 2025-07-02 23:48:32 -0400 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2025-07-02 23:48:32 -0400 |
| commit | 246f1f72ad2418930ac8837f0788d09a2b24ee6b (patch) | |
| tree | e99fab87b8bec6f8e6f8b60f546c285d41a494c6 | |
| parent | 48e705fd2ea86f985483312fa8ac98d5c5300466 (diff) | |
Add outlining support for wmemcpy.
| -rw-r--r-- | binaryninjaapi.h | 3 | ||||
| -rw-r--r-- | binaryninjacore.h | 10 | ||||
| -rw-r--r-- | binaryview.cpp | 4 | ||||
| -rw-r--r-- | lang/c/pseudoc.cpp | 6 | ||||
| -rw-r--r-- | lang/rust/pseudorust.cpp | 6 | ||||
| -rw-r--r-- | python/binaryview.py | 5 |
6 files changed, 21 insertions, 13 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index bab743d3..0ca84526 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -7127,8 +7127,7 @@ namespace BinaryNinja { void ClearUserGlobalPointerValue(); void SetUserGlobalPointerValue(const Confidence<RegisterValue>& value); - std::optional<std::pair<std::string, BNStringType>> StringifyUnicodeData( - Architecture* arch, const DataBuffer& buffer, bool allowShortStrings = false); + std::optional<std::pair<std::string, BNStringType>> StringifyUnicodeData(Architecture* arch, const DataBuffer& buffer, bool nullTerminates = true, bool allowShortStrings = false); }; class MemoryMap diff --git a/binaryninjacore.h b/binaryninjacore.h index deca98e5..b2f02949 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,14 +37,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 115 +#define BN_CURRENT_CORE_ABI_VERSION 116 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 115 +#define BN_MINIMUM_CORE_ABI_VERSION 116 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -3582,7 +3582,8 @@ extern "C" BuiltinMemset, BuiltinStrncpy, BuiltinStrcpy, - BuiltinWcscpy + BuiltinWcscpy, + BuiltinWmemcpy } BNBuiltinType; typedef struct BNSegmentInfo { @@ -4394,8 +4395,7 @@ extern "C" BINARYNINJACOREAPI void BNClearUserGlobalPointerValue(BNBinaryView* view); BINARYNINJACOREAPI void BNSetUserGlobalPointerValue(BNBinaryView* view, BNRegisterValueWithConfidence value); - BINARYNINJACOREAPI bool BNStringifyUnicodeData(BNBinaryView* data, BNArchitecture* arch, const BNDataBuffer* buffer, - bool allowShortStrings, char** string, BNStringType* type); + BINARYNINJACOREAPI bool BNStringifyUnicodeData(BNBinaryView* data, BNArchitecture* arch, const BNDataBuffer* buffer, bool nullTerminates, bool allowShortStrings, char** string, BNStringType* type); // Raw binary data view BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryDataView(BNFileMetadata* file); diff --git a/binaryview.cpp b/binaryview.cpp index f2b33dc3..4f6c9354 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -5530,11 +5530,11 @@ void BinaryView::SetUserGlobalPointerValue(const Confidence<RegisterValue>& valu } -optional<pair<string, BNStringType>> BinaryView::StringifyUnicodeData(Architecture* arch, const DataBuffer& buffer, bool allowShortStrings) +optional<pair<string, BNStringType>> BinaryView::StringifyUnicodeData(Architecture* arch, const DataBuffer& buffer, bool nullTerminates, bool allowShortStrings) { char* str = nullptr; BNStringType type = AsciiString; - if (!BNStringifyUnicodeData(m_object, arch ? arch->GetObject() : nullptr, buffer.GetBufferObject(), allowShortStrings, &str, &type)) + if (!BNStringifyUnicodeData(m_object, arch ? arch->GetObject() : nullptr, buffer.GetBufferObject(), nullTerminates, allowShortStrings, &str, &type)) return nullopt; string result(str); diff --git a/lang/c/pseudoc.cpp b/lang/c/pseudoc.cpp index 6f3c58ab..4d585966 100644 --- a/lang/c/pseudoc.cpp +++ b/lang/c/pseudoc.cpp @@ -1260,6 +1260,7 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H const ConstantData& data = instr.GetConstantData<HLIL_CONST_DATA>(); if (auto [db, builtin] = data.ToDataBuffer(); db.GetLength()) { + bool nullTerminates = true; switch (builtin) { case BuiltinStrcpy: @@ -1284,9 +1285,12 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H tokens.Append(BraceToken, "}"); break; } + case BuiltinWmemcpy: + nullTerminates = false; + // FALL_THROUGH default: { - if (auto unicode = GetFunction()->GetView()->StringifyUnicodeData(instr.function->GetArchitecture(), db); unicode.has_value()) + if (auto unicode = GetFunction()->GetView()->StringifyUnicodeData(instr.function->GetArchitecture(), db, nullTerminates); unicode.has_value()) { auto wideStringPrefix = (builtin == BuiltinWcscpy) ? "L" : ""; auto tokenContext = (builtin == BuiltinWcscpy) ? ConstStringDataTokenContext : ConstDataTokenContext; diff --git a/lang/rust/pseudorust.cpp b/lang/rust/pseudorust.cpp index 2f9b751c..429def51 100644 --- a/lang/rust/pseudorust.cpp +++ b/lang/rust/pseudorust.cpp @@ -1278,6 +1278,7 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe const ConstantData& data = instr.GetConstantData<HLIL_CONST_DATA>(); if (auto [db, builtin] = data.ToDataBuffer(); db.GetLength()) { + bool nullTerminates = true; switch (builtin) { case BuiltinStrcpy: @@ -1302,9 +1303,12 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe tokens.Append(BraceToken, "}"); break; } + case BuiltinWmemcpy: + nullTerminates = false; + // FALL_THROUGH default: { - if (auto unicode = GetFunction()->GetView()->StringifyUnicodeData(instr.function->GetArchitecture(), db); unicode.has_value()) + if (auto unicode = GetFunction()->GetView()->StringifyUnicodeData(instr.function->GetArchitecture(), db, nullTerminates); unicode.has_value()) { auto wideStringPrefix = (builtin == BuiltinWcscpy) ? "L" : ""; auto tokenContext = (builtin == BuiltinWcscpy) ? ConstStringDataTokenContext : ConstDataTokenContext; diff --git a/python/binaryview.py b/python/binaryview.py index 7b14b57b..16c2dbfb 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -10141,11 +10141,12 @@ to a the type "tagRECT" found in the typelibrary "winX64common" """ return MemoryMap(handle=self.handle) - def stringify_unicode_data(self, arch: Optional['architecture.Architecture'], buffer: 'databuffer.DataBuffer', allow_short_strings: bool = False) -> Tuple[Optional[str], Optional[StringType]]: + def stringify_unicode_data(self, arch: Optional['architecture.Architecture'], buffer: 'databuffer.DataBuffer', null_terminates: bool = True, allow_short_strings: bool = False) -> Tuple[Optional[str], Optional[StringType]]: """ ``stringify_unicode_data`` converts a buffer of unicode data into a string representation. :param arch: The architecture to use for stringification, or None to use the current architecture of the BinaryView :param buffer: The DataBuffer containing the unicode data to stringify + :param null_terminates: If True, stops stringification at the first null character, otherwise continues until the end of the buffer :param allow_short_strings: If True, allows short strings to be returned, otherwise only long strings are returned :return: A tuple containing the string representation and its type, or (None, None) if the stringification fails :rtype: Tuple[Optional[str], Optional[StringType]] @@ -10156,7 +10157,7 @@ to a the type "tagRECT" found in the typelibrary "winX64common" string_type = ctypes.c_int() if arch is not None: arch = arch.handle - if not core.BNStringifyUnicodeData(self.handle, arch, buffer.handle, allow_short_strings, ctypes.byref(string), ctypes.byref(string_type)): + if not core.BNStringifyUnicodeData(self.handle, arch, buffer.handle, null_terminates, allow_short_strings, ctypes.byref(string), ctypes.byref(string_type)): return None, None result = string.value.decode('utf-8') core.free_string(string) |
