Skip to content

About

Windows process memory inspector in Python: scan and filter values, find pointers, resolve pointer chains, run AOB pattern scans, and write values or NOP bytes only after confirmation. Built on pymem, for educational use on software you own.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

memory-inspector

CI License: MIT Python

Description

memory-inspector is a Windows-only, interactive command-line tool for inspecting the memory of a running process you own or have permission to analyze. It scans for exact values, narrows them down as they change, finds pointers to an address, resolves multi-level pointer chains, runs array-of-bytes (AOB) pattern scans inside a module, and — only after an explicit confirmation — writes a value or NOPs out code bytes, keeping the original bytes for a one-step restore.

It is built on pymem and is not affiliated with WeMod or any game trainer platform. It does not evade, disable, or bypass any anti-cheat, DRM, or integrity check.

Prerequisites

  • Windows 10/11, 64-bit. Pointer-chain resolution is 64-bit only; a 32-bit target is not supported for chains in this version.
  • Python 3.10 or higher.
  • An elevated terminal (Run as Administrator). Reading and writing another process's memory requires it.
  • A target process you own or have permission to analyze. The tool refuses to attach to its own process.
  • Git, to clone the repository. The GitHub CLI (gh) is optional, for setting the repository description and topics after pushing.

Installation

This package is not published to PyPI. Install it from source:

git clone https://github.com/enonymous1/memory-inspector.git
cd memory-inspector
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install .

Verify the install:

memory-inspector --help
memory-inspector --version

On Linux or macOS the command installs but refuses to run: it prints the banner and exits, because pymem needs the Win32 API. That platform guard is intentional, not a bug.

Usage

Attach by picking from a list, by PID, or by exact process name:

memory-inspector
memory-inspector --pid 1234
memory-inspector --process notepad.exe
memory-inspector --read-only

A safe first run is against Notepad (or any other process you own), with --read-only so writes and patches are disabled:

memory-inspector --process notepad.exe --read-only

The interactive inspector:

[1] New scan (find an exact value)
[2] Next scan (filter by a new value)
[3] Auto-filter (purge fluctuating values over time)
[4] Pointer scan (find what points to an address)
[5] Resolve pointer chain
[6] AOB pattern scan in a module
[7] Write value (modify an address)
[8] NOP bytes at an address
[9] Restore last NOP patch
[q] Quit inspector

Addresses and offsets accept decimal or 0x-prefixed hex. Value types are i32, u32, i64, u64, f32, and f64. Scans and filters never write. Options 7 and 8 always show the address, the current value or bytes, and the new value, and ask for confirmation first; --read-only disables them entirely.

Library use

from memory_inspector.process_manager import ProcessManager
from memory_inspector.memory_scanner import MemoryScanner
from memory_inspector.memory_writer import MemoryWriter

with ProcessManager(1234) as manager:
    pm = manager.get_pymem_instance()
    scanner = MemoryScanner(pm)
    addresses = scanner.find_value(100, "i32")
    addresses = scanner.filter_addresses(addresses, 90, "i32")
    if addresses and MemoryWriter(pm).write_value(addresses[0], 90, "i32"):
        print("Wrote 90 to", hex(addresses[0]))

write_value returns False on a write failure and raises ValueError for an out-of-range value before anything is written. Core classes take a ProcessMemory protocol, not a concrete pymem class, so they can be driven with a fake in tests (see below).

Local Development

Set up a development install (Windows for live runs; Linux or macOS is fine for the mocked suite):

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install ".[dev]"

Run every gate before committing. They must all pass:

ruff check src tests
ruff format --check src tests
mypy src
pytest -q

Tests stub pymem in tests/conftest.py and never touch a live process, so the suite runs on any platform. That is a deliberate trade-off, not full coverage: the live gate before any release is a run on Windows, as Administrator, against a process you own — scan, filter, resolve a pointer chain, write with confirmation, NOP a whole instruction, and restore it.

To add a value kind, edit exactly one place: src/memory_inspector/value_kinds.py (VALUE_KIND_SPECS). The scanner and writer both derive their method names and struct format from that table. To add an inspector action, add a branch in interactive_inspector in src/memory_inspector/cli.py and a driving test in tests/test_cli.py using the fake scanner/writer doubles there.

Deployment

There is no server, service, or hosted component to deploy. For users, "deployment" is installing from source on a Windows machine (see Installation) and running it elevated.

For maintainers, a release is a GitHub tag plus CI:

  1. Bump the version in pyproject.toml, src/memory_inspector/__init__.py, and CHANGELOG.md.
  2. Commit, push to main, and confirm the Ubuntu + Windows CI matrix (Python 3.10–3.13) is green.
  3. Tag the release, for example git tag v2.1.0, and push the tag.
  4. Confirm the live Windows gate above before announcing the release. CI alone does not prove the tool works against a real process, because pymem is stubbed in tests.

The package is not on PyPI. Publishing to PyPI would be a separate decision (distribution name, build, and upload credentials) and is not part of this release process.

Architecture

memory-inspector architecture

  • cli.py owns the interaction loop and confirmations only. It does not know pymem method names.
  • process_manager.py owns attaching by PID, exact-name resolution, and handle lifetime.
  • memory_scanner.py, memory_writer.py, pointer_scanner.py, and code_injector.py program against the ProcessMemory protocol in protocols.py, so a pymem change touches the adapter surface, not every module.
  • value_kinds.py is the single registry for value types.
  • code_injector.py changes page protection with VirtualProtectEx, writes, restores protection, and flushes the instruction cache, so patched code is actually executed as patched.

Safety and limits

  • Use only on software you own or have permission to analyze.
  • Writing to a process can crash it. NOPing a partial instruction corrupts code: only NOP whole instructions, and restore immediately if the target misbehaves.
  • Online games with anti-cheat systems may ban accounts for memory modification. This tool offers no protection against that.
  • Pointer chains are 64-bit only. Float scans use exact equality, so a decimal that does not round-trip to the same float bits will not match.
  • Scans without a cap can return very many addresses for common values such as 0. Library callers can pass max_results to find_value and find_pointers to bound the result.
  • Antivirus software may flag any memory-manipulation tool. That is expected for this category and is not, by itself, evidence of malware.

Troubleshooting

  • "Requires Windows" on Linux/macOS: expected. Run it on Windows.
  • "Could not find process" / "Could not open process": the PID or name is wrong, the process exited, or the terminal is not elevated. Re-check the PID in Task Manager and re-run elevated.
  • "Multiple processes named ...": use --pid with the exact PID from the picker instead of --process.
  • A scan finds nothing: check the value type (i32 vs u64, for example), that the value is actually in writable memory, and that the target has not reallocated the value elsewhere.
  • A NOP patch reports success but the target behaves unchanged: check that you NOPed whole instructions, and that the instruction-cache flush did not warn in the log.
  • A write succeeds but the value changes back immediately: the target rewrote it. That is the program's normal behavior, not a failed write; the inspector's read-back verification shows the value right after the write.

License

MIT. See LICENSE and CHANGELOG.md.

About

Windows process memory inspector in Python: scan and filter values, find pointers, resolve pointer chains, run AOB pattern scans, and write values or NOP bytes only after confirmation. Built on pymem, for educational use on software you own.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages