MikeKZ4444
MikeKZ4444

Reputation: 13

ReadProcessMemory not working properly with UTF16 string

I'm learning C++ and was messing around with Win32 api, particularly ReadProcessMemory.

So I'm trying to read text from notepad, I've found the address using Cheat Engine. The text is in Windows UTF16

Here's the code I use to read the text:

#include "pch.h"
#include <string>
#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    LPCVOID Addr = (LPCVOID) 0x1711B91E610;
    HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, 9948);

    u16string data[29];

    if (!handle) {
        exit(0);
    }

    ReadProcessMemory(handle, Addr, &data, 29, 0);
    cout << data << endl;

    cin.get();
}

I was expecting to get this Hello world!zzzzzeeeeeezzzees however, I got this: 00000053A7EFF260

What am I doing wrong? Thank you

edit: tried wcout, also not working

And everytime I run the program, I get a different hex value, what?

Upvotes: 1

Views: 575

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595369

u16string data[29]; is an array of 29 u16string objects, it is not a single u16string with a length of 29 chars, like you think it is.

Also, the nSize parameter of ReadProcessMemory() expects a byte count, not a character count. UTF-16 uses 2-byte characters.

Try this instead:

#include "pch.h"
#include <string>
#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    LPCVOID Addr = reinterpret_cast<LPVOID>(0x1711B91E610);

    HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, 9948);
    if (!handle) {
        return 0;
    }

    u16string data(29, u'\0');
    // or:
    // u16string data; data.resize(29);

    ReadProcessMemory(handle, Addr, &data[0], 29*sizeof(char16_t), 0);
    wcout << reinterpret_cast<const wchar_t*>(data.c_str()) << endl;

    cin.get();
    return 0;
}

Upvotes: 0

KiKoS
KiKoS

Reputation: 438

First please check your address twice, the 4th argument of ReadProcessMemory takes the number of bytes to read and in this case each character in your string is 2 bytes wide so you have to pass 2*29=58 as the size and finally don't use C++ string because in this case you need a simple data buffer to copy data to and u16string is a complex object with other attributes and methods.

u16string data[29];

This line doesn't create a string with 29 characters but it creates 29 string objects, so use something like this instead:

wchar_t data[30];
data[29] = L'\0';

Allocating 30 is for the null character that terminates the string.

For printing wide char characters use:

wcout << data << endl;

Upvotes: 1

Related Questions