我如何在没有大小验证的情况下使用 WriteProcessMemory 写入 C++ 中的内存?
How can i write to the memory in C++ with WriteProcessMemory without size verification?
我一直在尝试使用此代码写入进程的内存(以创建作弊代码):
#include
int main()
{
HWND hWnd = FindWindow(0, "xyz");
if(hWnd == 0)
{
MessageBox(0, "Error cannot find window.", "Error", MB_OK|MB_ICONERROR);
}
else
{
DWORD proccess_ID;
GetWindowThreadProcessId(hWnd, &proccess_ID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);
if(!hProcess)
{
MessageBox(0, "Could not open the process!", "Error!", MB_OK|MB_ICONERROR);
}
else
{
int newdata = 500;
DWORD newdatasize = sizeof(newdata);
if(WriteProcessMemory(hProcess, (LPVOID)0x57C2A4, &newdata, newdatasize, NULL))
{
MessageBox(NULL, "WriteProcessMemory worked.", "Success", MB_OK + MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, "Error cannot WriteProcessMemory!", "Error", MB_OK + MB_ICONERROR);
}
CloseHandle(hProcess);
}
}
return 0;
}
例如,当我用 jz 覆盖 jnz 时,效果很好,因为两者的大小相同。但是当我尝试用 jmp 覆盖例如 pop 时,我得到一个错误,因为这些命令有不同的大小。
我读到 here WriteProcessMemory 执行验证以检查指定地址的可用大小。
我想做的是在不检查大小的情况下写入内存地址,因此程序只需覆盖代码所需的字节数即可。
使用 Cheat Engine 我能够做到这一点,因为它让我可以覆盖必要的字节。
所以我的问题是如何在 C++ 中像使用 Cheat Engine 一样进行操作?
我不知道你的确切问题“如何在 C++ 中像使用 Cheat Engine 一样做?”的答案。因为我不知道 Cheat Engine 如何为您的案例工作。它可能做的事情比仅仅覆盖一条指令要复杂得多。
WriteProcessMemory 不会验证您认为它验证的内容。
它从调用进程的地址 space 中获取字节序列,并将这些字节写入另一个进程。它不会从这些字节或被覆盖的字节中解码任何 x86 指令。它不能,因为它甚至不能确定你写的是代码还是数据。
如果您知道自己在做什么,您肯定可以用较长的指令替换较短的指令。只需编写新的更长的代码。有一个副作用,您还会覆盖(可能部分)旧的短指令之后的一些指令。这可能会在您的补丁后直接破坏代码。
用较短的指令替换较长的指令更容易并且应该没有副作用,只需用 0x90 字节 = NOP 指令填充新指令。
我一直在尝试使用此代码写入进程的内存(以创建作弊代码):
#include
int main()
{
HWND hWnd = FindWindow(0, "xyz");
if(hWnd == 0)
{
MessageBox(0, "Error cannot find window.", "Error", MB_OK|MB_ICONERROR);
}
else
{
DWORD proccess_ID;
GetWindowThreadProcessId(hWnd, &proccess_ID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);
if(!hProcess)
{
MessageBox(0, "Could not open the process!", "Error!", MB_OK|MB_ICONERROR);
}
else
{
int newdata = 500;
DWORD newdatasize = sizeof(newdata);
if(WriteProcessMemory(hProcess, (LPVOID)0x57C2A4, &newdata, newdatasize, NULL))
{
MessageBox(NULL, "WriteProcessMemory worked.", "Success", MB_OK + MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, "Error cannot WriteProcessMemory!", "Error", MB_OK + MB_ICONERROR);
}
CloseHandle(hProcess);
}
}
return 0;
}
例如,当我用 jz 覆盖 jnz 时,效果很好,因为两者的大小相同。但是当我尝试用 jmp 覆盖例如 pop 时,我得到一个错误,因为这些命令有不同的大小。
我读到 here WriteProcessMemory 执行验证以检查指定地址的可用大小。
我想做的是在不检查大小的情况下写入内存地址,因此程序只需覆盖代码所需的字节数即可。
使用 Cheat Engine 我能够做到这一点,因为它让我可以覆盖必要的字节。
所以我的问题是如何在 C++ 中像使用 Cheat Engine 一样进行操作?
我不知道你的确切问题“如何在 C++ 中像使用 Cheat Engine 一样做?”的答案。因为我不知道 Cheat Engine 如何为您的案例工作。它可能做的事情比仅仅覆盖一条指令要复杂得多。
WriteProcessMemory 不会验证您认为它验证的内容。
它从调用进程的地址 space 中获取字节序列,并将这些字节写入另一个进程。它不会从这些字节或被覆盖的字节中解码任何 x86 指令。它不能,因为它甚至不能确定你写的是代码还是数据。
如果您知道自己在做什么,您肯定可以用较长的指令替换较短的指令。只需编写新的更长的代码。有一个副作用,您还会覆盖(可能部分)旧的短指令之后的一些指令。这可能会在您的补丁后直接破坏代码。
用较短的指令替换较长的指令更容易并且应该没有副作用,只需用 0x90 字节 = NOP 指令填充新指令。