Skip to main content

A Python library for memory manipulation in Windows

Project description

PyWin-Memr

GitHub License Build Status PyPI - Version PyPI - Python Version OS GitHub repo size

PyMym is a Python memory manipulation library that allows quick and easy memory manipulation using Python and C++ on Windows machines. While initially it was created to allow a Gymnasium environment to directly access state information from a process, it slowly became a full-fledged library with memory scanning and manipulation features, including a lightweight process wrapper for accessing memory in a Pythonic way.

Table of Contents


Features

  • C++ Core Performance: Native execution for memory-intensive operations, bypassing the overhead of traditional Python wrappers.
  • Pattern Matching: High-speed Array of Bytes scanning to find stable hooks in frequently updating applications.
  • Zero-Config Installation: Pre-compiled binary wheels for Windows mean no local compiler is required for most users.
  • Flexibility: Simple Pythonic process wrapping for seamless memory manipulation or stand-alone memory manipulation without needing to use a class

How to Use

Memory Scanning

import PyMym as pm

name = "some_application.exe"
pid = pm.get_pid(name)

# different pattern types for convenience
hex_pattern = "AA 00 AB AC 00 FF FF"
string_pattern = "Hello, world!"
list_pattern = pattern = [0x00, 0xAA, 0xAB, 0x00, 0xFF, 0xB3]
hex_mask = "x?xx?xx"
list_mask = "?xx?xx"

# pid or application_name can be used
address = pm.heap_aob_scan(
    pid=pid,
    pattern=hex_pattern,
    mask=hex_mask,
    hex_string=True
)

# masks are optional
address = pm.stack_aob_scan(
    application_name=name,
    pattern=string_pattern
)

mods = pm.get_modules(application_name=name)
address = pm.module_aob_scan(
    pid=pid,
    module_name=mods[0],
    pattern=list_pattern,
    mask=list_mask
)

Memory Reading and Manipulation

PyMym offers reading and writing functions that align with C data types using the ctypes library, the current supported types are listed below with their respective functions.

Data Type Read Function Write Function C++ Equivalent
Bytes read_bytes write_bytes unsigned char[]
Short read_short write_short short
Unsigned Short read_ushort write_ushort unsigned short
Int read_int write_int int
Unsigned Int read_uint write_uint unsigned int
Long read_long write_long long
Unsigned Long read_ulong write_ulong unsigned long
Long Long read_longlong write_longlong long long
Unsigned Long Long read_ulonglong write_ulonglong unsigned long long
Float read_float write_float float
Double read_double write_double double

Examples

import PyMym as pm

## READING EXAMPLES
# All the following can be used with pid= or application_name=
name = "some_application.exe"
pid = pm.get_pid(name)
mem_addr = 0xFF00 # Example address

# Read functions can return singular values
byte_val = pm.read_bytes(application_name=name, memory_address=mem_addr)
short_val = pm.read_short(application_name=name, memory_address=mem_addr)

# Read functions can take an optional n parameter to return a list of n items
byte_list = pm.read_bytes(pid=pid, memory_address=mem_addr, n=16)
short_list = pm.read_short(pid=pid, memory_address=mem_addr, n=5)

## WRITING EXAMPLES
btw = "AF BE 3D DD"
# write_bytes returns True if all bytes were written, False otherwise
if not pm.write_bytes(pid=pid, memory_address=mem_addr, val=btw, hex_string=True):
    return -1

# write_bytes can take same types as the searches can
btw = "Hello, world!"
pm.write_bytes(application_name=name, memory_address=mem_addr, val=btw)

# Optional n parameter will fill extra unwritten bytes with 0x00
# So n - len(btw) bytes will be 0x00
pm.write_bytes(application_name=name, memory_address=mem_addr, val=btw, n=16)

# All write functions can take lists as well as singular values
pm.write_short(pid=pid, memory_address=mem_addr, val=[125, 126, 127])
# All write functions have the optional parameter n
# Which will write n - len(val) 0s to memory, matching the data type used
pm.write_short(pid=pid, memory_address=mem_addr, val=155, n=2)

Packing and Unpacking of Data

PyMym has functions for packing and unpacking data types into bytes and vice versa, with the same data type support as the read and write functions.

import PyMym as pm
import ctypes

# values can be packed into bytes for use with search functions
name = "some_application.exe"
pid = pm.get_pid(name)

val = 101
pval = pm.pack_int(val=val)

addr = pm.heap_aob_scan(pid=pid, pattern=pval)
# read functions will automatically unpack for you
ri = pm.read_int(application_name=name, memory_address=addr)
# but read bytes can be used instead to keep values as bytes
rb = pm.read_bytes(
    application_name=name,
    memory_address=addr,
    n=ctypes.sizeof(ctypes.c_int)
)

ui = pm.unpack_int(rb)

Pythonic Process Wrapping

The ProcessWrapper class contains methods that allow for scanning and memory manipulation, like the stand-alone functions did, and allows for shorter argument lists. Besides the original read and write methods, there is also indexing and slicing specific data types to allow Pythonic access to memory.

