Internal Python Cheats

Introduction

As with any internal cheat, you will need to inject a DLL into the target process. Since we cannot compile a Python program into a DLL, we will inject the interpreter directly into our victim app and later call its functions.

Thankfully, Pymem has everything we need.

Reading & modifying memory from the current process

The best way to achieve this is by using cast from ctypes. I've made a little example to show how it works:


from ctypes import c_int, addressof, cast, POINTER


# Create an integer variable x with the value 10

x = c_int(10)


# Get the memory address of the integer variable x

xAddr = addressof(x)


# Print the value and memory address of x

print(f"""

Value of x: {x.value}

Address of x: {hex(xAddr)}

""")


# Create a pointer that points to the memory address of x

pointer = cast(xAddr, POINTER(c_int))


# Update the value at the memory address pointed by the pointer to 99

pointer.contents.value = 99


# Print the new value of x, which should reflect the change made through the pointer

print(f"New value of x: {x.value}"# This will show 99

The same logic will be applied after we inject the interpreter.

Injecting the interpreter

As I previously said, Pymem has everything we need:


from pymem import Pymem


# Create a Pymem instance for a target process ('dummyapp_x64.exe')

pm = Pymem('dummyapp_x64.exe')


# Inject the Python interpreter into the target process

pm.inject_python_interpreter()


This will allow us to inject Python code into the victim app using pm.inject_python_shellcode

Putting everything together

from pymem import Pymem


pm = Pymem('dummyapp_x64.exe')

pm.inject_python_interpreter()

shellcode = """

from ctypes import c_int, cast, POINTER


xAddr = 0x14FED0

pointer = cast(xAddr, POINTER(c_int))


pointer.contents.value = 99

"""

pm.inject_python_shellcode(shellcode)


This code snippet should inject the Python DLL into the dummyapp_x64.exe process & execute our Python shellcode.

int xAddr = 0x14FED0;

int* pointer = reinterpret_cast<int*>(xAddr);


*pointer = 99;

Injecting that Python shellcode is like having this C++ code inside a DLL that's injected in the process.

... or this Rust code:

let xaddr: i32 = 0x14FED0;

let pointer: *mut i32 = xaddr as *mut i32;


unsafe {

    *pointer = 99;

}

To prove its functionality, I've made and ran a simple app in C++ that outputs the value of an integer (X) followed by its address.

while (true){

    cout << "Value of X: " << X << "\n";

    cout << "Address of X: " << &X << "\n\n"; //0x14FED0

    _getch();

}

After running the Python code,  the value of X was changed to 99.

Therefore the PoC works.

You can see more in this YouTube video I made.

Limitations

That being said

"Python has a place and purpose and it is not used for internals due to the level of programming it is."

If you want a good internal cheat, I recommend learning C++, C or Rust.