Code:
void walk(HANDLE pHandle, DWORD baseAddress, int direction, bool dash)
{
BYTE codeCave[32]{
0x60, //PUSHAD
0x9C, //PUSHFD
0x68, 0x00, 0x00, 0x00, 0x00, //PUSH DASH
0x68, 0x00, 0x00, 0x00, 0x00, //PUSH DIRECTION
0xB9, 0x00, 0x00, 0x00, 0x00, //MOVE ECX, GAME ADDRESS
0xB8, 0x00, 0x00, 0x00, 0x00, //MOVE EAX, WALK FUNCTION ADDRESS
0xFF, 0xD0, //CALL
0x9D, //POPFD
0x61, //POPAD
0x68, 0x00, 0x00, 0x00, 0x00, //PUSH OriginalEIP
0xC3 //RETURN
};
DWORD gameAddress = baseAddress + 0x8036f0;
DWORD walkFunctionAddress = baseAddress + 0x11FD3;
int caveLenght = sizeof(codeCave);
LPVOID remoteCave = VirtualAllocEx(pHandle, 0, caveLenght, MEM_COMMIT, PAGE_EXECUTE);
DWORD mainThreadId = getProcessThreadId(pHandle);
HANDLE hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT), false, mainThreadId);
SuspendThread(hThread);
CONTEXT threadContext;
threadContext.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hThread, &threadContext);
memcpy(&codeCave[3], &dash, 1);
memcpy(&codeCave[8], &direction, 4);
memcpy(&codeCave[13], &gameAddress, 4);
memcpy(&codeCave[18], &walkFunctionAddress, 4);
memcpy(&codeCave[27], &threadContext.Eip, 4);
WriteProcessMemory(pHandle, remoteCave, codeCave, caveLenght, NULL);
threadContext.Eip = (DWORD)remoteCave;
threadContext.ContextFlags = CONTEXT_CONTROL;
SetThreadContext(hThread, &threadContext);
ResumeThread(hThread);
CloseHandle(hThread);
VirtualFreeEx(pHandle, remoteCave, caveLenght, MEM_RELEASE);