我如何使用RPM从内存中读取std :: string

问题描述 投票:0回答:1

好,最近我一直在使用RPM(ReadProccesMemory)。但是在这样做的同时,我遇到了无法以我想要的方式读取字符串的问题。

这是我听到/知道的:我知道,当读取std :: string时,我得到的是字符串OBJECT的内存地址,而不是包含实际文本的地址。我也知道“小字符串优化”及其理论上的作用。

我希望能够在不更改虚拟程序代码的情况下(如果可能)读取varString(DefaultString)的内容。

正在读取的虚拟程序:

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;
}

我当前正在做什么(不会按预期工作):

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;
}

c++ memory stdstring
1个回答
0
投票

std :: string是一个容器,偏移量0x14是它管理的char数组的大小。如果字符串少于15个字符,则第二个变量(偏移量0x4或0x8,取决于x86 / x64)是char数组本身。如果超过15个字符,则此变量将变为指向动态分配的char数组的指针

我们可以使用此信息从外部读取字符串,这是一种技巧,但可以使用

这里有一些示例代码向您展示了如何完成:

#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;
}
© www.soinside.com 2019 - 2024. All rights reserved.