我一直在尝试使用此代码写入进程的内存(以创建作弊码):
#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一样?
答案 0 :(得分:0)
我不知道您的准确问题的答案“如何在C ++中与Cheat Engine一样?”因为我不知道Cheat Engine如何适用于您的情况。它可能正在做一些比覆盖单个指令更复杂的事情。
WriteProcessMemory不会验证您认为它验证的内容。
它从调用进程的地址空间获取一个字节序列,将这些字节写入另一个进程。它不会从这些字节解码任何x86指令,也不会从被覆盖的字节解码。它不能,因为它甚至不确定你是在编写代码还是数据。
如果你知道自己在做什么,你肯定可以用更长的说明来替换更短的说明。只需编写新的更长的代码。有一个副作用,你也会覆盖(可能是部分)一些旧的短指令之后的指令。这可能会在您的补丁后直接破坏代码。
用较短的指令替换较长的指令更容易,并且应该没有副作用,只需用0x90字节= NOP指令填充新指令。