diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..860d680 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,113 @@ +/* Furo centers the layout: on wide screens the sidebar drawer spans the whole + left half and right-justifies its content against the text column, leaving a + wide margin on the far left. Pin it to a fixed width, flush against the left + edge of the window, for a conventional left-sidebar layout. */ +.sidebar-drawer { + width: 20em; + justify-content: flex-start; +} + +/* The inner container is hardcoded to 15em in Furo; widen it to match the + drawer so the brand, search box and nav tree fill the extra space. */ +.sidebar-container { + width: 20em; +} + +/* Roomier horizontal padding for the whole sidebar (brand, captions, links). */ +body { + --sidebar-item-spacing-horizontal: 1rem; +} + +/* Center the brand block (logo + project name) so it lines up with the + centered GitHub button below it. Furo only adds its own `.centered` class + for a text logo, not for an image logo. */ +.sidebar-brand { + align-items: center; + text-align: center; +} + +/* Smaller logo (Furo lets it grow to the full sidebar width by default). */ +.sidebar-logo { + max-width: 6em; +} + +/* Furo keeps a few purple accents that don't follow the brand colour: + visited links and the generic admonition-title accent. Point them at the + teal brand colour in every theme mode (explicit light/dark + auto). */ +body { + --color-brand-visited: var(--color-brand-content); + --color-admonition-title: var(--color-brand-content); +} +@media not print { + body[data-theme="dark"] { + --color-brand-visited: var(--color-brand-content); + --color-admonition-title: var(--color-brand-content); + } + @media (prefers-color-scheme: dark) { + body:not([data-theme="light"]) { + --color-brand-visited: var(--color-brand-content); + --color-admonition-title: var(--color-brand-content); + } + } +} + +/* Pygments (light theme): retint the purple keyword tokens to the teal accent. + Dark-theme keywords are already green, so they have no purple to fix. */ +.highlight .k, +.highlight .kc, +.highlight .kd, +.highlight .kn, +.highlight .kp, +.highlight .kr, +.highlight .ne, +.highlight .ow { + color: #0d9488; +} + +/* "Why use it?" feature grid on the landing page: add horizontal breathing + room between the three columns without overflowing (border-box keeps the + 33% widths intact), and zero out the outer edges. */ +.feature-grid td { + box-sizing: border-box; + padding: 0 1.25rem; + /* Shrink the cell text; the `h3` headings use `em`, so the title and body + scale down together proportionally. */ + font-size: 0.85rem; +} +.feature-grid td:first-child { + padding-left: 0; +} +.feature-grid td:last-child { + padding-right: 0; +} + +/* Persistent GitHub call-to-action in the sidebar, under the project name. */ +.sidebar-github-cta { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + margin: 0.75rem 1rem 0.25rem; + padding: 0.5rem 0.75rem; + border: 1px solid var(--color-background-border); + border-radius: 0.5rem; + color: var(--color-sidebar-link-text); + font-size: 0.85rem; + font-weight: 600; + line-height: 1; + text-decoration: none; + transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease; +} + +.sidebar-github-cta:hover, +.sidebar-github-cta:focus-visible { + background: var(--color-background-hover); + border-color: var(--color-foreground-border); + color: var(--color-sidebar-link-text); +} + +.sidebar-github-cta svg { + width: 1.15em; + height: 1.15em; + flex-shrink: 0; +} diff --git a/docs/_templates/sidebar/brand.html b/docs/_templates/sidebar/brand.html new file mode 100644 index 0000000..992f1f6 --- /dev/null +++ b/docs/_templates/sidebar/brand.html @@ -0,0 +1,26 @@ +{#- Furo's default brand, plus a persistent GitHub call-to-action pinned + directly under the project name so it's visible from every page. -#} + + + + View on GitHub + diff --git a/docs/api/enums.md b/docs/api/enums.md index 9a2ac9a..cb77890 100644 --- a/docs/api/enums.md +++ b/docs/api/enums.md @@ -2,7 +2,12 @@ ## `ScanTypesEnum` -Comparison modes for `search_by_value` and `search_by_value_between`. +```{eval-rst} +.. py:class:: ScanTypesEnum + + Comparison modes for :py:meth:`search_by_value` and + :py:meth:`search_by_value_between`. +``` ```python from PyMemoryEditor import ScanTypesEnum @@ -36,6 +41,13 @@ with OpenProcess(process_name="game.exe") as process: ## `ProcessOperationsEnum` (Windows only) +```{eval-rst} +.. py:class:: ProcessOperationsEnum + + Bitmask of Windows process access rights, passed as the ``permission=`` + argument of ``OpenProcess`` on Windows. +``` + Bitmask of [process access rights](https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights). Defined as `IntFlag` so members can be combined with `|`: @@ -81,6 +93,12 @@ This is enough for both read and write operations plus region enumeration ## `MemoryProtectionsEnum` (Windows only) +```{eval-rst} +.. py:class:: MemoryProtectionsEnum + + The Win32 ``PAGE_*`` page-protection constants. +``` + The Win32 `PAGE_*` constants. Used as the `permission=` argument of `allocate_memory` and surfaced in `region["struct"].Protect`. diff --git a/docs/api/errors.md b/docs/api/errors.md index 7ac6fb0..948d903 100644 --- a/docs/api/errors.md +++ b/docs/api/errors.md @@ -32,11 +32,19 @@ more idiomatic match (`PermissionError`, `OSError`, `TypeError`, `ValueError`, ### `PyMemoryEditorError` +```{eval-rst} +.. py:exception:: PyMemoryEditorError +``` + Base class for every PyMemoryEditor-specific exception. Catch it to handle *any* library error. ### `ClosedProcess` +```{eval-rst} +.. py:exception:: ClosedProcess +``` + Raised when you call any method on a process whose handle has already been closed (manually or by leaving the `with` block). @@ -52,10 +60,12 @@ process.read_process_memory(0x1000, int) # raises ClosedProcess Raised when the given `pid=` doesn't correspond to a running process. ```{eval-rst} -.. py:attribute:: pid - :type: int +.. py:exception:: ProcessIDNotExistsError + + .. py:attribute:: pid + :type: int - The PID that was looked up. + The PID that was looked up. ``` ### `ProcessNotFoundError` @@ -63,10 +73,12 @@ Raised when the given `pid=` doesn't correspond to a running process. Raised when no running process matches the given `process_name=`. ```{eval-rst} -.. py:attribute:: process_name - :type: str +.. py:exception:: ProcessNotFoundError - The process name that was looked up. + .. py:attribute:: process_name + :type: str + + The process name that was looked up. ``` ### `AmbiguousProcessNameError` @@ -75,16 +87,17 @@ Raised when **more than one** running process matches the given `process_name=` (typical when using `exact_match=False`). ```{eval-rst} -.. py:attribute:: process_name - :type: str - :no-index: +.. py:exception:: AmbiguousProcessNameError + + .. py:attribute:: process_name + :type: str - The process name that was looked up. + The process name that was looked up. -.. py:attribute:: pids - :type: List[int] + .. py:attribute:: pids + :type: List[int] - PIDs of the matching processes — pick one and pass it via ``pid=``. + PIDs of the matching processes — pick one and pass it via ``pid=``. ``` Example: diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000..1a29904 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,33 @@ +# API Reference + +Every public class, method and helper PyMemoryEditor exposes. For +task-oriented walkthroughs, see the [User Guide](../guide/index.md). + +## At a glance + + + + + + + + + + + + +
SymbolWhat it is
OpenProcessThe unified entry point — read, write, scan, allocate.
EnumsScanTypesEnum, ProcessOperationsEnum, MemoryProtectionsEnum.
MemoryRegionOne region of the target's address space.
RemotePointerA live, re-resolving handle to a typed value.
PointerPathA discovered static pointer path from a reverse scan.
ModuleInfoA loaded executable or shared library.
ThreadInfoA thread running inside the target.
ErrorsThe exception hierarchy.
UtilitiesLow-level helpers under PyMemoryEditor.util.
+ +```{toctree} +:maxdepth: 1 + +openprocess +enums +memory-region +remote-pointer +pointer-path +module-info +thread-info +errors +utilities +``` diff --git a/docs/api/memory-region.md b/docs/api/memory-region.md index 2f7b4d8..11165c2 100644 --- a/docs/api/memory-region.md +++ b/docs/api/memory-region.md @@ -73,7 +73,7 @@ of memory with its address, size, permissions and backing path. .. py:class:: MemoryRegionSnapshot A pre-sorted snapshot of memory regions returned by - :py:meth:`AbstractProcess.snapshot_memory_regions`. Behaves exactly like a + :py:meth:`snapshot_memory_regions`. Behaves exactly like a plain ``list[MemoryRegion]`` — the only purpose of the subclass is to let the scanning helpers detect via ``isinstance`` that the input is already sorted by ``address`` and skip the per-call ``sorted(...)`` step. diff --git a/docs/api/module-info.md b/docs/api/module-info.md index 22a0458..f97157c 100644 --- a/docs/api/module-info.md +++ b/docs/api/module-info.md @@ -33,7 +33,7 @@ Linux, `.dylib` on macOS). Address where the module is loaded for this run. Combine it with a static offset (``base_address + offset``) to reach a known location despite ASLR — the natural feed into - :py:meth:`AbstractProcess.resolve_pointer_chain`. + :py:meth:`resolve_pointer_chain`. .. py:attribute:: size :type: int diff --git a/docs/api/openprocess.md b/docs/api/openprocess.md index 1b0be2a..806f575 100644 --- a/docs/api/openprocess.md +++ b/docs/api/openprocess.md @@ -12,6 +12,14 @@ resolves to: All three subclass `AbstractProcess` and share the API documented below. +```{eval-rst} +.. py:class:: AbstractProcess + + The cross-platform base class every backend implements. ``OpenProcess`` + returns one of its subclasses; the methods documented on this page are the + shared, public surface. +``` + ## Construction ```{eval-rst} @@ -208,7 +216,7 @@ with OpenProcess( ```{eval-rst} .. py:method:: close() - Close the process handle. Subsequent calls raise :py:class:`ClosedProcess`. + Close the process handle. Subsequent calls raise :py:exc:`ClosedProcess`. .. py:method:: __enter__() .. py:method:: __exit__(exc_type, exc_value, exc_traceback) diff --git a/docs/conf.py b/docs/conf.py index 90fb167..680ded3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -77,16 +77,30 @@ "source_branch": "main", "source_directory": "docs/", "light_css_variables": { - "color-brand-primary": "#8A2BE2", - "color-brand-content": "#8A2BE2", + "color-brand-primary": "#0D9488", + "color-brand-content": "#0D9488", }, "dark_css_variables": { - "color-brand-primary": "#B57AFF", - "color-brand-content": "#B57AFF", + "color-brand-primary": "#2DD4BF", + "color-brand-content": "#2DD4BF", }, + # Persistent GitHub call-to-action, pinned to the sidebar footer on every page. + "footer_icons": [ + { + "name": "GitHub", + "url": "https://github.com/JeanExtreme002/PyMemoryEditor", + "html": """ + + + + """, + "class": "", + }, + ], } html_static_path = ["_static"] +html_css_files = ["custom.css"] # Logo and favicon resolved from the bundled SVG icon. html_logo = "../PyMemoryEditor/app/assets/icon.svg" diff --git a/docs/guide/index.md b/docs/guide/index.md new file mode 100644 index 0000000..e39d77e --- /dev/null +++ b/docs/guide/index.md @@ -0,0 +1,53 @@ +# User Guide + +Task-oriented walkthroughs of every PyMemoryEditor workflow, from opening a +process to following multi-level pointer chains. Each page is self-contained +and cross-links to the relevant [API reference](../api/index.md). + +New here? Read the [Quick Start](../quickstart.md) first, then come back for +the in-depth version. + +## What's covered + +- **Core workflow** — open a process, read/write values, and find addresses by + value or byte pattern. This is the classic Cheat Engine loop. +- **Inspecting the process** — enumerate memory regions, loaded modules and + threads. +- **Pointers** — walk pointer chains you know, and reverse-scan to discover the + chains that survive a restart. +- **Advanced** — reserve and release memory inside the target. + +For diagnostics, see [Logging](logging.md) in the Reference section. + +```{toctree} +:caption: Core workflow +:maxdepth: 1 + +opening-process +read-write +searching +pattern-scan +``` + +```{toctree} +:caption: Inspecting the process +:maxdepth: 1 + +memory-regions +modules-threads +``` + +```{toctree} +:caption: Pointers +:maxdepth: 1 + +pointers +pointer-scan +``` + +```{toctree} +:caption: Advanced +:maxdepth: 1 + +allocate-free +``` diff --git a/docs/guide/modules-threads.md b/docs/guide/modules-threads.md index 530041b..106cf58 100644 --- a/docs/guide/modules-threads.md +++ b/docs/guide/modules-threads.md @@ -51,7 +51,7 @@ with OpenProcess(process_name="game.exe") as process: Address where the module is loaded **for this run**. Combine it with a static offset (``base_address + offset``) to reach a known location despite ASLR — the natural feed into - :py:meth:`AbstractProcess.resolve_pointer_chain`. + :py:meth:`resolve_pointer_chain`. .. py:attribute:: size :no-index: diff --git a/docs/guide/pointer-scan.md b/docs/guide/pointer-scan.md index baa40f7..dc33643 100644 --- a/docs/guide/pointer-scan.md +++ b/docs/guide/pointer-scan.md @@ -45,7 +45,7 @@ It carries everything you need to reconstruct the chain in another run. Recommended for shallow exploration. :param memory_regions: optional snapshot from :py:meth:`snapshot_memory_regions`. - :param callable progress_callback: ``callback(fraction)`` invoked as the + :param progress_callback: a callable ``callback(fraction)`` invoked as the pointer map is built (the long phase), ``fraction`` in ``[0, 1]``. :returns: a generator of :py:class:`PointerPath`. ``` diff --git a/docs/index.md b/docs/index.md index 52d0070..f3eb380 100644 --- a/docs/index.md +++ b/docs/index.md @@ -33,7 +33,7 @@ If you've never done memory editing before, start with the ## Why use it? - +
@@ -53,7 +53,7 @@ platform-specific wheels. -### 🧰 Batteries included +### 🧰 Complete toolkit Value scans, AOB scans, pointer chains, pointer scans, a GUI app — all the Cheat Engine workflows in one package. @@ -78,16 +78,7 @@ quickstart :caption: User Guide :maxdepth: 2 -guide/opening-process -guide/read-write -guide/searching -guide/pattern-scan -guide/memory-regions -guide/modules-threads -guide/pointers -guide/pointer-scan -guide/allocate-free -guide/logging +guide/index ``` ```{toctree} @@ -101,15 +92,7 @@ app :caption: API Reference :maxdepth: 2 -api/openprocess -api/enums -api/memory-region -api/remote-pointer -api/pointer-path -api/module-info -api/thread-info -api/errors -api/utilities +api/index ``` ```{toctree} @@ -118,6 +101,7 @@ api/utilities platform-notes troubleshooting +guide/logging glossary ```