-1

I try to read the memory of a process with this code :

int main() {
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, 0, FindProcessId());

DWORD me;
cin >> me;

char buffer[256];

ReadProcessMemory(hProcess, (LPVOID)me, &buffer, sizeof(buffer), 0);

cout << "Data read : " << buffer << endl;

system("pause");

return 0;}

but when I start and enter an adress like : 0x7ffe0014

It prints this : ╠╠╠╠╠╠╠╠ (this * 256 I think)

But I don't know why.

Can you help me ? Thank you.

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59
Strangy
  • 21
  • 1
  • 2
  • 2
    What does `ReadProcessMemory()` return when you call it? If `0`, then it's failing and `buffer` might not have been updated; you'd then have to call `GetLastError()` to see what the error is. – frslm Nov 03 '17 at 21:45
  • 2
    And is the data you read *printable*? Is it supposed to be a null-terminated string? What did you *expect* to be printed? Please take some time to [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask). – Some programmer dude Nov 03 '17 at 21:48
  • and what you wait at address `7ffe0014` ? what sense print it content ? – RbMm Nov 03 '17 at 22:04
  • `ReadProcessMemory()` returns good I think when I call it. `GetLastError()` returns `749B4F10` . Printed means `cout` for me. This adress was an exmple but the same caracter appear when I want to read this string : `D$Pff` or this int : 1 – Strangy Nov 03 '17 at 22:17
  • @Strangy Why do you make the assumption, that process memory will always consist of printable characters? – Algirdas Preidžius Nov 03 '17 at 22:19
  • Characters will always be printable. They are not like this : `'\000'` – Strangy Nov 03 '17 at 22:22
  • 1
    What you read is an arbitrary chunk of *bytes*. Even though you use the type `char` doesn't mean it's actually something you can print, it's just bytes of indeterminate data. – Some programmer dude Nov 03 '17 at 22:30
  • 1
    You don't do any error checking. Any money says one of these calls fails. – David Heffernan Nov 03 '17 at 22:46
  • you didn't check the result of `cin`, so if you accidentally put an address outside `DWORD` range you'll have problem. And `me` isn't a `LPVOID`, doing that on win64 is UB. More over how do you know which address to read? Reading random addresses will just give you errors which you don't check either. The `╠` series is 0xCC in the default [codepage 437](https://en.wikipedia.org/wiki/Code_page_437) which is [what MSVC filled into uninitialized memory to aid debugging](https://stackoverflow.com/q/370195/995714). You see that because ReadProcessMemory didn't write anything to the buffer – phuclv May 06 '18 at 16:23

1 Answers1

1

buffer is defined as a char and when you pass buffer to std::cout it prints the char representation of the bytes stored in buffer. You try to fill buffer by calling ReadProcessMemory() on an arbitrary memory address, but it fails.

buffer is not initialized and because ReadProcessMemory fails it's printing the char representation of the un-initialized memory inside buffer.

Here is your code modified to call ReadProcessMemory on a variable in the current process, perhaps easier for learning purposes.

HANDLE hProcess = OpenProcess(PROCESS_VM_READ, 0, GetCurrentProcessId());

char buffer[20];

char* me = "Test";

ReadProcessMemory(hProcess, me, &buffer, sizeof(me)+1, 0);

std::cout << "Data read : " << buffer << std::endl;

system("pause");

return 0;

This would correctly output "Data read : Test" to the console.

If you assign nullptr to "char* me" you will get the same "╠╠╠╠╠╠╠╠" mumbo jumbo that you got previously as it will point at address 0x0 which is typically uninitialized.

Keep in mind if you're trying to read a string from another process you will want to reverse engineer the hard coded string size if it's not null terminated and only read the correct number of bytes.

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59