PyMemoryEditor 2.2.0__py3-none-any.whl → 2.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ Supported platforms: Windows, Linux and macOS (32-bit and 64-bit).
8
8
  """
9
9
 
10
10
  __author__ = "Jean Loui Bernard Silva de Jesus"
11
- __version__ = "2.2.0"
11
+ __version__ = "2.2.1"
12
12
 
13
13
  import logging
14
14
  import sys
@@ -311,6 +311,31 @@ _PAGE_GONE_KRS = (
311
311
  KERN_MEMORY_ERROR,
312
312
  )
313
313
 
314
+ # KERN_PROTECTION_FAILURE is tolerated by a full-address-space *sweep* only,
315
+ # never by a read of caller-supplied addresses — hence a second tuple rather
316
+ # than another entry above.
317
+ #
318
+ # The sweeps walk every region the filter accepted and have no opinion about
319
+ # any single one: a range the kernel declines to hand over is a range with no
320
+ # matches in it, and aborting the whole scan over it loses every region that
321
+ # came after. `search_values_by_addresses` is the opposite case — the caller
322
+ # named those addresses, and its documented `raise_error=True` must still be
323
+ # able to report that one of them could not be read. Anything in the tuple
324
+ # above is swallowed even when `raise_error` is set (see
325
+ # process.scanning.iter_values_for_addresses), so putting kr=2 there would
326
+ # silently turn "permission denied" into the same `(address, None)` the caller
327
+ # gets for an address in a gap.
328
+ #
329
+ # Honest limits of what is known here. This was added because a plain
330
+ # search_by_value over the current process died with kr=2 on GitHub's
331
+ # virtualized macOS runners, on a 22 MB region that reported VM_PROT_READ and
332
+ # Shared=False. The mechanism was not established. It does *not* reproduce
333
+ # locally: probing all 135 scannable regions of a live process yields only kr=1
334
+ # and kr=10, and a page deliberately re-protected to PROT_NONE (or never
335
+ # mapped) answers KERN_INVALID_ADDRESS, not kr=2 — so the usual
336
+ # "protection changed under us" story does not explain it.
337
+ _SWEEP_SKIPPABLE_KRS = _PAGE_GONE_KRS + (KERN_PROTECTION_FAILURE,)
338
+
314
339
 
315
340
  class MachReadError(OSError):
316
341
  """OSError subclass that carries the underlying kern_return_t."""
@@ -494,6 +519,14 @@ def _is_transient(exc: BaseException) -> bool:
494
519
  return isinstance(exc, MachReadError) and exc.kr in _PAGE_GONE_KRS
495
520
 
496
521
 
522
+ def _is_skippable_by_sweep(exc: BaseException) -> bool:
523
+ """
524
+ Same as :func:`_is_transient`, plus the codes only a full-address-space
525
+ sweep may skip. See :data:`_SWEEP_SKIPPABLE_KRS`.
526
+ """
527
+ return isinstance(exc, MachReadError) and exc.kr in _SWEEP_SKIPPABLE_KRS
528
+
529
+
497
530
  def _query_region(task: int, address: int):
498
531
  """Return the region containing `address`, or None when the query fails."""
499
532
  addr = mach_vm_address_t(address)
@@ -683,7 +716,7 @@ def search_addresses_by_value(
683
716
  scan_type,
684
717
  _make_read_chunk(task),
685
718
  progress_information=progress_information,
686
- transient_error_check=_is_transient,
719
+ transient_error_check=_is_skippable_by_sweep,
687
720
  )
688
721
 
689
722
 
@@ -1044,7 +1077,7 @@ def search_addresses_by_pattern(
1044
1077
  length,
1045
1078
  _make_read_chunk(task),
1046
1079
  progress_information=progress_information,
1047
- transient_error_check=_is_transient,
1080
+ transient_error_check=_is_skippable_by_sweep,
1048
1081
  )
1049
1082
 
1050
1083
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: PyMemoryEditor
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Read, write and scan process memory in a few lines of Python — Cheat Engine-style scans, pointer chains and AOB search on Windows, Linux and macOS.
5
5
  Project-URL: Homepage, https://github.com/JeanExtreme002/PyMemoryEditor
6
6
  Project-URL: Documentation, https://pymemoryeditor.readthedocs.io
@@ -71,18 +71,19 @@ A pure-Python library (built on [ctypes](https://docs.python.org/3/library/ctype
71
71
  <i>One unified API. Three operating systems. No C compiler. No native build step.</i>
72
72
  </p>
73
73
 
74
- <p align="center">
75
- Runs on <b>🪟 Windows</b> · <b>🐧 Linux</b> · <b>🍎 macOS</b> — 32-bit and 64-bit.
76
- </p>
77
-
78
74
  <p align="center">
79
75
  <a href="https://github.com/JeanExtreme002/PyMemoryEditor/actions/workflows/python-package.yml"><img src="https://github.com/JeanExtreme002/PyMemoryEditor/actions/workflows/python-package.yml/badge.svg" alt="Python Package" /></a>
76
+ <a href="https://codecov.io/gh/JeanExtreme002/PyMemoryEditor"><img src="https://codecov.io/gh/JeanExtreme002/PyMemoryEditor/branch/main/graph/badge.svg" alt="Coverage" /></a>
80
77
  <a href="https://pypi.org/project/PyMemoryEditor/"><img src="https://img.shields.io/pypi/v/PyMemoryEditor" alt="Pypi" /></a>
81
78
  <a href="https://github.com/JeanExtreme002/PyMemoryEditor"><img src="https://img.shields.io/pypi/l/PyMemoryEditor" alt="License" /></a>
82
79
  <a href="https://github.com/JeanExtreme002/PyMemoryEditor"><img src="https://img.shields.io/badge/python-3.10+-8A2BE2" alt="Python Version" /></a>
83
80
  <a href="https://pypi.org/project/PyMemoryEditor/"><img src="https://static.pepy.tech/personalized-badge/pymemoryeditor?period=total&units=international_system&left_color=grey&right_color=orange&left_text=Downloads" alt="Downloads" /></a>
84
81
  </p>
85
82
 
83
+ <p align="center">
84
+ Runs on <b>Windows</b> · <b>Linux</b> · <b>macOS</b> — 32-bit and 64-bit.
85
+ </p>
86
+
86
87
  <p align="center">
87
88
  <img src="https://raw.githubusercontent.com/JeanExtreme002/PyMemoryEditor/main/assets/screenshots/app.png" alt="PyMemoryEditor app attached to a running process" width="820" />
88
89
  </p>
@@ -1,4 +1,4 @@
1
- PyMemoryEditor/__init__.py,sha256=7y6oSpnE3E7iBrwEFhKwUq3cE36-hrNyK1gWL8xY9do,3234
1
+ PyMemoryEditor/__init__.py,sha256=v5k7h66qCdfV3XNjSJ3dwiarLWFLfaMrzWLFftY8dP0,3234
2
2
  PyMemoryEditor/__main__.py,sha256=xukvvLjQ0BnYnnxMZda1cvyZ-BurSUk8dAGQybIqMD4,95
3
3
  PyMemoryEditor/enums.py,sha256=q_SWQYgh4F7yyAa7sZvNo2Sw91TSm3aTqPfTA7OqldM,322
4
4
  PyMemoryEditor/app/__init__.py,sha256=DGCYWpqGKPSeBa7cvzL7GmmhIfDDgF6vtim0VtLcfOo,357
@@ -28,7 +28,7 @@ PyMemoryEditor/linux/libc.py,sha256=U4yOpHJ48OAaDxcVk_s57GGXlvmyakInwM2liegf3OA,
28
28
  PyMemoryEditor/linux/process.py,sha256=_PafbkQHAcwsQlbwcUFd6ERHN_c4wQ3Qcgyt82Gz2Zw,8636
29
29
  PyMemoryEditor/linux/types.py,sha256=sOgO-s9oqKrKKCHMG4N-Pe7sNw49V06PeMENSNnNFl8,1924
30
30
  PyMemoryEditor/macos/__init__.py,sha256=85mOA4U5i9EW2r1ggKqRJkqRq0e9bV3I2HdfHIvox10,72
31
- PyMemoryEditor/macos/functions.py,sha256=zL8jylondbDAj7UUuLmU8Fg8wVTCWkmEEpTzAu_384c,42894
31
+ PyMemoryEditor/macos/functions.py,sha256=ImP5E8oBxXjisAr5Mao6aXsaHsXi29zR_qwA5lGgT58,44726
32
32
  PyMemoryEditor/macos/libsystem.py,sha256=H9p72IqO0C5CrMFCAjnY_iQCzi_AQgw6ZN6CXsopceo,8683
33
33
  PyMemoryEditor/macos/process.py,sha256=06zgLaTKIyc1DQZFgS-9lqT2imB_IYFTOs4xEfSgftg,13259
34
34
  PyMemoryEditor/macos/types.py,sha256=bwPbYRZAOflITeNy0jeEXqFu-M5SVYkaFSsbyxz_K2w,5437
@@ -59,8 +59,8 @@ PyMemoryEditor/win32/enums/process_operations.py,sha256=wn-aMl01VVg-2rFavR9szBNR
59
59
  PyMemoryEditor/win32/enums/standard_access_rights.py,sha256=VGWlTagW4hvbm2AjZ4NK56ZrQwRmEl9Kz9GSCG8o-HI,738
60
60
  PyMemoryEditor/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  PyMemoryEditor/app/assets/icon.svg,sha256=T7OqR7ldqC_dK2Ib2ntsH2rWO-Z5RzNK4WdD1wFwgM4,7132
62
- pymemoryeditor-2.2.0.dist-info/METADATA,sha256=hiAocF8rEWox6UUUsnI_PKGgDLD5cbByM03DxF1PofY,8540
63
- pymemoryeditor-2.2.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
64
- pymemoryeditor-2.2.0.dist-info/entry_points.txt,sha256=ct14npP5HRKCHdq6-n83KBFi5QwQNSCsWE3MmGaWbzY,75
65
- pymemoryeditor-2.2.0.dist-info/licenses/LICENSE,sha256=YkOx6Nvkavq36bgiAc3eF85SBG0Qu14KMAvxmv6Ssjc,1089
66
- pymemoryeditor-2.2.0.dist-info/RECORD,,
62
+ pymemoryeditor-2.2.1.dist-info/METADATA,sha256=WPo6K0qNbB5HxGh2HKYxPc4lqqfKQZ2YztIFnIpkU_U,8702
63
+ pymemoryeditor-2.2.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
64
+ pymemoryeditor-2.2.1.dist-info/entry_points.txt,sha256=ct14npP5HRKCHdq6-n83KBFi5QwQNSCsWE3MmGaWbzY,75
65
+ pymemoryeditor-2.2.1.dist-info/licenses/LICENSE,sha256=YkOx6Nvkavq36bgiAc3eF85SBG0Qu14KMAvxmv6Ssjc,1089
66
+ pymemoryeditor-2.2.1.dist-info/RECORD,,