Skip to main content

Python game hacking interface

Project description

pygamehack

pygamehack is a simple, dependency free Python 3.7+ library for reading/writing memory and binary analysis of running processes.

import pygamehack as gh

hack = gh.Hack()
hack.attach("MyProgram.exe")
print(hack.read_u32(0xdeadbeef))

pygamehack provides a simple API to read/write the memory of a process externally to the process. This can be done manually, or using named variables and a type hierarchy that that you define. You can entirely replicate the structure of an arbitrary compiled program in Python using a familiar dataclass-based type annotation syntax.

The goal of pygamehack is to prevent you from ever having to repeat tedious/manual labor tasks that are common when reverse engineering binary programs.

pygamehack also provides various tools for binary analysis, and defines a workflow for fully automating the tedious work of updating hard-coded values in a reverse-engineering project.

pygamehack also understands the file formats of some common reverse engineering tools (CheatEngine, ReClassNet) and allows you to quickly get started hacking in Python without having to redo any tedious manual labor.

Installation

pygamehack can be installed with pip.

pip install pygamehack

Features

  • Read/write process memory externally to the process.
  • Replicate a program's structure externally to the program
  • Named variables in Python that modify the memory of a target process
  • Familiar, dataclass based syntax in Python to define the structure of any compiled program

Core

pygamehack defines a few primary types that can then be used to build up the structure of any program. These types are Hack, Address, Buffer. There is also the concept of a Variable, which is an abstract representation of a typed memory region. pygamehack provides variable implementations for all of the basic numeric types, as well as strings, buffers and arrays. For more details see the Variable section.

Basic Types

A basic type is a numeric type. All naming conventions for types are based on the names of the basic types. pygamehack defines the following basic types:

Name C-type Size (bytes)
i8 int8_t 1
i16 int16_t 2
i32 int32_t 4
i64 int64_t 8
u8 uint8_t 1
u16 uint16_t 2
u32 uint32_t 4
u64 uint64_t 8
bool bool 1
float float 4
double double 8
usize size_t 4 or 8
ptr void* 4 or 8

There are 2 more types - str and buf - that have names that are used in the previously mentioned naming conventions, but are not numeric types. str represents a string (i.e. an array of characters) and buf represents an array of u8.

Hack

This is the primary interface to an external process' memory. Before reading/writing memory you must first attach to the target process

import pygamehack as gh

hack = gh.Hack()
hack.attach("MyProgram.exe")
# or you can use the Process ID
hack.attach(12345)

Reading/writing memory

For every basic type, there are corresponding 'Hack.read_NAME' and 'Hack.write_NAME' methods that can be used to read/write memory.

import pygamehack as gh
hack = gh.Hack()
# Read 
value = hack.read_u32(0xdeadbeef)
# Write
hack.write_u32(0xdeadbeef, 999)

Scanning memory

Address

This type is the representation of a memory address (I.e. A pointer) in the target process' memory. Addresses that depend on program parameters or runtime values must be loaded. There are 3 types of addresses:

  • Manual
  • Static
  • Dynamic

Manual

A manual address is what it sounds like, a hard-coded numeric value that represents a memory address in the target process. To create a manual address you need to provide the value of the address.

import pygamehack as gh
hack = gh.Hack()

address = gh.Address(hack, 0xdeadbeef)

NOTE: Because of practices like ASLR (address space layout randomization), it is recommended that you only use manual addresses when debugging or prototyping, as the address will likely stop working the next time that you run the target program.

Static

A static address represents an offset into the memory region of a process, or any of the dynamic libraries loaded into the target process' memory space. To create a static address, you need a module name and an offset.

import pygamehack as gh
hack = gh.Hack()

address = gh.Address(hack, "MyProgram.exe", 0xbeef)

Static addresses are the starting point of any program, and can be used to access data that has been compiled directly into the program binary. You can use static addresses as a base for all of the other interesting addresses.

Dynamic

A dynamic address represents an arbitrary memory address that depends on the value of another address in the target process' memory. The address is calculated by following an offset path in memory starting with the value of the parent address. To create a dynamic address, you need a parent address and a list of offsets.

import pygamehack as gh
hack = gh.Hack()

address = gh.Address(hack, "MyProgram.exe", 0xbeef)
d_address = gh.Address(address, [0x4])

Address loading

Each address type is created with different arguments and will respond differently to being loaded:

Type Requires Operation
Manual Nothing None
Static Base Address Query base address using library name
Dynamic Valid Parent Address (Load parent address), follow offset path

To load an address:

import pygamehack as gh
hack = gh.Hack()

address = gh.Address(hack, "MyProgram.exe", 0xbeef)
# Load
address.load()
# Get loaded value
print(address.value)
# Check if valid
print(address.valid)

Automatically loading addresses

When you have a lot of address objects and want to update them all in bulk, or you simply want to avoid calling 'Address.load()' every time you want to use an address, you can enable address auto loading.

When you call 'Hack.update()', every address that has been marked for auto loading will reload its value. You can conditionally load subsets of addresses by setting the 'Address.<>TODO<>' property.

Buffer

A buffer is a handle to dynamically allocated memory. Since memory cannot be accessed directly in Python, buffers provide a convenient interface for reading typed values from arbitrary memory. There are two types of buffers, an owning buffer and a view buffer.

Owning buffer

An owning buffer must explicitly read from the target process memory to update its contents. It will never observe changes in the contents of another buffer's memory.

To create an owning buffer, you only need to provide the size of the buffer.

import pygamehack as gh
hack = gh.Hack()

buffer = gh.Buffer(hack, 32)

