public StageCollection(IModLoader loader) { _modLoader = loader; _logger = (ILogger)_modLoader.GetLogger(); _redirectorController = _modLoader.GetController <IRedirectorController>(); _initPathHook = Fun_InitializeSplines.Hook(InitSplineImpl).Activate(); _getEndPositionHook = Fun_GetEndPosition.Hook(GetEndPositionImpl).Activate(); _getBragPositionHook = Fun_GetIntroPosition.Hook(GetBragPositionImpl).Activate(); _getStartPositionHook = Fun_GetStartPosition.Hook(GetStartPositionImpl).Activate(); // Populate Default Stages foreach (var stageId in (Stage[])Enum.GetValues(typeof(Stage))) { // Rail Canyon for Chaotix var stage = stageId != Stage.RailCanyonChaotix ? new DefaultStage(stageId) : new DefaultStage(Stage.RailCanyon); _allStages.Add(stage); } // Temporary crash workaround for SET objects beyond default limits. var crashWorkaround = new[] { "use32", "mov edi, dword [esp + 0x58]", // Take pointer to object list from function parameters. "mov [0xA2CF70], dword edi" }; _setLimitCrashWorkaround = SDK.ReloadedHooks.CreateAsmHook(crashWorkaround, 0x43D1EA, AsmHookBehaviour.ExecuteFirst).Activate(); }
public void TestHookAddNoOriginal() { int wordSize = IntPtr.Size; string[] addFunction = { $"{Macros._use32}", $"push {Macros._ebp}", $"mov {Macros._ebp}, {Macros._esp}", $"mov {Macros._eax}, [{Macros._ebp} + {wordSize * 2}]", // Left Parameter $"mov {Macros._ecx}, [{Macros._ebp} + {wordSize * 3}]", // Right Parameter $"add {Macros._eax}, 1", // Left Parameter }; _addNoOriginalHook = ReloadedHooks.Instance.CreateAsmHook(addFunction, (long)_nativeCalculator.Add, AsmHookBehaviour.DoNotExecuteOriginal).Activate(); for (int x = 0; x < 100; x++) { for (int y = 1; y < 100;) { int expected = (x + y) + 1; int result = _addFunction(x, y); Assert.Equal(expected, result); y += 2; } } }
public RenderHooks(float aspectRatioLimit, IReloadedHooks hooks) { _memory = Memory.CurrentProcess; _aspectConverter = new AspectConverter(aspectRatioLimit); _draw2PViewPortHook = hooks.CreateHook <sub_422AF0>(Draw2PViewportHook, 0x422AF0).Activate(); _drawSpecialStageGaugeHook = hooks.CreateHook <sub_5263C0>(DrawSpecialStageGaugeImpl, 0x5263C0).Activate(); _drawSpecialStageBarHook = hooks.CreateHook <sub_526280>(DrawSpecialStageBarImpl, 0x526280, 0xD).Activate(); _draw2PStatusHook = hooks.CreateHook <sub_422A70>(Draw2pStatusImpl, 0x422A70).Activate(); _renderPrimitiveHook = hooks.CreateHook <_rwD3D8Im2DRenderPrimitive>(RenderPrimitiveImpl, 0x00662B00).Activate(); _renderVideoHook = hooks.CreateHook <sub_644450>(RenderVideoHookImpl, 0x644450).Activate(); _drawFullVideoFrameHook = hooks.CreateHook <DrawFullVideoFrame>(DrawFullVideoFrameHookImpl, 0x0042A100).Activate(); _drawSmallVideoFrameHook = hooks.CreateHook <DrawSmallFrame>(DrawSmallFrameImpl, 0x00429F80).Activate(); _drawTitlecardElementsHook = hooks.CreateHook <sub_442850>(DrawTitlecardElementsImpl, 0x442850).Activate(); _drawSpecialStageLinkHook = hooks.CreateHook <sub_526F60>(DrawSpecialStageLinkImpl, 0x526F60).Activate(); _getVertexBufferSubmission = hooks.CreateWrapper <sub_651E20>(0x651E20, out _); _drawNowLoadingHook = hooks.CreateHook <sub_44EAC0>(DrawNowLoadingImpl, 0x44EAC0).Activate(); _executeCreditsHook = hooks.CreateHook <sub_4545F0>(ExecuteCredits, 0x4545F0).Activate(); _drawResultScreenDotsHook = hooks.CreateHook <sub_438A90>(DrawResultScreenDotsImpl, 0x438A90).Activate(); _drawPowerupBoxHook = hooks.CreateHook <DrawPowerupBox>(DrawPowerupBoxImpl, 0x479AB0).Activate(); _drawEmeraldHookReverseWrap = hooks.CreateReverseWrapper <DrawEmeraldHook>(DrawSpecialStageEmeraldImpl); _addressOfHook = new Pinnable <IntPtr>(_drawEmeraldHookReverseWrap.WrapperPointer); _drawSpecialStageEmeraldIndicatorHook = hooks.CreateAsmHook(new[] { "use32", // Offset to first param (after execution of code) "push eax", // + 8 "push esi", // + 12 "push ecx", // + 16 "push edx", // + 20 /* Push address of stack parameters up stack. */ "lea edx, [esp + 32]", "lea ecx, [esp + 28]", "lea ebx, [esp + 24]", "lea eax, [esp + 20]", "push edx", "push ecx", "push ebx", "push eax", $"call dword [0x{(long)_addressOfHook.Pointer:X}]", "add esp, 16", "pop edx", "pop ecx", "pop esi", "pop eax" }, 0x458920).Activate(); _memory.ChangePermission((IntPtr)_descriptionX, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_descriptionY, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_descriptionWidth, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_descriptionHeight, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_pickupBoxSeparation, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_dotsVertSeparation, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_dotsHorzSeparation, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_dotsHeight, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); _memory.ChangePermission((IntPtr)_dotsWidth, sizeof(void *), Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); }
public GetRaceModeHook(IReloadedHooks hooks) { _hooks = hooks; var hook = new string[] { "use32", // Callee Register Backup $"mov [{(IntPtr)_pinnable.Pointer}], eax" }; _getRaceModeHook = hooks.CreateAsmHook(hook, 0x0046C116, AsmHookBehaviour.ExecuteAfter).Activate(); }
public DebugBoot(string modDirectory, string configDirectory, IReloadedHooks hooks) { // Setup Config _configurator = new Configurator(configDirectory); _configurator.Migrate(modDirectory, _configurator.ConfigFolder); _config = _configurator.GetConfiguration <Config.Config>(0); _config.ConfigurationUpdated += configurable => { _config = (Config.Config)configurable; ConfigToPinnable(_config); Console.WriteLine($"Debug Boot Configuration Updated. Set new main menu mode."); }; ConfigToPinnable(_config); // Apply Boot Time Constants *_stageId = _config.BootOptions.Stage; *_teamOne = _config.BootOptions.TeamP1; *_teamTwo = _config.BootOptions.TeamP2; *_teamThree = _config.BootOptions.TeamP3; *_teamFour = _config.BootOptions.TeamP4; // Setup mid function hooks. // Disasm name: Main::Loop string[] asmHookSetMainMenu = { $"use32", $"mov ecx, dword [{(IntPtr)_mainMenuSystemMode.Pointer}]", // New line, sacrificing ECX. $"mov [eax + 0x38], ecx", $"mov ecx, [esi]", $"mov [esi + 4], edi", }; string[] asmHookStartGame = { $"use32", $"mov [{(IntPtr)_ediBackup.Pointer}], edi", // Backup EDI $"mov edi, dword [{(IntPtr)_bootSystemMode.Pointer}]", // Replace EDI $"mov [0xA82034], ebp", $"mov [eax + 0x38], edi", // Set SystemMode $"mov edi, dword [{(IntPtr)_ediBackup.Pointer}]", // Restore EDI }; _loadMainMenuHook = hooks.CreateAsmHook(asmHookSetMainMenu, 0x427342, AsmHookBehaviour.DoNotExecuteOriginal).Activate(); _bootHook = hooks.CreateAsmHook(asmHookStartGame, 0x00427138, AsmHookBehaviour.DoNotExecuteOriginal).Activate(); }
public Mod(ILogger logger, IReloadedHooks hooks) { _logger = logger; _hooks = hooks; _process = Process.GetCurrentProcess(); using var scanner = new Scanner(_process, _process.MainModule); //var result = scanner.CompiledFindPattern("48 8B C4 53 41 56 41 57 48 83 EC 50"); var result = scanner.CompiledFindPattern("F6 40 08 04 0F 84 DF 01 00 00"); var injectLocation = result.Offset + (long)_process.MainModule.BaseAddress; //test byte ptr[rax + 08],04 //jne "Digimon Story CS.exe.unpacked.exe" + 00171ddb //cmp EDI, 0x14 //je "Digimon Story CS.exe.unpacked.exe" + 00171f3d //jmp "Digimon Story CS.exe.unpacked.exe" + 171D5E string[] asmCode = { //here we use ecx to hold the jump address temporarily $"use64", $"test byte [rax + 08],04", $"mov rcx, " + String.Format("0x{0:X8}", 0x00171ddb + (long)_process.MainModule.BaseAddress).ToString(), $"jne jumptorcx", $"cmp edi, 0x14", $"mov rcx, " + String.Format("0x{0:X8}", 0x00171f3d + (long)_process.MainModule.BaseAddress).ToString(), $"je jumptorcx", $"mov rcx, " + String.Format("0x{0:X8}", 0x171D5E + (long)_process.MainModule.BaseAddress).ToString(), $"jumptorcx:", $"jmp rcx" }; #if DEBUG _logger.WriteLine($"Inject Location Offset: {result.Offset:X}"); _logger.WriteLine($"Inject Location: {injectLocation:X}"); foreach (var asm in asmCode) { _logger.WriteLine(asm); } #endif _asmHook = _hooks.CreateAsmHook(asmCode, injectLocation, Reloaded.Hooks.Definitions.Enums.AsmHookBehaviour.DoNotExecuteOriginal); _asmHook.Activate(); }
private void InitXpHook() { long functionAddress = _utils.SigScan("55 ?? ?? 83 EC 08 53 56 57 ?? ?? 89 55 ?? B9 ?? ?? ?? ?? E8 ?? ?? ?? ??", "xp added"); if (functionAddress == -1) { return; } string[] function = { $"use32", // Not always necessary but good practice; // just in case the parent function doesn't preserve them. $"{_hooks.Utilities.PushCdeclCallerSavedRegisters()}", $"{_hooks.Utilities.GetAbsoluteCallMnemonics(XpAdded, out _reverseWrapper)}", $"{_hooks.Utilities.PopCdeclCallerSavedRegisters()}", }; _asmHook = _hooks.CreateAsmHook(function, functionAddress, AsmHookBehaviour.ExecuteFirst).Activate(); }
public void TestHookAddAfterOriginal() { string[] addFunction = { $"{Macros._use32}", $"add {Macros._eax}, 1", // Left Parameter - Should have already been copied from stack. }; _addAfterOriginalHook = ReloadedHooks.Instance.CreateAsmHook(addFunction, (long)_nativeCalculator.Add, AsmHookBehaviour.ExecuteAfter).Activate(); for (int x = 0; x < 100; x++) { for (int y = 1; y < 100;) { int expected = (x + y) + 1; int result = _addFunction(x, y); Assert.Equal(expected, result); y += 2; } } }
public void TestHookAddBeforeOriginal() { int wordSize = IntPtr.Size; string[] addFunction = { $"{Macros._use32}", $"add [{Macros._esp} + {wordSize * 1}], byte 1", // Left Parameter }; _addBeforeOriginalHook = ReloadedHooks.Instance.CreateAsmHook(addFunction, (long)_nativeCalculator.Add, AsmHookBehaviour.ExecuteFirst).Activate(); for (int x = 0; x < 100; x++) { for (int y = 1; y < 100;) { int expected = (x + y) + 1; int result = _addFunction(x, y); Assert.Equal(expected, result); y += 2; } } }