简体   繁体   中英

How do i read a std::string from memory using RPM

Okay, so recently i've been working witth RPM(ReadProccesMemory). But while doing so i bumped into the issue of not being able to read a string the way i wanted it.

This is what i heard/know: I know, when reading a std::string, i get the memory adress of the string OBJECT and not the adress that contains the actual text.I am also aware of "Small String Optimization", and what it does in theory.

I'd like to be able to read the contents of varString(DefaultString) without changing the code of my dummy program(if possible).

The dummy program im reading:

int main() {
    // Variables & Pointers
    int varInt = 123456;
    string varString = "DefaultString";
    cout << sizeof(varString);
    char arrChar[128] = { "Long char array right there ->" };
    int* ptr2int = &varInt;
    int** ptr2ptr = &ptr2int;
    int*** ptr2ptr2 = &ptr2ptr;

    // Printing them out
    while (true){
    cout << "Process ID: " << GetCurrentProcessId() << endl << endl;
    cout << "varInt (0x" << &varInt << ") = " << varInt << endl;
    cout << "varString (" << reinterpret_cast<const void*>(varString.data()) << ") = " << varString << endl;
    cout << "arrChar (0x" << &arrChar << ") = " << arrChar << endl << endl;

    cout << "ptr2int (0x" << &ptr2int << ") = " << &varInt << endl;
    cout << "ptr2ptr (0x" << &ptr2ptr << ") = " << &ptr2int << endl;
    cout << "ptr2ptr2 (0x" << &ptr2ptr2 << ") = " << &ptr2ptr << endl << endl;
    break;
    }

    cin.get();
    return 0;
}

What im currently doing(wont work as intended):

void reading_string(HANDLE handle_procces) {
    uintptr_t memoryAdress_2 = 0x0;
    cout << "Please write down the memory adress of \"varString\" > " << flush;
    cin >> hex >> memoryAdress_2;

    string read_string_object;
    ReadProcessMemory(handle_procces, (LPCVOID)memoryAdress_2, &read_string_object, sizeof(string), NULL);
    cout << "The value of this memory adress is: " << read_string_object << endl;
}

std::string is a container, offset 0x14 is the size of the char array which it manages. If the string is less than 15 characters, the second variable (offset 0x4 or 0x8 depending on x86/x64) is the char array itself. If it's more than 15 characters, this variable turns into a pointer to the char array which is allocated dynamically

We can use this information to read the string externally, it's a hack but it works

Here some sample code which shows you how it's done:

#include <windows.h>
#include <iostream>

using namespace std;

void ReadExternalString(HANDLE hProc, uintptr_t addr, char* dstArray)
{

    unsigned int arraySize;
    //Get the size of the array, offset 0x14 is the size of the array
    ReadProcessMemory(hProc, (BYTE*)(addr + 0x14), &arraySize, sizeof(arraySize), 0);

    if (arraySize > 15)
    {
        uintptr_t addrOfCharArray;
        //dereference the pointer in the second member variable to get the dynamic address of the array
        ReadProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), &addrOfCharArray, sizeof(void*), 0);

        char buffer[500];
        //Read the array into buffer, +1 to get the null terminator
        ReadProcessMemory(hProc, (BYTE*)(addrOfCharArray), &buffer, arraySize + 1, 0);

        //copy the buffer into our ouput argument
        memcpy(dstArray, &buffer, strlen(buffer) + 1);
    }
    else
    {
        ReadProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), dstArray, arraySize, 0);
    }
}

int main()
{

    int processNumber;
    cout << "Enter the process number" << endl;
    cin >> processNumber;
    for (;;)
    {
        uintptr_t memoryAddress = 0x0;
        cout << "Enter memoryAddress" << endl;
        cin >> hex >> memoryAddress;
        cout << hex << memoryAddress << endl;

        HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, processNumber);
        if (hProcess == NULL) { // Failed to get a handle
            cout << "OpenProcess failed. GetLastError = " << dec << GetLastError() << endl;
            system("pause");
            return EXIT_FAILURE;
        }

        char* cString = new char[500];

        ReadExternalString(hProcess, memoryAddress, cString);

        cout << "string char array = " << cString << endl;
        system("pause");
    }
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM