From c5a090f640b9a500c219a4060180da6558ea0e34 Mon Sep 17 00:00:00 2001 From: cromachina <82557197+cromachina@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:11:33 -0400 Subject: [PATCH 1/2] Fix float and bytes conversion from ctypes buffers --- PyMemoryEditor/linux/functions.py | 8 +++++++- PyMemoryEditor/util/convert.py | 7 ++++--- PyMemoryEditor/win32/functions.py | 7 ++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/PyMemoryEditor/linux/functions.py b/PyMemoryEditor/linux/functions.py index d917296..7fde20d 100644 --- a/PyMemoryEditor/linux/functions.py +++ b/PyMemoryEditor/linux/functions.py @@ -67,7 +67,13 @@ def read_process_memory( pid, (iovec * 1)(iovec(addressof(data), sizeof(data))), 1, (iovec * 1)(iovec(address, sizeof(data))), 1, 0 ) - return data.value.decode() if pytype is str else data.value + + if pytype is str: + return data.value.decode() + elif pytype is bytes: + return bytes(data) + else: + return data.value def search_addresses_by_value( diff --git a/PyMemoryEditor/util/convert.py b/PyMemoryEditor/util/convert.py index 224f884..3150fea 100644 --- a/PyMemoryEditor/util/convert.py +++ b/PyMemoryEditor/util/convert.py @@ -32,9 +32,10 @@ def get_c_type_of(pytype: Type, length) -> ctypes._SimpleCData: if length <= 4: return ctypes.c_int32() # 4 Bytes return ctypes.c_int64() # 8 Bytes - # Float values lose their precision when converted to c_float. For that reason, - # any float value will be converted to double. - elif pytype is float: return ctypes.c_double() # 8 Bytes + elif pytype is float: + + if length == 4: return ctypes.c_float() # 4 Bytes + return ctypes.c_double() # 8 Bytes elif pytype is bool: return ctypes.c_bool() diff --git a/PyMemoryEditor/win32/functions.py b/PyMemoryEditor/win32/functions.py index 4f6d860..7926c4a 100644 --- a/PyMemoryEditor/win32/functions.py +++ b/PyMemoryEditor/win32/functions.py @@ -127,7 +127,12 @@ def ReadProcessMemory( data = get_c_type_of(pytype, bufflength) kernel32.ReadProcessMemory(process_handle, ctypes.c_void_p(address), ctypes.byref(data), bufflength, None) - return data.value.decode() if pytype is str else data.value + if pytype is str: + return data.value.decode() + elif pytype is bytes: + return bytes(data) + else: + return data.value def SearchAddressesByValue( From 4f2825ce9709717d9071ccd063da5be6c92618a6 Mon Sep 17 00:00:00 2001 From: cromachina <82557197+cromachina@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:24:18 -0400 Subject: [PATCH 2/2] Decode str from bytes to bypass null terminator --- PyMemoryEditor/linux/functions.py | 2 +- PyMemoryEditor/win32/functions.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PyMemoryEditor/linux/functions.py b/PyMemoryEditor/linux/functions.py index 7fde20d..93bbf4c 100644 --- a/PyMemoryEditor/linux/functions.py +++ b/PyMemoryEditor/linux/functions.py @@ -69,7 +69,7 @@ def read_process_memory( ) if pytype is str: - return data.value.decode() + return bytes(data).decode() elif pytype is bytes: return bytes(data) else: diff --git a/PyMemoryEditor/win32/functions.py b/PyMemoryEditor/win32/functions.py index 7926c4a..6cdf0bc 100644 --- a/PyMemoryEditor/win32/functions.py +++ b/PyMemoryEditor/win32/functions.py @@ -128,7 +128,7 @@ def ReadProcessMemory( kernel32.ReadProcessMemory(process_handle, ctypes.c_void_p(address), ctypes.byref(data), bufflength, None) if pytype is str: - return data.value.decode() + return bytes(data).decode() elif pytype is bytes: return bytes(data) else: