Skip to main content

A library to modify another program's memory.

Project description

memmod

A library to modify another program's memory on linux x64. The goal of this library is to provide easy functions to modify the memory of another application externaly. Additionaly creating a program like CheatEngine that runs natively on Linux with many features that CheatEngine provides.

Examples

A basic example on how to use memmod, for more examples look here.

from memmod import Process

# opens a process with the name "supertux2" 
proc = Process(name="supertux2")

# get the puts function and execute it inside the process
puts = proc.get_libc_function("puts")
puts("Hello World!")

# Find a module by name
modulebase = proc.find_module(proc.name)
assert modulebase != None, "Failed to find module base"

# Search ingame coin address by resolving a pointer chain 
static_ptr = modulebase.start + 0x6CBC40
coin_ptr_addr = proc.resolve_pointer_chain(static_ptr, [0x28, 0x20, 0x0])

# Write to address a number
proc.write(coin_ptr_addr, 9999)

Features

  • read/write to a process
  • inject breakpoints and listen to them
  • execute functions within the target process
  • find modules from /proc/pid/maps by name, mode, offset or address
  • inject .so into target process with load_shaderd_library()
  • create function detours with an optional trampoline
  • bindings for ptrace
  • get path to binary file with get_path_to_executable()
  • search pattern in a module with a signature
  • resolve a pointerchain to find addresses, can be used with the Pointer Scanner.
  • supports mono specific calls, see here
  • find symbol and relocation offsets within a module
  • get X11 window id with get_x11_window()
  • send key presses to the process send_key()
  • search for data or addresses in a specified range with scan()

How it works

Finding processes and reading/writing to them

We use the /proc/ folder that "stores" all processes in separate folders with their Process-ID (pid) as the folder name. Each process has a /proc/pid/status file that contains the process name, a /proc/pid/maps file with all the memory regions listed, a /proc/pid/mem "file" in which we can read/write in to the memory of the process (with the necessary permissions). For reading and writting use the functions read() and write(), searching for a module can be done by using the functions find_module() and find_module_with_address().

Debugging

For debugging we use the ptrace systemcall that allows us to stop a process, read its registers and continue until it reaches a breakpoint. A breakpoint in x64 linux is the hex number 0xCC and we can simply write this byte into the process as explained in the previous section. To use the debugger with this library run with proc.ptrace() as ptrace:, when running this, it will automatically attach to the process and stops, after that it will NOT detach, but instead just continue! If you want it to detach you will need todo it manually with ptrace.detach(). For easier handling with debugging and breakpoints you can use add_breakpoint(), it will take an address and a handler that is being executed as soon as the target process reaches the breakpoint. Optionaly you can provide it with data that can be used int the handler. The handler will receive the registers and the data if provided. The handler must return a boolean, if it returns False the breakpoint will be removed, to keep the breakpoint return True. But to start listening to the breakpoints you will need to run the listen() function. Note that the breakpoints are not being written into the memory by add_breakpoint() but by listen(). Listen will stop when all breakpoints have been deleted or the user interrupts it with ctrl+c, which will lead to the automatic removal of all breakpoints. Look here for examples on how to use it.

Function execution

We use ptrace to stop the application and write the call rax instruction at the current rip location and a breakpoint after that. We load into the rax register the address to the function we want to execute and the other register are being set to the arguments we want to pass to the function. After setting the registers, we continue the process flow and will reset the registers and the overwritten binary as soon as we reach the breakpoint. To use this feature use the function run_function(). For more information see this article.

Scripts

To show the capabilities of this library I programmed a few scripts that can be helpful when searching for addresses and are also being installed when installing this library. These scripts where inspired by the functionalities of CheatEngine.

Resources

Here are some useful links to websites that helped me making this library and the scripts.

Tools

Some tools and programs that I used when testing and debugging the library and it's scripts.

  • readelf (read symbols from binary file)
  • objdump (assembler code of binary file)
  • gdb (for debugging the target process)
  • monodis

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

libmemmod-0.0.3.tar.gz (31.2 kB view details)

Uploaded Source

Built Distribution

libmemmod-0.0.3-cp310-cp310-manylinux_2_35_x86_64.whl (42.2 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

File details

Details for the file libmemmod-0.0.3.tar.gz.

File metadata

  • Download URL: libmemmod-0.0.3.tar.gz
  • Upload date:
  • Size: 31.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.5

File hashes

Hashes for libmemmod-0.0.3.tar.gz
Algorithm Hash digest
SHA256 35e429e04819f5604a5bef07769ada643e3ca9dfbaf5bc421cd6e609c42426f4
MD5 7f3a86d5d8281b89dbed74e145123771
BLAKE2b-256 6eff545934a7e3c0b6c865ac1a7e3cad9c58a35dc8a642e350e8d89b643c6353

See more details on using hashes here.

File details

Details for the file libmemmod-0.0.3-cp310-cp310-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for libmemmod-0.0.3-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 9bdfe3e0f2229224ccf311ab7c8e48230f0538153a4048148b17a3592ad5821a
MD5 5e806ae7d0dcc20ed42fe3d4a125d661
BLAKE2b-256 cdcb5be7eed63c328d69057512fdd81a7a2e974b171b289ede9e2615ca0e72d3

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