View buffer

A view buffer is a view into the memory of another buffer, and will observe changes to its memory when its parent reads from the target process. View buffers also allow for a number of useful internal optimizations.

To create a view buffer, you must provide a parent buffer, an offset into the parent buffer, and the size of the buffer.

import pygamehack as gh
hack = gh.Hack()

buffer = gh.Buffer(hack, 32)
v_buffer = gh.Buffer(buffer, 8, 16)

Reading/writing buffers

Buffers are like memory middle-men in pygamehack. Like a Hack, a Buffer has 'read_' and 'write_' methods for all of the basic types. Unlike a Hack, calling 'read_' and 'write_' on a Buffer will not read/write the target process memory. These methods operate on the buffer's local storage, and if you want to read/write the target process memory you must do so explicitly using the 'Buffer.read_from()' and 'Buffer.write_to()' methods.

import pygamehack as gh
hack = gh.Hack()

# ... attach ...

addr = 0xdeadbeef
buffer = gh.Buffer(hack, 32)

# 0 since buffer has not read from process
assert buffer.read_u32(0) == 0
# Read entire content of buffer from process
buffer.read_from(addr)
# Buffer has data ready to read
value = buffer.read_u32(0)

# Write a new value to local storage
buffer.write_u32(0, 5)
# Process unaffected
assert hack.read_u32(addr) == value
# Write entire content of buffer to process
buffer.write_to(addr)
# Process has been updated
assert hack.read_u32(addr) == 5

Variables

Project details


Download files

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

Source Distribution

pygamehack-1.0.11.tar.gz (53.5 kB view details)

Uploaded Source

Built Distributions

pygamehack-1.0.11-pp37-pypy37_pp73-win_amd64.whl (437.1 kB view details)

Uploaded PyPy Windows x86-64

pygamehack-1.0.11-cp310-cp310-win_amd64.whl (437.9 kB view details)

Uploaded CPython 3.10 Windows x86-64

pygamehack-1.0.11-cp39-cp39-win_amd64.whl (424.8 kB view details)

Uploaded CPython 3.9 Windows x86-64

pygamehack-1.0.11-cp38-cp38-win_amd64.whl (438.1 kB view details)

Uploaded CPython 3.8 Windows x86-64

pygamehack-1.0.11-cp37-cp37m-win_amd64.whl (435.4 kB view details)

Uploaded CPython 3.7m Windows x86-64

File details

Details for the file pygamehack-1.0.11.tar.gz.

File metadata

  • Download URL: pygamehack-1.0.11.tar.gz
  • Upload date:
  • Size: 53.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for pygamehack-1.0.11.tar.gz
Algorithm Hash digest
SHA256 074d05899ab58d3f2880ac6d61906b9f066c1522724b07e0527c269b7b80d68b
MD5 74a08557a944fa1e6f00e2740cf08cd6
BLAKE2b-256 e3c26d66895c80370349bb3dadacc0c2d521f16cb8a0daed6108cd939ea325ea

See more details on using hashes here.

File details

Details for the file pygamehack-1.0.11-pp37-pypy37_pp73-win_amd64.whl.

File metadata

  • Download URL: pygamehack-1.0.11-pp37-pypy37_pp73-win_amd64.whl
  • Upload date:
  • Size: 437.1 kB
  • Tags: PyPy, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for pygamehack-1.0.11-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 c715939bcf605d2393885882984542819b38771fe347275edfd07434cdf7e79f
MD5 bd98663ca14ceb839379edf32994c036
BLAKE2b-256 76d3af77fbea128404784ecc2f91f39d19f10a700a2ccf00ae4cf0307d1799b1

See more details on using hashes here.

File details

Details for the file pygamehack-1.0.11-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pygamehack-1.0.11-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 437.9 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for pygamehack-1.0.11-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 687d956ac1361452ed289e19727f6e800f11f4c1301a7d82abc37fc5669e5396
MD5 0eb2b2df4bab95d9f838f02cb9e59cb3
BLAKE2b-256 e1c6c02541130b4c210d3430d3c516ef92a0fbfaa1d021bb23ce062056655b7b

See more details on using hashes here.

File details

Details for the file pygamehack-1.0.11-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: pygamehack-1.0.11-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 424.8 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for pygamehack-1.0.11-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 4632ba975cdedc2153d80d75ce2ddbed35203738df315aba5896d6ea90938f93
MD5 9d45d1b476f6d52042bd12062c7cf480
BLAKE2b-256 e28aceb4e96bbd2dc99032f337c38ea005a330dfd9ac5069cae51bb884644849

See more details on using hashes here.

File details

Details for the file pygamehack-1.0.11-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: pygamehack-1.0.11-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 438.1 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for pygamehack-1.0.11-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 91be15e5d7ca7b617d973f7b8281614a0725bcbd453ca8ed7deec1e710c3c23a
MD5 65d05021894e5e3f3af3bf8af50de564
BLAKE2b-256 19a2f9cfdb53ed6c28fbba89a50dab0213b6d71b3fa5c2c2d97df19a2829219f

See more details on using hashes here.

File details

Details for the file pygamehack-1.0.11-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: pygamehack-1.0.11-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 435.4 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for pygamehack-1.0.11-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 d6e6063a56dd512ab2fceb615edca82b9ce5efb161b8b9b27e7f01650ff6bfad
MD5 6c8ee086df7718f0fb2d8b03af27bd09
BLAKE2b-256 a5656dc137b076aeb3b692f1a03e38ec8f037e20685cd95d2af95058613df3e6

See more details on using hashes here.

Supported by

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