如何使用WriteProcessMemory(WPM)替换字符串?

时间:2018-05-29 19:40:07

标签: c++ string readprocessmemory

我正在尝试编写一个简单的代码,用另一个使用WPM替换程序中的字符串,我能够使它工作,但只是部分。这是我用来获得结果的代码的一部分。

string strWrite;
cin >> strWrite;
strWrite = strWrite + "\0";
if (WriteProcessMemory(hProcess, (LPVOID) reqdAddr, &strWrite[0], strWrite.size(), NULL) == false)
    {
        cout << "WriteProcessMemory failed. GetLastError = " << dec << GetLastError() << endl;
        system("pause");
        return EXIT_FAILURE;
    }

当我尝试用DefaultString替换原始字符串blabla时,我得到的结果是blablatString。我尝试过将strWrite.size()替换为strWrite.size() + 1,并意识到结果会更改为blabla String。我需要帮助替换整个字符串而不仅仅是它的一部分。

2 个答案:

答案 0 :(得分:1)

如果(如果是这样)目标字符串存储为std :: string,则此方法不起作用。它们有一个内部结构,程序员不应该知道(除非你在头文件中挖掘)并且你在那里的代码没有考虑到这一点。即使你这样做,下一版本的编译器可能会破坏你的代码。

因此,请考虑(如果可以)将目标字符串存储为简单的C字符串。只要你没有跑到最后并添加一个终止的nul,覆盖它就会很简单。我会明确地这样做 - 不要假设源字符串是nul-terminated,它可能不是。或者使用std::string.c_str()并从中复制size() + 1个字节。

答案 1 :(得分:0)

std :: string是在后端管理char数组的容器。

就目前而言,在x86上,如果要写入的字符串大小等于或小于当前字符串,则可以相对轻松地执行此操作,但不建议这样做。

容器的偏移量0x14是数组的大小 如果char数组少于15个字符,则该数组存储在偏移量0x4处 如果char数组大于15个字符,则此偏移量将变为指向其他位置的动态数组的指针

因此,您读取数组的大小,然后根据其大小写入正确的地址。此代码将执行此操作,并输出“再见m8”

void WriteExternalString(HANDLE hProc, BYTE* addr, char* newstr)
{

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

        //Write the buffer to the array, +1 to get the null terminator
        WriteProcessMemory(hProc, (BYTE*)(addrOfCharArray), newstr, strlen(newstr) + 1, 0);
    }
    else
    {
        WriteProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), newstr, strlen(newstr) + 1, 0);
    }
}

int main()
{
    std::string str = "Hello Mate";

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());

    char newstr[] = "Goodbye m8";

    WriteExternalString(hProcess, (BYTE*)&str, newstr);

    cout << "string char array = " << str << endl;
    system("pause");

    return 0;
}