python - python 中的邪恶 ctypes hack

标签 python ctypes low-level

首先我想说这个问题纯粹是出于兴趣而提出的,我绝不打算在任何严肃的项目中使用如此邪恶的东西。 (是的,就是这样一个问题)

我一直在尝试拼凑 CPython 内部工作的一些信息,据我所知,应该可以操纵小整数的实际值,以便(对于例如)1 + 2 可以评估为 3 以外的其他东西。我几乎不是这种低级黑客的专家,我所能实现的只是段错误。这是我到目前为止所得到的:

import ctypes
ctypes.c_int8.from_address(id(1) + 8).value = 2

我的印象是这样就可以解决问题,但这只会导致任何试图评估 1 的语句因段错误而崩溃。虽然这是一项有趣的成就,但这并不是我想要的。我错过了什么吗?该行中的 c_int8 和 + 8 是否仅适用于某些平台?如果我确切地知道要寻找什么,我会很高兴地查找它,尽管我想答案可能隐藏在 CPython 源代码中的某个地方。

最佳答案

8 在 32 位平台上是“正确的”,其中 ob_refcntob_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/

相关文章:

c++ - 有没有办法为 C 或 C++ 结构强制执行特定的字节顺序?

python - 使用默认值从字典列表中提取项目

python - 使用 scipy.integrate.quad 积分复数

Python:ctypes 和垃圾收集

Python ctypes - 访问 Structure.value 中的数据字符串失败

c - 我无法理解我们看到的字符之间的抽象以及计算机如何处理它们

Python:在列表中拆分字符串的优雅且节省代码的方法

python - celery - 没有名为五的模块

python - 在 Python 中使用动态数组反序列化 C 结构

c - 如何修改返回值?