ZeroIntensity
ZeroIntensity

Reputation: 67

Python Ctypes - Writing to memory created by malloc

I have something like this:

import ctypes

dll = ctypes.CDLL('libc.so.6')

dll.malloc.argtypes = ctypes.c_size_t
dll.malloc.restype = ctypes.c_void_p

ptr: int = dll.malloc(100) # how do i write to this memory?
print(ptr) # gives a memory address

How do I set a value to that memory? Preferably a ctypes.py_object.

I'm aware that doing this in Python is a bad idea, but I'm just experimenting with breaking the rules.

Upvotes: 0

Views: 673

Answers (1)

Mark Tolonen
Mark Tolonen

Reputation: 177715

You can write to the pointer similar to C. Cast the void pointer to something that can be dereferenced and write to it with Python or use ctypes to call a C function that can use the pointer. A couple of examples:

import ctypes as ct

dll = ct.CDLL('msvcrt')  # Windows C runtime

# void* malloc(size_t size);
dll.malloc.argtypes = ct.c_size_t,
dll.malloc.restype = ct.c_void_p
# void free(void* ptr);
dll.free.argtypes = ct.c_void_p,
dll.free.restype = None
# char* strcpy(char* dest, const char* src)
dll.strcpy.argtypes = ct.c_char_p, ct.c_char_p
dll.strcpy.restype = ct.c_char_p

# casting to pointer to specific-sized array enables
# use of ".raw" and checks that array bounds aren't exceeded.
ptr = ct.cast(dll.malloc(10), ct.POINTER(ct.c_char * 10))
print(ptr.contents.raw)
# Note use of [:] to replace the entire array contents with a same-sized bytes object
ptr.contents[:] = b'abcdefghij'
print(ptr.contents.raw)

# char (*ptr)(10) isn't correct for strcpy, so cast to char*
dll.strcpy(ct.cast(ptr, ct.POINTER(ct.c_char)), b'ABCDEFGHIJ')
print(ptr.contents.raw)
dll.free(ptr)

Output:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00'
b'abcdefghij'
b'ABCDEFGHIJ'

Upvotes: 2

Related Questions