3

The ReadProcessMemory function of kernel32.dll appears to be returning Unicode.

kernel32 = ctypes.windll.kernel32
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

pid = int(raw_input("Enter PID: "))
hproc = kernel32.OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ, False, pid)
lpbaseaddr = 16799644
read_buff = ctypes.create_string_buffer(4)
bytread = ctypes.c_ulong(0)
kernel32.ReadProcessMemory(hproc, lpbaseaddr, read_buff,
                               4, ctypes.byref(bytread))
print read_buff.raw #i also tried read_buff.value

I know the value at that address is 80 because I used cheat engine to make it 80. The print read_buff line returns P. If I make the value of that address 81 with cheat engine and run my program it returns the value Q. I have been messing around and unichr(80) returns P and unichr(81) returns Q. There is obviously a problem with create_string_buff. Should I be using a byte buffer or integer buffer and how would I do that? Using unichr() works for a few values but say the address value is 800, unichr(800) obviously won't work. I'm looking for read_buff to return 50 or 60 or 800, etc.

1 Answer 1

6

It is not returning Unicode, but four bytes as a string (probably '\x80\x00\x00\x00') Pass a pointer to an integer not a string buffer:

read_buff = ctypes.c_uint()
kernel32.ReadProcessMemory(hproc, lpbaseaddr, ctypes.byref(read_buff),
                           ctypes.sizeof(read_buff), ctypes.byref(bytread))
print read_buff.value
Sign up to request clarification or add additional context in comments.

5 Comments

thank you so much mark it worked perfectly, thats exactly the answer i was looking for :) one last question tho, the read_buff = ctypes.c_uint() will that hold any size variable? unlike the string buffer where i had to specify 4 bytes long etc.. thanks again for the fast reply
ok one last question.. say i wanted to return that byte string. eg "\x80\x00\x00\x00". what pointer would i use then?
No, c_uint is 4 bytes in size, ctypes.sizeof returns the size. print repr(read_buff.raw) will display the string in escaped format.
sigh every time i push enter it sends... anyway.. heres my code.. read_buff = ctypes.create_string_buffer(4) print repr(read_buff.raw) this returns "\x90\x00\x00\x00" for example. then using the struct module i go struct.unpack("i", "\x90\x00\x00\x00") and it gives me the integer i want :) but now how do i get the string version? say for example at that address the value could be an int or a str of a word and i want to try both possible options to see which might contain the value im looking for... thanks
If it is a string just use create_string_buffer like you were using, and print read_buff.value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.