Skip to main content
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'])

Metadata

Release files for pyjectify 1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyjectify 1.0
File Size Uploaded
pyjectify-1.0.tar.gz 24.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyjectify 1.0
File Interpreter ABI Platform
pyjectify-1.0-py3-none-any.whl Python 3 none any Details

Total release size: 51.5 kB

Release files / pyjectify-1.0.tar.gz

Download URL pyjectify-1.0.tar.gz
Size 24.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a21a0416b48061bdf375e58f0bb6191cac4ea0c5140decf589bc50861faedb5f
BLAKE2b-256 checksum
How to use checksums
aa9df332f8ec5724460c1b6de8ae7064ff2d95b7234d48dc56ce0fbfbaef8141
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 27, 2025.

Transparency log

Release files / pyjectify-1.0-py3-none-any.whl

Download URL pyjectify-1.0-py3-none-any.whl
Size 27.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ff38c2284b8740e5af8bf45408ef3ddfeff0b953b811785fd4f7630119475a2
BLAKE2b-256 checksum
How to use checksums
4fb9e921bb9f5d2f3bdf5c9e80c9b864272ab33c269715f2e3c3fdd0c6cb8da7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 27, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.0 This release

2 release files

0.7

2 release files

0.6

2 release files

0.5

2 release files

0.4

2 release files

0.3

2 release files

0.2

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page