1

我正在尝试为 Icy Tower 1.4 创建一个培训师用于教育目的。

我写了一个函数来缩短 WriteProcessMemory 函数,如下所示:

void WPM(HWND hWnd,int address,byte data[])
{
    DWORD proc_id;
    GetWindowThreadProcessId(hWnd, &proc_id);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);

    if(!hProcess)
        return;

    DWORD dataSize = sizeof(data);
    WriteProcessMemory(hProcess,(LPVOID)address,&data,dataSize,NULL);
    CloseHandle(hProcess);
}

这就是应该停止冰塔时钟的功能:

void ClockHack(int status)
{
    if(status==1)//enable
    {
        //crashes the game
        byte data[]={0xc7,0x05,0x04,0x11,0x45,0x00,0x00,0x00,0x00,0x00};
        WPM(FindIcyTower(),0x00415E19,data);
    }
    else if(status==0)//disable
    {
            byte data[]={0xA3,0x04,0x11,0x45,0x00};
    }
}

在 else 语句中有操作码的原始 AOB。当我在 status 参数设置为 1 的情况下调用 ClockHack 函数时,游戏崩溃了。

在 Cheat Engine 中,我为此编写了一个脚本,该脚本并不完全写入同一个地址,因为我做了 Code Cave,而且效果很好。

有人知道为什么吗?谢谢你。

顺便说一句:它仅用于教育目的

4

2 回答 2

2

您不能将数组传递给这样的函数。有一个byte[]参数与一个参数相同byte *sizeof(data)只会给你一个指针的大小。此外,您不应该使用它,&data因为它已经是一个指针。

所以你的函数应该是这样的:

void WPM(HWND hWnd,int address, byte *data, int dataSize)
{
    //....
    WriteProcessMemory(hProcess,(LPVOID)address,data,dataSize,NULL);
    //...
}
于 2010-01-15T22:45:58.933 回答
2

当一个数组被传递给一个函数时,它总是通过引用传递,所以 byte[] 与 byte* 相同,并且您只编写sizeof(byte*)代码的第一个字节。或 X86 平台上的 4 个字节。

此外,看起来您正在编写的是目标代码,如果不是,则忽略此答案的其余部分。

好吧,假设您正在写入正确的位置,并且您正在编写的内容是正确的,那么您仍然有问题 -WriteProcessMemory不能保证相对于目标进程中运行的线程是原子的。

您需要确保该目标线程已暂停,并且不在该部分代码中执行。而且我不知道您(可能)需要做什么来刷新指令解码管道和/或 L1 缓存。

编辑:现在我想了更多。我认为使用互斥锁来保护这段代码在执行时不被覆盖比暂停线程更好。

于 2010-01-15T22:59:32.033 回答