我有这个AA脚本(Cheat Engine脚本语言):
[ENABLE]
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(exit)
00415e19:
jmp newmem
returnhere:
newmem:
mov [00451104],0//moves 0 to the clock variable
//nop//nops the clock increaser
exit:
jmp returnhere
[DISABLE]
dealloc(newmem)
00415e19:
mov [00451104],eax
//Alt: db A3 04 11 45 00
它正在工作 - 停止游戏时钟。现在,我正在尝试将此代码转换为C ++。这是我到目前为止所做的:
#include <windows.h>
HWND FindIcyTower()
{
return FindWindowA(NULL, "Icy Tower v1.4");
}
void WPM(HWND hWnd,int address, byte *data, int dataSize)
{
DWORD proc_id;
GetWindowThreadProcessId(hWnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);
if(!hProcess)
return;
WriteProcessMemory(hProcess, (LPVOID)address, data, dataSize, NULL);
CloseHandle(hProcess);
}
void EnableClockHack()
{
WPM(FindIcyTower(), 0x00415E19, {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}, 9);
}
void DisableClockHack()
{
WPM(FindIcyTower(), 0x00415E19, {0xA3, 0x04, 0x11, 0x45, 0x00}, 4);
}
但它会使游戏崩溃,而不是停止时钟。任何想法?返回FindWindowA(NULL,“Icy Tower v1.4”);
答案 0 :(得分:3)
用于移动立即的操作码(就像你试图做的那样)比从寄存器(4个字节)移动的游戏原始代码更长(9个字节)。额外的5个字节很可能在原始mov导致程序崩溃后覆盖一两条指令。
就像在Cheat Engine中一样,你需要在目标进程中分配新内存来放置修改代码,这样你就不会覆盖任何游戏代码。由于处理器将使用此存储器执行,因此需要设置执行位。
一旦你注入了你的mod代码,你就可以将游戏的原始mov [00451104],eax
改为jmp到mod代码起始地址。在替换jmp之后,mod代码中的最后一条指令需要是一个jmp回到指令,这将恢复游戏的执行。
请参阅VirtualAllocEx在其他进程中分配内存,VirtualProtectEx用于在该内存上设置PAGE_EXECUTE,当然还有VirtualFreeEx用于在完成内存时释放内存。
答案 1 :(得分:0)
不知道AA脚本的语法,但我得到了几点:
mov [00451104],0
应翻译为'将中间值0移动到位置00451104'。你的C ++代码是:
WPM(FindIcyTower(), 0x00415E19, {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}, 9);
为什么使用中间版{0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}
代替0
({0,0,0,0}
)?
您可能还需要首先读取偏移量0x00415E19
中的值(这可能是AA代码通过在mov
指令前加上分配缓冲区的名称来隐式执行的操作),所以你以后可以恢复Disable...
函数中的原始值。