Data Type Accessor C++ Equivalent
Bytes pw[start:end] unsigned char[]
Short pw.short[start:end] short
Unsigned Short pw.ushort[start:end] unsigned short
Int pw.int[start:end] int
Unsigned Int pw.uint[start:end] unsigned int
Long pw.long[start:end] long
Unsigned Long pw.ulong[start:end] unsigned long
Long Long pw.longlong[start:end] long long
Unsigned Long Long pw.ulonglong[start:end] unsigned long long
Float pw.float[start:end] float
Double pw.double[start:end] double
import PyMym as pm

name = "some_application.exe"
pid = pm.get_pid(name)

# We can use pid=pid or application_name=name here
with ProcessWrapper(application_name=name) as pw:
    addr = pw.heap_aob_scan(pattern=pval)
    rb = pw.read_bytes(memory_address=addr, n=16)

    # Alternative, quick and Pythonic
    rb = pw[addr: addr + 16]

    # The same goes for other data types
    # Here we read 2 integers
    ri = pw.read_int(memory_address=addr, n=2)
    ri = pw.int[addr: addr + 2]

    # We can also write in a similar fashion
    pw.int[addr] = 500
    # Same goes for multiple values at once
    # Here we are writing 4 integers
    pw.int[addr: addr + 4] = [400, 500, 200, 100]

    # We can retrieve basic information about the process
    pid = pw.get_pid()
    name = pw.get_application_name()
    modules = pw.get_modules()
    endian = pw.get_endian()

    # We can also change the way we interpret the values
    if endian == "little":
        pw.set_endian(new_endian="big")
    else:
        pw.set_endian(new_endian="little")

Roadmap

  • Refactoring of backend C++ code
  • Wide character and UTF-16 support
  • Get addresses of specific modules
  • Get main thread ID as well as a list of thread IDs
  • More data types, char, uchar, int32, int16, etc.
  • Stronger exception and error handling
  • ProcessWrapper.get_base_module and .get_address
  • Stronger testing for dev branch
  • Searching for list of instances rather than the first instance
  • Strict and loose name search for modules and processes

Contribution

Feel free to suggest improvements or report issues in the repository.

License

This project is open-source and available under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pymym-1.0.3-cp314-cp314-win_amd64.whl (149.5 kB view details)

Uploaded CPython 3.14Windows x86-64

pymym-1.0.3-cp313-cp313-win_amd64.whl (147.9 kB view details)

Uploaded CPython 3.13Windows x86-64

pymym-1.0.3-cp312-cp312-win_amd64.whl (147.9 kB view details)

Uploaded CPython 3.12Windows x86-64

pymym-1.0.3-cp311-cp311-win_amd64.whl (147.2 kB view details)

Uploaded CPython 3.11Windows x86-64

pymym-1.0.3-cp310-cp310-win_amd64.whl (146.3 kB view details)

Uploaded CPython 3.10Windows x86-64

File details

Details for the file pymym-1.0.3-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: pymym-1.0.3-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 149.5 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymym-1.0.3-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 3befff70e8fb0b938ea6945d13fd970e0c610f174a936f26196ba7f299ac9edb
MD5 6d10ce35af5c726601594bdf98d76a81
BLAKE2b-256 a9dce1bc664881cebb349f59bf55730b61b602b9e92f3a771e7d4279d90b58e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymym-1.0.3-cp314-cp314-win_amd64.whl:

Publisher: main.yml on JSilvestrini/PyMym

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymym-1.0.3-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pymym-1.0.3-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 147.9 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymym-1.0.3-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 c9b89ebafb740c3decf1527cd318bee4a686148f116037e410000697028b517b
MD5 ec1e3e549fd73a32f00f8cff5289a7ce
BLAKE2b-256 bf75e2ae6a29fe4cd0b33d28efc2c39c749912dbac9108c93680c4a6065e39e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymym-1.0.3-cp313-cp313-win_amd64.whl:

Publisher: main.yml on JSilvestrini/PyMym

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymym-1.0.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pymym-1.0.3-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 147.9 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymym-1.0.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 febdd048b583e944b9603b4c154df30bc8f3c7ad897aca089800f8bc79cc84a9
MD5 ac4916707afaba3c248442bf0069fe1b
BLAKE2b-256 5ff7812ec66c6aea81f8025cfdfdd2c31aebc5137af99c1a86d6df424280e1ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymym-1.0.3-cp312-cp312-win_amd64.whl:

Publisher: main.yml on JSilvestrini/PyMym

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymym-1.0.3-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pymym-1.0.3-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 147.2 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymym-1.0.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d8e56e19a7f8688c740e76de9915d438cb8ee37efef653d7492b55470eb32079
MD5 2ee7b67a85aa8ce4f22d7c4af293bb76
BLAKE2b-256 05f5953251ac0f4c5c1ab192e3146f375d9d5992ad814f3dc17e164a94bbeaef

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymym-1.0.3-cp311-cp311-win_amd64.whl:

Publisher: main.yml on JSilvestrini/PyMym

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymym-1.0.3-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pymym-1.0.3-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 146.3 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymym-1.0.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 53c609e1c1e70d9f2e9c5fc26810894b72d68596066c2283917aa6fb2c2b8123
MD5 8bafe02a371679b1aa5c3df18bd97bea
BLAKE2b-256 5dd9c8f811961b2ff23c107df8308f21f84c14cf7e79bb71047b311a2dd023a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymym-1.0.3-cp310-cp310-win_amd64.whl:

Publisher: main.yml on JSilvestrini/PyMym

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page