如何使用 WriteProcessMemory (WPM) 替换字符串?
How to use WriteProcessMemory (WPM) to replace strings?
我正在尝试编写一个简单的代码来使用 WPM 将程序中的字符串替换为另一个字符串,我能够使其工作,但只能部分工作。这是我用来获取结果的代码的一部分。
string strWrite;
cin >> strWrite;
strWrite = strWrite + "[=10=]";
if (WriteProcessMemory(hProcess, (LPVOID) reqdAddr, &strWrite[0], strWrite.size(), NULL) == false)
{
cout << "WriteProcessMemory failed. GetLastError = " << dec << GetLastError() << endl;
system("pause");
return EXIT_FAILURE;
}
当我尝试用 blabla
替换原始字符串 DefaultString
时,我得到的结果是 blablatString
。我已经尝试过将 strWrite.size()
替换为 strWrite.size() + 1
之类的操作,并意识到结果变为 blabla String
。我需要帮助替换整个字符串,而不仅仅是其中的一部分。
如果(似乎是这种情况)目标字符串存储为 std::string,那么此方法将不起作用。它们有一个程序员不应该知道的内部结构(除非你在头文件中四处挖掘)并且你拥有的代码没有考虑到这一点。即使你这样做了,下一个版本的编译器也可能会破坏你的代码。
因此请考虑(如果可以的话)将目标字符串存储为简单的 C 字符串。只要你不 运行 结束并添加一个终止 nul,覆盖它就很简单了。我会明确地这样做——不要假设源字符串是以 nul 结尾的,它可能不是。或者使用 std::string.c_str()
并从中复制 size() + 1
个字节。
std::string 是一个在后端管理 char 数组的容器。
就目前而言,在 x86 上,如果您要写入的字符串与当前字符串大小相同或更小,您可以相对轻松地执行此操作,但不推荐这样做。
容器的offset 0x14为数组的大小
如果 char 数组少于 15 个字符,则数组存储在偏移量 0x4 处
如果 char 数组大于 15 个字符,则此偏移量将变成指向其他地方的动态数组的指针
所以你读取了数组的大小,然后根据它的大小写入正确的地址。此代码将执行此操作并输出 "goodbye 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;
}
我正在尝试编写一个简单的代码来使用 WPM 将程序中的字符串替换为另一个字符串,我能够使其工作,但只能部分工作。这是我用来获取结果的代码的一部分。
string strWrite;
cin >> strWrite;
strWrite = strWrite + "[=10=]";
if (WriteProcessMemory(hProcess, (LPVOID) reqdAddr, &strWrite[0], strWrite.size(), NULL) == false)
{
cout << "WriteProcessMemory failed. GetLastError = " << dec << GetLastError() << endl;
system("pause");
return EXIT_FAILURE;
}
当我尝试用 blabla
替换原始字符串 DefaultString
时,我得到的结果是 blablatString
。我已经尝试过将 strWrite.size()
替换为 strWrite.size() + 1
之类的操作,并意识到结果变为 blabla String
。我需要帮助替换整个字符串,而不仅仅是其中的一部分。
如果(似乎是这种情况)目标字符串存储为 std::string,那么此方法将不起作用。它们有一个程序员不应该知道的内部结构(除非你在头文件中四处挖掘)并且你拥有的代码没有考虑到这一点。即使你这样做了,下一个版本的编译器也可能会破坏你的代码。
因此请考虑(如果可以的话)将目标字符串存储为简单的 C 字符串。只要你不 运行 结束并添加一个终止 nul,覆盖它就很简单了。我会明确地这样做——不要假设源字符串是以 nul 结尾的,它可能不是。或者使用 std::string.c_str()
并从中复制 size() + 1
个字节。
std::string 是一个在后端管理 char 数组的容器。
就目前而言,在 x86 上,如果您要写入的字符串与当前字符串大小相同或更小,您可以相对轻松地执行此操作,但不推荐这样做。
容器的offset 0x14为数组的大小 如果 char 数组少于 15 个字符,则数组存储在偏移量 0x4 处 如果 char 数组大于 15 个字符,则此偏移量将变成指向其他地方的动态数组的指针
所以你读取了数组的大小,然后根据它的大小写入正确的地址。此代码将执行此操作并输出 "goodbye 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;
}