首先我想说这个问题纯粹是出于兴趣而提出的,我绝不打算在任何严肃的项目中使用如此邪恶的东西。 (是的,就是这样一个问题)
我一直在尝试拼凑 CPython 内部工作的一些信息,据我所知,应该可以操纵小整数的实际值,以便(对于例如)1 + 2 可以评估为 3 以外的其他东西。我几乎不是这种低级黑客的专家,我所能实现的只是段错误。这是我到目前为止所得到的:
import ctypes
ctypes.c_int8.from_address(id(1) + 8).value = 2
我的印象是这样就可以解决问题,但这只会导致任何试图评估 1 的语句因段错误而崩溃。虽然这是一项有趣的成就,但这并不是我想要的。我错过了什么吗?该行中的 c_int8 和 + 8 是否仅适用于某些平台?如果我确切地知道要寻找什么,我会很高兴地查找它,尽管我想答案可能隐藏在 CPython 源代码中的某个地方。
最佳答案
8
在 32 位平台上是“正确的”,其中 ob_refcnt
和 ob_type
各为 4 个字节;在 64 位平台上,这会有所不同。本质上,您试图通过 PyObject_HEAD
到达整数对象的其余部分,因此请尝试在编译器或调试器中检查 PyObject
的大小。
显然这在 Python 3 上会有所不同,其中只有 long
类型,所以即使是小整数也是可变长度的;在这种情况下,您需要 PyObject_VAR_HEAD
(和 PyVarObject
)而不是 PyObject_HEAD
。
开始查看此文件的好地方是 object.h
中的文档,也可在 C API 引用手册中阅读 https://docs.python.org/2/c-api/structures.html , 然后在 intobject.h
, 或 longintrepr.h
适用于 Python 3。
注意:更改 1
的值仍然会出现段错误,但原因不同。不过,更改较大的小整数(例如 10
)的值应该是安全的。
关于python - python 中的邪恶 ctypes hack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24060991/