private void UnpauseGame() { MemoryManager.WriteInt(MemoryManager.CalculatePointer(INRACE_BASEADDRESS, PAUSED_SELECTED_INDEX_OFFSET), 0); // select index 0 MemoryManager.WriteInt(MemoryManager.CalculatePointer(INRACE_BASEADDRESS, PAUSED_CURRENT_MENU_OFFSET), 0); // set current menu to 0 int esi = MemoryManager.ReadInt(INRACE_BASEADDRESS) + INRACE_ESI_OFFSET; List <byte> codetoinject = new List <byte>(); codetoinject.Add(0xBE); codetoinject.AddRange(BitConverter.GetBytes(esi)); // mov esi,'esi' codetoinject.AddRange(new byte[] { 0x8B, 0xCE }); // mov ecx,esi codetoinject.Add(0xE8); codetoinject.AddRange(BitConverter.GetBytes(UNPAUSE_FUNCTION_ADDRESS - (int)(MemoryManager.NewMemory + codetoinject.Count + 4))); // call function codetoinject.Add(0xC3); // ret MemoryManager.WriteBytes(MemoryManager.NewMemory, codetoinject.ToArray()); MemoryManager.CreateThread(MemoryManager.NewMemory); // select menu item 0,0 (continue race) }
/// <summary> /// Sets the value whether AI drivers use Power-ups. /// </summary> /// <param name="value">The value whether the AI drivers use Power-ups or not.</param> /// <returns>Returns whether the set was successful or not.</returns> private bool SetAIUsePowerUps(bool value) { bool result = true; if (value) { result &= MemoryManager.WriteBytes(POWERUP_FUNCTION_BASE, new byte[] { 0x8b, 0x86 }); result &= MemoryManager.WriteBytes(POWERUP_FUNCTION_BASE + 2, BitConverter.GetBytes(DRIVER_OFFSET_BRICK)); // mov eax,[esi+00000CCC] } else { UInt32 targetMem = MemoryManager.NewMemory + 0x300; List <byte> bytestowrite = new List <byte>(); bytestowrite.Add(0xE9); bytestowrite.AddRange(BitConverter.GetBytes((int)(targetMem - (POWERUP_FUNCTION_BASE + 5)))); // jmp targetmem bytestowrite.Add(0x90); // nop result &= MemoryManager.WriteBytes(POWERUP_FUNCTION_BASE, bytestowrite.ToArray()); bytestowrite.Clear(); bytestowrite.AddRange(new byte[] { 0x8b, 0x0d }); bytestowrite.AddRange(BitConverter.GetBytes(DRIVER_BASEADDRESS)); // mov ecx,[004C67BC] for (int i = 0; i < DRIVER_BASE_OFFSETS.Length; i++) { bytestowrite.AddRange(new byte[] { 0x8b, 0x89 }); bytestowrite.AddRange(BitConverter.GetBytes(DRIVER_BASE_OFFSETS[i])); } bytestowrite.AddRange(new byte[] { 0x39, 0xf1 }); // cmp ecx,esi bytestowrite.AddRange(new byte[] { 0x0f, 0x84, 0x05, 0x00, 0x00, 0x00 }); // je +5 bytestowrite.AddRange(new byte[] { 0x8b, 0xce }); // mov ecx,esi bytestowrite.Add(0x5f); // pop edi bytestowrite.Add(0x5e); // pop esi bytestowrite.Add(0xc3); // ret bytestowrite.AddRange(new byte[] { 0x8b, 0x86 }); bytestowrite.AddRange(BitConverter.GetBytes(DRIVER_OFFSET_BRICK)); // mov eax,[esi+poweruptype_offset] bytestowrite.Add(0xe9); bytestowrite.AddRange(BitConverter.GetBytes((POWERUP_FUNCTION_BASE + 6) - (int)(targetMem + bytestowrite.Count + 4))); // jmp 0043910A result &= MemoryManager.WriteBytes(targetMem, bytestowrite.ToArray()); } return(result); }
private void PauseGame() { MemoryManager.WriteInt(MemoryManager.CalculatePointer(INRACE_BASEADDRESS, INRACE_PAUSED_OFFSET), 1); // 1) pause game int esi = MemoryManager.ReadInt(INRACE_BASEADDRESS) + INRACE_ESI_OFFSET; List <byte> codetoinject = new List <byte>(); if (this.GetType() == typeof(Client_2001)) { codetoinject.AddRange(new byte[] { 0x6A, 0x00 }); // push 00 } codetoinject.Add(0xBE); codetoinject.AddRange(BitConverter.GetBytes(esi)); // mov esi,'esi' codetoinject.AddRange(new byte[] { 0x8B, 0xCE }); // mov ecx,esi codetoinject.Add(0xE8); codetoinject.AddRange(BitConverter.GetBytes(PAUSE_FUNCTION_ADDRESS - (int)(MemoryManager.NewMemory + codetoinject.Count + 4))); // call function codetoinject.Add(0xC3); // ret MemoryManager.WriteBytes(MemoryManager.NewMemory, codetoinject.ToArray()); MemoryManager.CreateThread(MemoryManager.NewMemory); // 2) stop music, open menu, etc. }
public bool RemoveMenuButtons() { bool result = true; result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0xB, 0x00); // build result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0xB + 1 * 0x14, 0x00); // circuit result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0xB + 2 * 0x14, 0x00); // singlerace result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0xB + 3 * 0x14, 0x55); // versus (moving to location 55 (circuit)) result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0xB + 4 * 0x14, 0x00); // timeattack result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0xB + 5 * 0x14, 0x00); // options //result &= writeByte(MAINMENU_BUTTONS_BASE + 0xB + 6*0x14, 0x00); // exit result &= MemoryManager.WriteByte(RACERSELECT_BUTTONS_BASE + 0x49, 0x00); // cancel racer selection result &= MemoryManager.WriteBytes(MAINMENU_BUTTONS_BASE + 0x98, new byte[] { 0x90, 0x90, 0x90, 0x90 }); // always disable versus result &= MemoryManager.WriteByte(MAINMENU_BUTTONS_BASE + 0x3D, 46); // set versus button text to line 47 of menustrings.srf result &= MemoryManager.WriteBytes(GetMenuStringsAddress(46), MemoryManager.GetStringBytes("WAITING FOR SERVER TO START A RACE...")); return(result); }
/// <summary> /// Sets the value whether to load RRB (AI path) files. /// </summary> /// <param name="value">The value whether to load RRB (AI path) files or not.</param> /// <returns>Returns whether the set was successful or not.</returns> private bool SetLoadRRB(bool value) { bool result = true; if (initialized) { if (value == true) { result &= MemoryManager.WriteBytes(LOAD_RRB_BASE, new byte[] { 0x75, 0x0C }); // JNE +332AD result &= MemoryManager.WriteBytes(LOAD_RRB_BASE + 4, new byte[] { 0x75, 0x08 }); // JNE +332AD result &= MemoryManager.WriteByte(LOAD_RRB_BASE + 0xC, 0x74); // JE } else { result &= MemoryManager.WriteBytes(LOAD_RRB_BASE, new byte[] { 0x90, 0x90 }); // NOP NOP result &= MemoryManager.WriteBytes(LOAD_RRB_BASE + 4, new byte[] { 0x90, 0x90 }); // NOP NOP result &= MemoryManager.WriteByte(LOAD_RRB_BASE + 0xC, 0xEB); // JMP } } return(result); }
/// <summary> /// Navigates to a given menu. /// </summary> /// <param name="targetmenu">The menu to navigate to.</param> public void GotoMenu(Menu targetmenu) { if (initialized) { Menu currentMenu = GetCurrentMenu(); Console.WriteLine(currentMenu + " -> " + targetmenu); int offset = 0; int ECXbase = memoryManager.ReadInt(memoryManager.ReadInt(MENU_BASE) + TARGETMENU_ECX_OFFSET); int ESIbase = memoryManager.ReadInt(memoryManager.ReadInt(MENU_BASE) + TARGETMENU_ESI_OFFSET); if (ECXbase != ESIbase) // if a prompt is open { switch (currentMenu) { case Menu.Options: if (targetmenu == Menu.DisplayOptions) { offset = 0x549C; } break; case Menu.Build: // delete racer if (targetmenu == Menu.PromptYes) { offset = 0x5B38; } else if (targetmenu == Menu.PromptNo) { offset = 0x5E28; } break; case Menu.CreateDriver: // cancel if (targetmenu == Menu.PromptYes) { offset = 0x3FD0; } else if (targetmenu == Menu.PromptNo) { offset = 0x42C0; } break; default: return; } } else { switch (currentMenu) { case Menu.MainMenu: if (targetmenu == Menu.Build) { offset = 0x1058; } else if (targetmenu == Menu.SingleRace) { offset = 0x498; } else if (targetmenu == Menu.Options) { offset = 0x1348; } else if (targetmenu == Menu.TimeAttack) { offset = 0xD68; } else if (targetmenu == Menu.Circuit) { offset = 0x788; } else { return; } break; case Menu.Build: if (targetmenu == Menu.MainMenu) { offset = 0x5848; } else if (targetmenu == Menu.CreateDriver) { offset = 0x40C8; } else if (targetmenu == Menu.DeleteRacer) // opens a prompt { offset = 0x4999; } else if (targetmenu == Menu.EditRacer) // Not finished { offset = 0x43B8; } else if (targetmenu == Menu.CopyRacer) { offset = 0x46A8; } else { return; } break; case Menu.Options: if (targetmenu == Menu.MainMenu) { offset = 0x18D8; } else if (targetmenu == Menu.ControlsP1) { offset = 0xA28; } else if (targetmenu == Menu.ControlsP2) { offset = 0xD18; } else if (targetmenu == Menu.GameOptions) { offset = 0x448; } else if (targetmenu == Menu.PromptDisplayOptions) // opens a prompt { offset = 0x51AC; } else if (targetmenu == Menu.Options) // currentmenu==DisplayOptions or GameOptions { offset = 0x18D8; } else { return; } break; case Menu.Controls: if (targetmenu == Menu.Options) { offset = 0x47C; } else { return; } break; case Menu.SingleRace: if (targetmenu == Menu.MainMenu) { offset = 0x1CCC; } else if (targetmenu == Menu.ChooseRacer) { offset = 0x19DC; } else { return; } break; case Menu.TimeAttack: if (targetmenu == Menu.MainMenu) { offset = 0x1CC; } else { return; } break; case Menu.Circuit: if (targetmenu == Menu.MainMenu) { offset = 0x1c34; } else if (targetmenu == Menu.ChooseRacer) { offset = 0x1F24; } else { return; } break; case Menu.CreateDriver: if (targetmenu == Menu.CancelDriver) // opens a prompt { offset = 0x39F0; } else if (targetmenu == Menu.CreateLicense) { offset = 0x3CE0; } else { return; } break; case Menu.CreateLicense: if (targetmenu == Menu.CreateDriver) { offset = 0xA88; } else if (targetmenu == Menu.BuildCar) { offset = 0xD78; } else { return; } break; case Menu.BuildCar: if (targetmenu == Menu.Build) { offset = 0x11E4; } else if (targetmenu == Menu.CreateLicense) { offset = 0x14D4; } else { return; } break; case Menu.ChooseRacer: if (targetmenu == Menu.Circuit || targetmenu == Menu.SingleRace || targetmenu == Menu.TimeAttack) { offset = 0x4998; } else if (targetmenu == Menu.StartRace) { offset = 0x40C8; } else { return; } break; default: return; } } List <byte> codeToInject = new List <byte>(); codeToInject.Add(0xB9); codeToInject.AddRange(BitConverter.GetBytes(ECXbase)); // mov ecx,neededECX codeToInject.Add(0xBE); codeToInject.AddRange(BitConverter.GetBytes(ESIbase + offset)); // mov esi,neededESI codeToInject.AddRange(new byte[] { 0x8B, 0x11, 0x56, 0xFF, 0x52, 0x38, 0xC3 }); // mov edx,[ecx] | push esi | call dword ptr [edx+38] | ret // Write code to the assigned memory and execute it memoryManager.WriteBytes((int)memoryManager.NewMemory, codeToInject.ToArray()); memoryManager.Execute(memoryManager.NewMemory); } }
/// <summary> /// Uses a Power-up from the driver. This does not trigger the PowerUpUsed event. /// </summary> /// <param name="brick">The Brick type to use.</param> /// <param name="whiteBricks">Amount of White bricks to use.</param> public void UsePowerUp(Brick brick, int whiteBricks) { if (driverNumber >= 0 && driverNumber <= 5 && brick != Brick.White && brick != Brick.None) { int function = 0; switch (brick) { case Brick.Red: // Red Power-up function = powerUpRed; break; case Brick.Blue: // Blue Power-up function = powerUpBlue; break; case Brick.Green: // Green Power-up function = powerUpGreen; break; case Brick.Yellow: // Yellow Power-up function = powerUpYellow; break; default: return; } int raceraddress; if (driverNumber == 0) { raceraddress = memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(0x004C67BC) + 0x60) + 0xA8) + 0x114) + 0x40) - 0x121C; } else { raceraddress = memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(0x004C67BC) + 0x60) + 0xA8) + 0x110 + (int)driverNumber * 4) + 0x40) - 0x3e8; } int ecx = memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(memoryManager.ReadInt(0x004C67BC) + 0x60) + 0xA8) + 0x114) + 0x40) - 0x121C + 0x8); int ebx = 0; int edx = 0; switch (driverNumber) { case 0: // Local player ebx = ecx - 0x498; edx = ecx - 0x444; break; case 1: // Opponent 1 edx = 0xD1; break; case 2: // Opponent 2 edx = 0xA4; break; case 3: // Opponent 3 edx = 0xBA; break; case 4: // Opponent 4 edx = 0x49; break; case 5: // Opponent 5 edx = 0x8D; break; default: return; } List <byte> codeToInject = new List <byte>(); codeToInject.Add(0xBB); codeToInject.AddRange(BitConverter.GetBytes(ebx)); // mov ebx,neededEBX codeToInject.Add(0xB9); codeToInject.AddRange(BitConverter.GetBytes(ecx)); // mov ecx,neededECX codeToInject.Add(0xBA); codeToInject.AddRange(BitConverter.GetBytes(edx)); // mov edx,neededEDX codeToInject.Add(0x6A); codeToInject.Add((byte)whiteBricks); // push whitebricks codeToInject.Add(0x68); codeToInject.AddRange(BitConverter.GetBytes(raceraddress)); // push raceraddress codeToInject.Add(0xE8); codeToInject.AddRange(BitConverter.GetBytes((int)(-(memoryManager.NewMemory + codeToInject.Count + 4) + function))); // call function codeToInject.Add(0xC3); // ret // Write code to the assigned memory and execute it memoryManager.WriteBytes((int)memoryManager.NewMemory, codeToInject.ToArray()); memoryManager.Execute(memoryManager.NewMemory); /*int raceraddress; * * int ecx = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, ENEMY_1_BASE_OFFSETS) + 0x8); * int ebx = 0; * int edx = 0; * * switch (driverNumber) * { * case 0: // Player * raceraddress = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, PLAYER_BASE_OFFSETS)); * ebx = ecx - 0x498; * edx = ecx - 0x444; * break; * case 1: // AI 1 * raceraddress = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, ENEMY_1_BASE_OFFSETS)); * edx = 0xD1; * break; * case 2: // AI 2 * raceraddress = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, ENEMY_2_BASE_OFFSETS)); * edx = 0xA4; * break; * case 3: // AI 3 * raceraddress = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, ENEMY_3_BASE_OFFSETS)); * edx = 0xBA; * break; * case 4: // AI 4 * raceraddress = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, ENEMY_4_BASE_OFFSETS)); * edx = 0x49; * break; * case 5: // AI 5 * raceraddress = memoryManager.ReadInt(memoryManager.CalculatePointer(DRIVER_BASE, ENEMY_5_BASE_OFFSETS)); * edx = 0x8D; * break; * } * * List<byte> codeToInject = new List<byte>(); * * codeToInject.Add(0xBB); * codeToInject.AddRange(BitConverter.GetBytes(ebx)); // mov ebx,neededEBX * codeToInject.Add(0xB9); * codeToInject.AddRange(BitConverter.GetBytes(ecx)); // mov ecx,neededECX * codeToInject.Add(0xBA); * codeToInject.AddRange(BitConverter.GetBytes(edx)); // mov edx,neededEDX * codeToInject.Add(0x6A); * codeToInject.Add((byte)whiteBricks); // push whitebricks * codeToInject.Add(0x68); * codeToInject.AddRange(BitConverter.GetBytes(raceraddress)); // push raceraddress * codeToInject.Add(0xE8); * codeToInject.AddRange(BitConverter.GetBytes(function - (int)(MemoryManager.NewMemory + codeToInject.Count + 4))); // call function * codeToInject.Add(0xC3); // ret * memoryManager.WriteBytes((int)memoryManager.NewMemory, codeToInject.ToArray()); * memoryManager.Execute(MemoryManager.NewMemory);*/ } }
/// <summary> /// Uses a Power-up from the driver. This does not trigger the PowerUpUsed event. /// </summary> /// <param name="brick">The Brick type to use.</param> /// <param name="whiteBricks">Amount of White bricks to use.</param> public void UsePowerUp(Brick brick, int whiteBricks) { if (driverIndex >= 0 && driverIndex <= 5 && brick != Brick.White && brick != Brick.None) { UInt32 function = 0; switch (brick) { case Brick.Red: // Red Power-up function = gameClient.POWERUP_RED_ADDRESS; break; case Brick.Blue: // Blue Power-up function = gameClient.POWERUP_RED_ADDRESS; break; case Brick.Green: // Green Power-up function = gameClient.POWERUP_GREEN_ADDRESS; break; case Brick.Yellow: // Yellow Power-up function = gameClient.POWERUP_YELLOW_ADDRESS; break; default: return; } uint ecx = MemoryManager.ReadUInt(baseAddress + 0x8); uint ebx = 0; uint edx = 0; switch (driverIndex) { case 0: // Local player ebx = ecx - 0x498; edx = ecx - 0x444; break; case 1: // Opponent 1 edx = 0xD1; break; case 2: // Opponent 2 edx = 0xA4; break; case 3: // Opponent 3 edx = 0xBA; break; case 4: // Opponent 4 edx = 0x49; break; case 5: // Opponent 5 edx = 0x8D; break; default: return; } List <byte> codeToInject = new List <byte>(); codeToInject.Add(0xBB); codeToInject.AddRange(BitConverter.GetBytes(ebx)); // mov ebx,neededEBX codeToInject.Add(0xB9); codeToInject.AddRange(BitConverter.GetBytes(ecx)); // mov ecx,neededECX codeToInject.Add(0xBA); codeToInject.AddRange(BitConverter.GetBytes(edx)); // mov edx,neededEDX codeToInject.Add(0x6A); codeToInject.Add((byte)whiteBricks); // push whitebricks codeToInject.Add(0x68); codeToInject.AddRange(BitConverter.GetBytes(baseAddress)); // push raceraddress codeToInject.Add(0xE8); codeToInject.AddRange(BitConverter.GetBytes((int)(-(MemoryManager.NewMemory + codeToInject.Count + 4) + function))); // call function codeToInject.Add(0xC3); // ret // Write code to the assigned memory and execute it MemoryManager.WriteBytes(MemoryManager.NewMemory, codeToInject.ToArray()); MemoryManager.CreateThread(MemoryManager.NewMemory); } }