/// <summary> /// Invoke this hook with a certain parameter registry. /// </summary> /// <param name="registry">The registry containing the required values for this hook's execution.</param> /// <param name="resolver">A helper resolver for complex registry entries (automatically cached).</param> public override void SubInvoke(IRegistry registry, IRegistryResolver resolver) { string registryEntry = ParameterRegistry.Get <string>("registry_entry"); string resultEntry = ParameterRegistry.Get <string>("shared_result_entry"); double value = resolver.ResolveGetSingle <double>(registryEntry); double previousAccumulatedValue = ParameterRegistry.Get <double>("accumulated_value"); int currentInterval = HookUtils.GetCurrentInterval(registry, TimeStep.TimeScale); int resetInterval = ParameterRegistry.Get <int>("reset_interval"); int resetEvery = ParameterRegistry.Get <int>("reset_every"); int countSinceReset = ParameterRegistry.Get <int>("count_since_reset"); if (currentInterval == resetInterval || resetEvery > 0 && currentInterval % resetEvery == 0) { previousAccumulatedValue = 0.0; countSinceReset = 0; } countSinceReset++; double result = value + previousAccumulatedValue; if (ParameterRegistry.Get <bool>("average_mode")) { result /= countSinceReset; } ParameterRegistry["count_since_reset"] = countSinceReset; ParameterRegistry["accumulated_value"] = value + previousAccumulatedValue; resolver.ResolveSet(resultEntry, result, addIdentifierIfNotExists: true); }
protected void RestoreHeader() { HookUtils.FlushICache(_pTarget, _targetHeaderBackup.Length); fixed(void *ptr = _targetHeaderBackup) HookUtils.MemCpy(_pTarget, ptr, _targetHeaderBackup.Length); }
public void InvokeTimeScaleEvent(TimeScale timeScale) { lock (_bufferHooksToInvoke) // the lock is only needed as a safeguard against lifecycle invokes, but as it's just a marginal overhead it's better than colliding with another invoke { Operator.EjectTimeScaleEvent(timeScale, Operator.AttachedLocalHooksByTimeScale, LocalLocalHookTimeSteps, _bufferHooksToInvoke); IRegistry bufferRegistry = GetPopulatedBufferRegistry(); ArrayUtils.SortListInPlaceIndexed(_bufferHooksToInvoke, Operator.GetLocalHookInvocationIndex); HookUtils.FetchOrderedBackgroundHooks(_bufferHooksToInvoke, _bufferHooksToInvokeInBackground); foreach (IHook hook in _bufferHooksToInvoke) { if (!hook.InvokeInBackground) { hook.Operator = Operator; hook.Invoke(bufferRegistry, _bufferRegistryResolver); } } if (_bufferHooksToInvokeInBackground.Count > 0) { Operator.DispatchBackgroundHookInvocation(_bufferHooksToInvokeInBackground, bufferRegistry, _bufferRegistryEntries, _bufferResolvedRegistryEntries); } MarkDeadHooks(Operator.AttachedLocalHooks, LocalLocalHookTimeSteps); } }
internal static void DoHook() { o_OnUpdate = HookUtils.HookCall <OnUpdate>(0xA70090, Main.OnUpdate); o_Exit = HookUtils.HookCall <Exit>(0xE79BF0, Main.Exit); o_CompleteTask = HookUtils.HookCall <CompleteTask>(0x88AB50, Main.CompleteTask); o_CallMeeting = HookUtils.HookCall <CallMeeting>(0x8DF240, Main.CallMeeting); o_EndMeeting = HookUtils.HookCall <EndMeeting>(0xE1B490, Main.EndMeeting); o_StartGame = HookUtils.HookCall <StartGame>(0xD59E40, Main.StartGame); // is called when game starts and when meeting starts }
private void EnableAddrModifiable() { if (!LDasm.IsIL2CPP()) { return; } HookUtils.SetAddrFlagsToRWE(new IntPtr(_pTarget), _targetHeaderBackup.Length); HookUtils.SetAddrFlagsToRWE(new IntPtr(_pProxy), _targetHeaderBackup.Length + _jmpCodeSize); }
protected void PatchProxyMethod() { HookUtils.FlushICache(_pProxy, _targetHeaderBackup.Length * 2); // copy target's code to proxy fixed(byte *ptr = _targetHeaderBackup) HookUtils.MemCpy(_pProxy, ptr, _targetHeaderBackup.Length); // jmp to target's new position long jmpFrom = (long)_pProxy + _targetHeaderBackup.Length; long jmpTo = (long)_pTarget + _targetHeaderBackup.Length; FlushJmpCode((void *)jmpFrom, (void *)jmpTo); }
protected void BackupHeader() { if (_targetHeaderBackup != null) { return; } uint requireSize = LDasm.SizeofMinNumByte(_pTarget, _jmpCodeSize); _targetHeaderBackup = new byte[requireSize]; fixed(void *ptr = _targetHeaderBackup) HookUtils.MemCpy(ptr, _pTarget, _targetHeaderBackup.Length); }
protected void PatchTargetMethod() { HookUtils.FlushICache(_pTarget, _targetHeaderBackup.Length); FlushJmpCode(_pTarget, _pReplace); }
static void HookUtilsMessage() { HookUtils.ToMessage(); }
private void DoInstall() { HookPool.AddHook(_targetMethod, this); if (_codePatcher == null) { if (GetFunctionAddr()) { #if ENABLE_HOOK_DEBUG UnityEngine.Debug.Log($"Original [{_targetMethod.DeclaringType.Name}.{_targetMethod.Name}]: {HookUtils.HexToString(_targetPtr.ToPointer(), 64, -16)}"); UnityEngine.Debug.Log($"Original [{_replacementMethod.DeclaringType.Name}.{_replacementMethod.Name}]: {HookUtils.HexToString(_replacementPtr.ToPointer(), 64, -16)}"); UnityEngine.Debug.Log($"Original [{_proxyMethod.DeclaringType.Name}.{_proxyMethod.Name}]: {HookUtils.HexToString(_proxyPtr.ToPointer(), 64, -16)}"); #endif CreateCodePatcher(); _codePatcher.ApplyPatch(); #if ENABLE_HOOK_DEBUG UnityEngine.Debug.Log($"New [{_targetMethod.DeclaringType.Name}.{_targetMethod.Name}]: {HookUtils.HexToString(_targetPtr.ToPointer(), 64, -16)}"); UnityEngine.Debug.Log($"New [{_replacementMethod.DeclaringType.Name}.{_replacementMethod.Name}]: {HookUtils.HexToString(_replacementPtr.ToPointer(), 64, -16)}"); UnityEngine.Debug.Log($"New [{_proxyMethod.DeclaringType.Name}.{_proxyMethod.Name}]: {HookUtils.HexToString(_proxyPtr.ToPointer(), 64, -16)}"); #endif } } isHooked = true; }