- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试从内存中删除密码字符串 like it is suggested in here .
我写了那个小片段:
import ctypes, sys
def zerome(string):
location = id(string) + 20
size = sys.getsizeof(string) - 20
#memset = ctypes.cdll.msvcrt.memset
# For Linux, use the following. Change the 6 to whatever it is on your computer.
print ctypes.string_at(location, size)
memset = ctypes.CDLL("libc.so.6").memset
memset(location, 0, size)
print "Clearing 0x%08x size %i bytes" % (location, size)
print ctypes.string_at(location, size)
a = "asdasd"
zerome(a)
奇怪的是,这段代码在 IPython 上运行良好,
[7] oz123@yenitiny:~ $ ipython a.py
Clearing 0x02275b84 size 23 bytes
但是使用 Python 会崩溃:
[8] oz123@yenitiny:~ $ python a.py
Segmentation fault
[9] oz123@yenitiny:~ $
有什么想法吗?
我使用 Python 2.7.3 在 Debian Wheezy 上进行了测试。
该代码适用于 CentOS 6.2 和 Python 2.6.6。 代码在使用 Python 2.6.8 的 Debian 上崩溃。 我试着思考为什么它适用于 CentOS 而不是 Debian。唯一的原因, 立即不同的是,我的 Debian 是多架构的,而 CentOS 在我的 i686 CPU 旧笔记本电脑上运行。
因此,我重新启动了我的 CentOS latop 并在其上加载了 Debian Wheezy。 该代码适用于非多体系结构的 Debian Wheezy。 因此,我怀疑我在 Debian 上的配置有点问题......
最佳答案
ctypes 已经有一个 memset
函数,所以你不必为 libc/msvcrt 函数创建一个函数指针。此外,20 个字节用于常见的 32 位平台。在 64 位系统上,它可能是 36 个字节。这是 PyStringObject
的布局:
typedef struct {
Py_ssize_t ob_refcnt; // 4|8 bytes
struct _typeobject *ob_type; // 4|8 bytes
Py_ssize_t ob_size; // 4|8 bytes
long ob_shash; // 4|8 bytes (4 on 64-bit Windows)
int ob_sstate; // 4 bytes
char ob_sval[1];
} PyStringObject;
因此在 32 位系统上可能是 5*4 = 20 字节,在 64 位 Linux 上可能是 8*4 + 4 = 36 字节,在 64 位 Windows 上可能是 8*3 + 4*2 = 32 字节.由于字符串未使用垃圾收集 header 进行跟踪,因此您可以使用 sys.getsizeof
。一般来说,如果您不想包含 GC header 大小(在内存中它实际上位于您从 id
获取的对象基地址之前),则使用对象的 __sizeof__
方法。至少这是我的经验中的一般规则。
您想要的只是从对象大小中减去缓冲区大小。 CPython 中的字符串以 null 结尾,因此只需将其长度加 1 即可获得缓冲区大小。例如:
>>> a = 'abcdef'
>>> bufsize = len(a) + 1
>>> offset = sys.getsizeof(a) - bufsize
>>> ctypes.memset(id(a) + offset, 0, bufsize)
3074822964L
>>> a
'\x00\x00\x00\x00\x00\x00'
编辑
更好的选择是定义 PyStringObject
结构。这使得检查 ob_sstate
变得很方便。如果它大于 0,则意味着该字符串已被驻留,理智的做法是引发异常。单字符字符串与仅由 ASCII 字母和下划线组成的代码对象中的字符串常量以及解释器在内部用于名称(变量名称、属性)的字符串一起被驻留。
from ctypes import *
class PyStringObject(Structure):
_fields_ = [
('ob_refcnt', c_ssize_t),
('ob_type', py_object),
('ob_size', c_ssize_t),
('ob_shash', c_long),
('ob_sstate', c_int),
# ob_sval varies in size
# zero with memset is simpler
]
def zerostr(s):
"""zero a non-interned string"""
if not isinstance(s, str):
raise TypeError(
"expected str object, not %s" % type(s).__name__)
s_obj = PyStringObject.from_address(id(s))
if s_obj.ob_sstate > 0:
raise RuntimeError("cannot zero interned string")
s_obj.ob_shash = -1 # not hashed yet
offset = sizeof(PyStringObject)
memset(id(s) + offset, 0, len(s))
例如:
>>> s = 'abcd' # interned by code object
>>> zerostr(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 10, in zerostr
RuntimeError: cannot zero interned string
>>> s = raw_input() # not interned
abcd
>>> zerostr(s)
>>> s
'\x00\x00\x00\x00'
关于python - python 中的 ctypes 因 memset 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15581881/
我似乎找不到任何将 ctypes.c_void_p() 转换为字符串或字节数组的简单示例。有没有简单的衬里可以做到这一点? 最佳答案 给你: import ctypes as ct # set up
在ctypes中,pointer和byref有什么区别?它们似乎都是将指针传递给函数的一种方式,例如作为输出参数。 最佳答案 在功能上,它们是等价的。 然而,python docs请指出 pointe
我知道我应该指定 argtypes对于我的 C/C++ 函数,因为我的某些调用会导致堆栈损坏。 myCfunc.argtypes = [ct.c_void_p, ct.POINTER(ct.c
有没有办法获取指向 ctypes 数组中间元素的指针?示例: lib = ctypes.cdll.LoadLibrary('./lib.so') arr = (ctypes.c_int32 * 100
在我自定义的 TYPO3 Extbase 扩展中,我创建了一个后端模块来管理个人记录。现在我需要一个内容元素来在前端显示记录。 我看到了两种实现此目的的方法: 使用 CType“list”和自定义 l
实际上,我正在尝试将 ctypes 数组转换为 python 列表并返回。 如果找到this thread 。但它假设我们在编译时知道类型。 但是是否可以检索元素的 ctypes 类型? 我有一个 p
我正在将 float 列表转换为具有以下字段的 ctypes Structure 类,然后再将它们传递给 FFI 函数: FFIArray(Structure): _fields_ = [("
我需要将异质数据的二维数组从我的 c dll 返回到 python。 为此目的,我从我的 c dll 返回一个元组的元组。它作为 PyObject 返回 * 这个元组的元组需要作为第一行第一列的 tu
这是不一致的: from ctypes import * class S(Structure): _fields_ = [("x", POINTER(c_int)), ("y", c_int)
我真的希望一些 Python/Ctypes/C 专家可以帮助我解决这个问题,这可能是我在使用 Python 与 C 库交互时正确使用 Ctypes 的类型结构方面缺乏知识。 目标:我需要访问几个使用
我正在尝试调试 python 使用 ctypes 调用 C 函数的代码。我感兴趣的 python 代码中的一行看起来像: returnValue = cfunction() 其中 cfunction
我正在开发 DLL/SO 的 Python 包装器。我已经验证了代码可以调用实际的 DLL 和 SO。我想对我的包装器进行单元测试,而不需要安装底层 DLL/SO。我正在考虑使用 mock 。 我遇到
大家。我在使用 ctypes 和 C 代码时遇到内存分配错误。我想知道内存问题是在 C 内部,还是由 ctypes 使用不当引起的。内存错误是 python(79698) malloc: * erro
我想制作一个笑话程序,首先它打开一个消息框,关闭后另一个消息框出现在随机位置。它会一直这样重复,直到有什么东西终止了它的任务。使用 tkinter 消息框,那么这些消息框就无法被 Hook ,我必须制
我对 python 中的变量大小有疑问,我使用 Ctypes 因为我想要一个 1 字节的数字,但是当我试图在 python 中检查它的大小时(通过 sys.getsize ) 它说它是 80 字节但是
我正在尝试在 python lambda 函数中使用 matplotlib 生成图形。我使用库 mathplotlib 导入了一个图层,但它不起作用。 这个想法是生成一个图形,将其保存为临时文件并上传
我正在尝试使用 C 中的 python ctypes 制作简单的库 blake 哈希函数包装器。但只是为了首先测试我的简单 C 辅助函数是否能正常工作,我编写了小的 python 脚本 blake 哈
图书馆代码(简化版): // package1.go package package1 import "C" func Play(s *C.char) { } 客户代码: // main.go pac
到目前为止,我已经得到了一个不适用于 python 的 DLL,并输入 return: I just can't pass it arguments because I doing it wrong
我有一个具有以下签名的 C 函数: void init(int* argc, char** argv[]); 我想使用 Ctypes 从我的 OCaml 代码中调用此函数,但我想不出一个正确的方法来传
我是一名优秀的程序员,十分优秀!