summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2025-07-02 23:48:32 -0400
committerBrian Potchik <brian@vector35.com>2025-07-02 23:48:32 -0400
commit246f1f72ad2418930ac8837f0788d09a2b24ee6b (patch)
treee99fab87b8bec6f8e6f8b60f546c285d41a494c6
parent48e705fd2ea86f985483312fa8ac98d5c5300466 (diff)
Add outlining support for wmemcpy.
-rw-r--r--binaryninjaapi.h3
-rw-r--r--binaryninjacore.h10
-rw-r--r--binaryview.cpp4
-rw-r--r--lang/c/pseudoc.cpp6
-rw-r--r--lang/rust/pseudorust.cpp6
-rw-r--r--python/binaryview.py5
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)