Skip to main content

A Python library for memory manipulation, code injection and function hooking

Project description

PyJectify logo

    PyJectify

    A Python library for memory manipulation, code injection and function hooking.

Quick start

PyJectify is available on PyPI.

Alternatively, you can download releases from GitHub or clone the project.

Documentation is available at https://petitoto.github.io/pyjectify/

Features

Windows (x86 & x86_64)

Core

  • Allocate / Free / Read / Write memory
  • Create threads
  • List loaded modules
  • PE parser
  • Use kernel32 or ntdll functions

Modules

  • MemScan: scan memory using regex patterns
  • Inject: load library, from disk (remote LoadLibrary) or from memory (fully map the DLL into the remote process)
  • Hook: set up inline hooks in the target process
  • PythonLib: embed python into a remote process

Utils

  • Syscall: parse syscall codes from ntdll.dll (from the loaded library or from the disk), and produce a ntdll-like object which can be used by the core to use direct syscalls
  • ApiSetSchema: parse Windows ApiSet

Examples

Memory search & basic operations

import pyjectify

# Open notepad process (only the first found if multiple instances of notepad are running)
notepad = pyjectify.open('notepad.exe')[0]

# Use the pattern "secret( is)?: (.){10}", but encoded in utf-16-le because Notepad uses wchar_t
words = ['secret', ' is', ': ', '.']
pattern = b'%b(%b)?%b(%b){10}' % tuple(e.encode('utf-16-le') for e in words)

# Search for the secret in notepad's memory
addrs = notepad.memscan.scan(pattern)

# Process found addresses
for addr in addrs:
    secret = notepad.process.read(addr, 50).decode('utf-16-le')
    print('[+] Found secret:', secret)
    notepad.process.write(addr, ('*'*len(secret)).encode('utf-16-le')) # let's hide the secret!

# Reset memscan to discard found addresses and perform a new search
notepad.memscan.reset()

Python code injection

import pyjectify

# Open notepad process
notepad = pyjectify.open('notepad.exe')[0]

# Inject Python DLL
notepad.pythonlib.python_mod = notepad.inject.load_library("C:\\path\\to\\python-embed\\python311.dll")

# Run some Python code from notepad
notepad.pythonlib.initialize()
notepad.pythonlib.exec('import os; os.system("calc.exe")')

# Undo all initializations
notepad.pythonlib.finalize()

Setup an inline hook written in Python

import pyjectify

# Open notepad process & inject Python DLL
notepad = pyjectify.open('notepad.exe')[0]
notepad.pythonlib.python_mod = notepad.inject.load_library("C:\\path\\to\\python-embed\\python311.dll")
notepad.pythonlib.initialize()

# Let's hook GetClipboardData!
# Step 1: define our new function
pycode = """
import ctypes
def GetClipboardData(uFormat:ctypes.c_uint) -> ctypes.c_void_p:
  ctypes.windll.user32.MessageBoxW(0, "I hooked you :D", "MyNewGetClipboardData", 0)
  return o_GetClipboardData(uFormat)
"""
notepad.pythonlib.exec(pycode)

# Step 2: get original function address and setup a trampoline (of 15 bytes size)
user32 = notepad.process.get_module('user32.dll')
oaddr = user32.exports['GetClipboardData'] + user32.base_addr
trampoline_addr = notepad.hook.trampoline(oaddr, 15)

# Step 3: prepare Python function hooking, ie create o_GetClipboardData and get ou Python GetClipboardData address
hook_addr = notepad.pythonlib.prepare_hook('GetClipboardData', trampoline_addr)

# Step 4: inline hook
notepad.hook.inline(oaddr, hook_addr)

Advanced DLL injection

import pyjectify

# Open processes
proc1 = pyjectify.open('proc1.exe')[0]
proc2 = pyjectify.open('proc2.exe')[0]

# Extract a library from proc1's memory
module = proc1.process.get_module('module.dll')

# Extract common syscalls from ntdll.dll and wrap them into a ntdll-like object
syscall = pyjectify.windows.Syscall()
syscall.get_common(from_disk=True)

# Use direct syscalls to operate on proc2 (memory read / write / protect, thread creation...)
proc2.process.ntdll = syscall

# Inject the module directly from memory into proc2, at a random location, without PE headers, and do not call DLL entry point
injected_mod = proc2.inject.memory_loader(module, prefer_base_addr=False, copy_headers=False, call_entry_point=False)

# Run a function from the injected module
proc2.process.start_thread(injected_mod.base_addr + injected_mod.exports['SomeExportedFunction'])

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

pyjectify-1.0.tar.gz (24.3 kB view details)

Uploaded Source

Built Distribution

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

pyjectify-1.0-py3-none-any.whl (27.2 kB view details)

Uploaded Python 3

File details

Details for the file pyjectify-1.0.tar.gz.

File metadata

  • Download URL: pyjectify-1.0.tar.gz
  • Upload date:
  • Size: 24.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pyjectify-1.0.tar.gz
Algorithm Hash digest
SHA256 a21a0416b48061bdf375e58f0bb6191cac4ea0c5140decf589bc50861faedb5f
MD5 8768559da0945b4a5b15316966ca84e7
BLAKE2b-256 aa9df332f8ec5724460c1b6de8ae7064ff2d95b7234d48dc56ce0fbfbaef8141

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjectify-1.0.tar.gz:

Publisher: publish-pypi.yml on Petitoto/pyjectify

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

File details

Details for the file pyjectify-1.0-py3-none-any.whl.

File metadata

  • Download URL: pyjectify-1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pyjectify-1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7ff38c2284b8740e5af8bf45408ef3ddfeff0b953b811785fd4f7630119475a2
MD5 b77bd3323e7365770acddcb8d378c72b
BLAKE2b-256 4fb9e921bb9f5d2f3bdf5c9e80c9b864272ab33c269715f2e3c3fdd0c6cb8da7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjectify-1.0-py3-none-any.whl:

Publisher: publish-pypi.yml on Petitoto/pyjectify

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