Skip to content

Commit

Permalink
added writeable_only param
Browse files Browse the repository at this point in the history
  • Loading branch information
JeanExtreme002 committed Nov 16, 2023
1 parent bf561b8 commit dad718d
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 5 deletions.
2 changes: 1 addition & 1 deletion PyMemoryEditor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

__author__ = "Jean Loui Bernard Silva de Jesus"
__version__ = "1.5.4"
__version__ = "1.5.5"


from .enums import ScanTypesEnum
Expand Down
4 changes: 4 additions & 0 deletions PyMemoryEditor/linux/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def search_all_memory(
value: Union[bool, int, float, str, bytes, tuple],
scan_type: ScanTypesEnum = ScanTypesEnum.EXACT_VALUE,
progress_information: bool = False,
writeable_only: bool = False,
) -> Generator[Union[int, Tuple[int, dict]], None, None]:
"""
Search the whole memory space, accessible to the process,
Expand Down Expand Up @@ -109,6 +110,9 @@ def search_all_memory(
# Only readable memory pages.
if not b"r" in region["struct"].Privileges: continue

# If writeable_only is True, checks if the memory page is writeable.
if writeable_only and not b"w" in region["struct"].Privileges: continue

memory_total += region["size"]
regions.append(region)

Expand Down
8 changes: 6 additions & 2 deletions PyMemoryEditor/linux/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def search_by_value(
scan_type: ScanTypesEnum = ScanTypesEnum.EXACT_VALUE,
*,
progress_information: bool = False,
writeable_only: bool = False,
) -> Generator[Union[int, Tuple[int, dict]], None, None]:
"""
Search the whole memory space, accessible to the process,
Expand All @@ -76,13 +77,14 @@ def search_by_value(
:param value: value to be queried (bool, int, float, str or bytes).
:param scan_type: the way to compare the values.
:param progress_information: if True, a dictionary with the progress information will be return.
:param writeable_only: if True, search only at writeable memory regions.
"""
if self.__closed: raise ClosedProcess()

if scan_type in [ScanTypesEnum.VALUE_BETWEEN, ScanTypesEnum.NOT_VALUE_BETWEEN]:
raise ValueError("Use the method search_by_value_between(...) to search within a range of values.")

return search_all_memory(self.pid, pytype, bufflength, value, scan_type, progress_information)
return search_all_memory(self.pid, pytype, bufflength, value, scan_type, progress_information, writeable_only)

def search_by_value_between(
self,
Expand All @@ -93,6 +95,7 @@ def search_by_value_between(
*,
not_between: bool = False,
progress_information: bool = False,
writeable_only: bool = False,
) -> Generator[Union[int, Tuple[int, dict]], None, None]:
"""
Search the whole memory space, accessible to the process,
Expand All @@ -104,11 +107,12 @@ def search_by_value_between(
:param end: maximum inclusive value to be queried (bool, int, float, str or bytes).
:param not_between: if True, return only addresses of values that are NOT within the range.
:param progress_information: if True, a dictionary with the progress information will be return.
:param writeable_only: if True, search only at writeable memory regions.
"""
if self.__closed: raise ClosedProcess()

scan_type = ScanTypesEnum.NOT_VALUE_BETWEEN if not_between else ScanTypesEnum.VALUE_BETWEEN
return search_all_memory(self.pid, pytype, bufflength, (start, end), scan_type, progress_information)
return search_all_memory(self.pid, pytype, bufflength, (start, end), scan_type, progress_information, writeable_only)

def write_process_memory(
self,
Expand Down
7 changes: 7 additions & 0 deletions PyMemoryEditor/linux/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# -*- coding: utf-8 -*-

# Read more about proc and memory mapping here:
# https://man7.org/linux/man-pages/man5/proc.5.html

# Read more about iovec here:
# https://man7.org/linux/man-pages/man3/iovec.3type.html

from ctypes import Structure, c_char_p, c_size_t, c_uint, c_void_p


Expand Down
3 changes: 3 additions & 0 deletions PyMemoryEditor/win32/enums/memory_protections.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class MemoryProtectionsEnum(Enum):
# Indicates memory page is readable. (Custom constant)
PAGE_READABLE = PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READWRITE

# Indicates memory page is readable and writeable. (Custom constant)
PAGE_READWRITEABLE = PAGE_EXECUTE_READWRITE | PAGE_READWRITE

# Sets all locations in the pages as invalid targets for CFG. Used along with any execute page protection like
# PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE and PAGE_EXECUTE_WRITECOPY. Any indirect call to locations
# in those pages will fail CFG checks and the process will be terminated. The default behavior for executable pages
Expand Down
4 changes: 4 additions & 0 deletions PyMemoryEditor/win32/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def SearchAllMemory(
value: Union[bool, int, float, str, bytes, tuple],
scan_type: ScanTypesEnum = ScanTypesEnum.EXACT_VALUE,
progress_information: bool = False,
writeable_only: bool = False,
) -> Generator[Union[int, Tuple[int, dict]], None, None]:
"""
Search the whole memory space, accessible to the process,
Expand Down Expand Up @@ -171,6 +172,9 @@ def SearchAllMemory(
if region["struct"].Type != MemoryTypesEnum.MEM_PRIVATE.value: continue
if region["struct"].Protect & MemoryProtectionsEnum.PAGE_READABLE.value == 0: continue

# If writeable_only is True, checks if the memory page is writeable.
if writeable_only and region["struct"].Protect & MemoryProtectionsEnum.PAGE_READWRITEABLE.value == 0: continue

memory_total += region["size"]
regions.append(region)

Expand Down
8 changes: 6 additions & 2 deletions PyMemoryEditor/win32/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def search_by_value(
scan_type: ScanTypesEnum = ScanTypesEnum.EXACT_VALUE,
*,
progress_information: bool = False,
writeable_only: bool = False,
) -> Generator[Union[int, Tuple[int, dict]], None, None]:
"""
Search the whole memory space, accessible to the process,
Expand All @@ -76,6 +77,7 @@ def search_by_value(
:param value: value to be queried (bool, int, float, str or bytes).
:param scan_type: the way to compare the values.
:param progress_information: if True, a dictionary with the progress information will be return.
:param writeable_only: if True, search only at writeable memory regions.
"""
if self.__closed: raise ClosedProcess()

Expand All @@ -89,7 +91,7 @@ def search_by_value(
if scan_type in [ScanTypesEnum.VALUE_BETWEEN, ScanTypesEnum.NOT_VALUE_BETWEEN]:
raise ValueError("Use the method search_by_value_between(...) to search within a range of values.")

return SearchAllMemory(self.__process_handle, pytype, bufflength, value, scan_type, progress_information)
return SearchAllMemory(self.__process_handle, pytype, bufflength, value, scan_type, progress_information, writeable_only)

def search_by_value_between(
self,
Expand All @@ -100,6 +102,7 @@ def search_by_value_between(
*,
not_between: bool = False,
progress_information: bool = False,
writeable_only: bool = False,
) -> Generator[Union[int, Tuple[int, dict]], None, None]:
"""
Search the whole memory space, accessible to the process,
Expand All @@ -111,6 +114,7 @@ def search_by_value_between(
:param end: maximum inclusive value to be queried (bool, int, float, str or bytes).
:param not_between: if True, return only addresses of values that are NOT within the range.
:param progress_information: if True, a dictionary with the progress information will be return.
:param writeable_only: if True, search only at writeable memory regions.
"""
if self.__closed: raise ClosedProcess()

Expand All @@ -122,7 +126,7 @@ def search_by_value_between(
raise PermissionError("The handle does not have permission to read the process memory.")

scan_type = ScanTypesEnum.NOT_VALUE_BETWEEN if not_between else ScanTypesEnum.VALUE_BETWEEN
return SearchAllMemory(self.__process_handle, pytype, bufflength, (start, end), scan_type, progress_information)
return SearchAllMemory(self.__process_handle, pytype, bufflength, (start, end), scan_type, progress_information, writeable_only)

def read_process_memory(
self,
Expand Down

0 comments on commit dad718d

Please sign in to comment.