0

What would be the difference between:

pointer = ctypes.c_char_p('abc')

and

string = 'abc'
buffer = (ctypes.c_char * len(string)).from_buffer(string)

Technically both are pointers when passed in their respective function calls like such: (cross platform different function calls)

if os.name == 'posix':
    string = 'abc'
    libc = ctypes.CDLL('libc.so.6')

    # creating a pointer pointing at our string
    s_ptr = ctypes.c_char_p(string)

    # allocating free space
    free_space_ptr = ctypes.c_void_p(libc.valloc(ctypes.c_int(len(string))))

    # copying memory from one loc to another
    ctypes.memmove(free_space_ptr, s_ptr, ctypes.c_int(len(string)))

else:
    string = 'abc'

    # allocating free space
    free_space_ptr = ctypes.windll.kernel32.VirtualAlloc(...)

    # creating a pointer pointing at our string?
    buffer = (cytpes.c_char_p * len(string))).from_buffer(string)

    # copying memory from one loc to another
    ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_void_p(free_space_ptr), buffer, ctypes.c_int(len(shellcode)))

My Question is:

The two function calls (both memmove, and RtlMoveMemory) take in two pointers ==> destination, source, and then the last param is the length to copy.

What is the difference in the two ways of getting a pointer that points to our string?:

  • Using ctypes.c_char_p(string)

vs

  • Using ctypes.c_char.from_buffer(string)
0x5929
  • 400
  • 1
  • 4
  • 16
  • 1
    One difference is `ctypes.c_void_p('abc')` doesn't work :^) I don't see the point of this code. I think `create_string_buffer()` would do the same thing as this OS-specific code. – Mark Tolonen May 30 '18 at 04:54
  • Oh yeah it should be ctypes.c_char_p(string), fixed in the edit. But do you think if these ways can be used on the other platform? eg. Using ctypes.c_char_p(string) and passing it into the ms api RtlMoveMemory function as the source param, I wonder if that will work... – 0x5929 May 30 '18 at 05:16
  • thanks btw @Mark, just cant upvote b/c not enough reps, but yeah create_string_buffer() would also be a great way to create a buffer of char pointer which is just a char array. – 0x5929 May 30 '18 at 05:23

1 Answers1

1

After many tests, it can be concluded that

First:

ctypes.c_char.from_buffer(string)

wouldn't work because the from_buffer method accepts a param that is an array of bytes, so I would need to convert string into array of bytes first like such:

buf = bytearray(string)
ptr = ctypes.c_char.from_buffer(string)

now both returned results of:

ctypes.c_char_p(string)

and

ctypes.c_char.from_buffer(buf)

can be used in memory copying operation function calls like:

ctypes.memmove for linux 

and

RtlMemoryMove for windows 
0x5929
  • 400
  • 1
  • 4
  • 16