Created
March 1, 2025 14:39
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| 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