5

所以,我正在尝试用 C++ 编写一个程序,以修改另一个程序中的值。在我的例子中,Windows 的计算器。这是代码:

#include <iostream>
#include <windows.h>

using namespace std;

int main(void) {

    int nVal = 2000;

    HWND hWnd = FindWindowA(0, "Calculator");
    if(hWnd == 0){
        cerr << "Could not find window." << endl;
    } else {
        DWORD PID;
        GetWindowThreadProcessId(hWnd, &PID);
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, PID);

        if(!hProc) {
            cerr << "Cannot open process." << endl;
        } else {
            int stat = WriteProcessMemory(hProc, (LPVOID)0xC6A0EB922C, &nVal, (DWORD)sizeof(nVal), NULL);

            if(stat > 0){
                clog << "Memory written to process." << endl;
            } else {
                cerr << "Memory couldn't be written to process." << endl;
            }

            CloseHandle(hProc);

            cin.get();

        }

    }

    return 0;
}

程序试图覆盖一个值,存储在计算器中的“MS”按钮中。问题是程序无法做到这一点。我试图以管理员身份运行可执行文件,但没有任何变化。我在 YouTube 视频上找到了这段代码,那个人使用的是 XP,我使用的是 Windows 8。

我使用Cheat Engine找到了0xC6A0EB922C地址,并尝试修改里面的值,效果很好!

如果有人可以帮助我,请做。谢谢!

4

2 回答 2

7

从您的硬编码地址来看,您的计算器作为 64 位应用程序运行。

如果您的程序编译为 32 位,则硬编码地址(LPVOID)0xC6A0EB922C将被截断为 32 位,因此是错误的。

要解决这个问题,您应该将程序编译为 64 位或使用 32 位计算器作为测试目标。它位于C:\Windows\SysWOW64\calc.exe

WinAPI 函数可能会失败,而且它们的作用可能超出人们的预期。始终检查返回值并GetLastError()在发生错误时调用,这样您就知道失败的原因。

请记住以管理员身份运行程序或在打开其他进程时关闭 UAC。

于 2013-09-23T22:37:11.350 回答
2

除了 typ1232 所说的之外,ALSR也可能会妨碍您。基本上,为了阻止攻击者覆盖程序中的硬编码内存地址,ALSR 将随机化地址空间中的绝对位置。我不是 100% 确定 calc.exe 使用 ASLR,因为它必须在编译时启用(除非您使用EMET等工具)

于 2013-09-23T23:08:50.047 回答