Reputation: 67
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
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