2

我一直在尝试使用此代码写入进程的内存(以创建作弊码):


    #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 时,我会收到一个错误,因为这些命令的大小不同。

我在这里读到WriteProcessMemory 执行验证以检查指定地址的可用大小。

我想要做的是在没有大小检查的情况下写入内存地址,因此程序只需覆盖代码所需的尽可能多的字节。

使用 Cheat Engine 我能够做到这一点,因为它让我可以覆盖必要的字节。

所以我的问题是如何在 C++ 中做与 Cheat Engine 相同的操作?

4

1 回答 1

0

我不知道您的确切问题“如何在 C++ 中与 Cheat Engine 相同?”的答案。因为我不知道作弊引擎如何为您的案例工作。它可能会做一些比仅仅覆盖一条指令更复杂的事情。

WriteProcessMemory 不会验证您认为它验证的内容。

它从调用进程的地址空间中获取一个字节序列,将这些字节写入另一个进程。它不会从这些字节中解码任何 x86 指令,也不会从被覆盖的字节中解码。它不能,因为它甚至不确定你是在编写代码还是数据。

如果您知道自己在做什么,那么您肯定可以用较长的指令代替较短的指令。只需编写新的更长的代码。有一个副作用,您还将覆盖(可能部分)一些在旧的短指令之后的指令。这可能会在您的补丁之后直接破坏代码。

用较短的指令替换较长的指令更容易并且应该没有副作用,只需用 0x90 字节 = NOP 指令填充新指令。

于 2016-09-10T23:59:59.757 回答