Skip to content

Instantly share code, notes, and snippets.

@M-logique
Created March 1, 2025 14:39
Show Gist options
  • Select an option

  • Save M-logique/caf4c1bbd39100252cdd33af0e93822d to your computer and use it in GitHub Desktop.

Select an option

Save M-logique/caf4c1bbd39100252cdd33af0e93822d to your computer and use it in GitHub Desktop.
This script showcases a low-level Python memory hack to make a string callable.
"""
Overview of the Script:
------------------------
This script demonstrates an advanced memory manipulation technique in Python, allowing an immutable
string (like "Hello World!") to be called like a function. Normally, in Python, calling a string directly
raises a TypeError, but by modifying Python's internal memory structures, we can bypass this restriction.
Why Was This Script Written?
----------------------------
This script was created as an experiment to manipulate Python’s interned strings in a way that is
normally impossible. It:
1. Modifies the internal type of a string to a custom subclass (CallableString) that allows calling it as a function.
2. Intercepts and explains Python’s SyntaxWarning, which gets triggered when you try to call a string.
3. Restores the original state after execution to prevent program crashes.
This is a purely academic and fun exercise—it is not a recommended practice for real-world applications!
How Python’s Memory Works and Why This Works:
---------------------------------------------
Python manages strings in a highly optimized way. When you create a string like "Hello World!",
Python interns it, meaning it stores it in a shared pool for efficiency. This is why if you do:
a = "Hello World!"
b = "Hello World!"
print(a is b) # True
Both `a` and `b` point to the same memory address.
How This Script Exploits Python’s Memory Management:
----------------------------------------------------
- In CPython, every object has a **type pointer** stored at a fixed offset within its memory structure.
- The **type pointer determines an object’s behavior** (i.e., what kind of object it is and how it functions).
- By using `ctypes`, we **overwrite this type pointer** to point to our custom subclass (`CallableString`).
- Now, `"Hello World!"` behaves like an instance of `CallableString`, which allows it to be called like a function.
- After execution, the original type pointer is **restored**, so `"Hello World!"` behaves normally again.
This is a **dangerous and hacky** method, but it demonstrates how Python objects are represented in memory.
Step-by-Step Execution:
------------------------
1. **Check for Syntax Warnings**
- Since calling a string like a function triggers a `SyntaxWarning`, we capture `sys.stderr` output
to detect if warnings are enabled.
2. **Modify the String Type Pointer**
- We replace `"Hello World!"`'s type pointer with our `CallableString` class.
3. **Execute the Modified String**
- `"Hello World!"(print)` now works, printing `"Hello World!"`.
4. **Restore the Original State**
- The type pointer is restored to prevent segmentation faults and undefined behavior.
"""
import ctypes # Used for low-level memory manipulation
import sys
import warnings
from io import StringIO # Used to check if warnings are enabled
def check_syntax_warning() -> bool:
# Create a StringIO object to capture stderr
captured_stderr = StringIO()
# Redirect stderr to the StringIO object
sys.stderr = captured_stderr
# Trigger a SyntaxWarning manually for demonstration
warnings.warn("This is a SyntaxWarning for demonstration", SyntaxWarning)
# Reset stderr to its original value
sys.stderr = sys.__stderr__
# Check if any warning message was captured in stderr
captured_output = captured_stderr.getvalue()
return "SyntaxWarning" in captured_output
# Define a subclass of str that allows instances to be called like functions
class CallableString(str):
def __call__(self, value: object) -> None:
# If syntax warnings are enabled, display an explanation
if check_syntax_warning():
print()
print("Above this message, you might see a SyntaxWarning. Don't worry, it's just because even Python developers didn't expect anyone to write such a ridiculous script!")
print("Tip: If you don't want to see the SyntaxWarning, use: python3 -W ignore")
print()
# Call the function with the string as an argument
value(self)
# Reference to the interned string "Hello World!" in memory
_string = "Hello World!"
# Offset for the type pointer in CPython memory layout
type_ptr_offset = 8
# Save the original type pointer address before modification
original_type_ptr_addr = id(_string) + type_ptr_offset
original_type = ctypes.c_void_p.from_address(original_type_ptr_addr).value
# Calculate the address of the new type pointer
type_ptr_addr = id(_string) + type_ptr_offset
# Overwrite the type pointer so that the interned string "Hello World!" is now of type 'CallableString'
ctypes.c_void_p.from_address(type_ptr_addr).value = id(CallableString)
# Call the modified "Hello World!" string
"Hello World!"(print)
# To prevent the program from crashing and to avoid a Segmentation Fault, we restore all values to their original state.
ctypes.c_void_p.from_address(type_ptr_addr).value = original_type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment