IL2CPPChainloader.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Runtime.InteropServices;
  6. using BepInEx.Bootstrap;
  7. using BepInEx.Logging;
  8. using BepInEx.Preloader.Core;
  9. using BepInEx.Preloader.Core.Logging;
  10. using MonoMod.RuntimeDetour;
  11. using MonoMod.Utils;
  12. using UnhollowerBaseLib.Runtime;
  13. using UnhollowerRuntimeLib;
  14. using UnityEngine;
  15. using Logger = BepInEx.Logging.Logger;
  16. namespace BepInEx.IL2CPP
  17. {
  18. public class IL2CPPChainloader : BaseChainloader<BasePlugin>
  19. {
  20. private static ManualLogSource UnityLogSource = new ManualLogSource("Unity");
  21. [UnmanagedFunctionPointer(CallingConvention.StdCall)]
  22. private delegate void UnityLogCallbackDelegate([In] [MarshalAs(UnmanagedType.LPStr)] string log);
  23. private static void UnityLogCallback([In] [MarshalAs(UnmanagedType.LPStr)] string log)
  24. {
  25. UnityLogSource.LogInfo(log.Trim());
  26. }
  27. [UnmanagedFunctionPointer(CallingConvention.StdCall)]
  28. private delegate IntPtr RuntimeInvokeDetour(IntPtr method, IntPtr obj, IntPtr parameters, IntPtr exc);
  29. public unsafe IL2CPPChainloader()
  30. {
  31. ClassInjector.DoHook = (ptr, intPtr) =>
  32. {
  33. var detour = new NativeDetour(new IntPtr(*((int**)ptr)), intPtr);
  34. detour.Apply();
  35. };
  36. var gameAssemblyModule = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().First(x => x.FileName.Contains("GameAssembly"));
  37. var functionPtr = DynDll.GetFunction(gameAssemblyModule.BaseAddress, "il2cpp_runtime_invoke");
  38. RuntimeInvokeDetour originalInvoke = null;
  39. RuntimeInvokeDetour invokeHook = (method, obj, parameters, exc) =>
  40. {
  41. UnityLogSource.LogInfo(Marshal.PtrToStringAnsi(UnhollowerBaseLib.IL2CPP.il2cpp_method_get_name(method)));
  42. return originalInvoke(method, obj, parameters, exc);
  43. };
  44. var invokeDetour = new NativeDetour(functionPtr, Marshal.GetFunctionPointerForDelegate(invokeHook), new NativeDetourConfig {ManualApply = true});
  45. originalInvoke = invokeDetour.GenerateTrampoline<RuntimeInvokeDetour>();
  46. invokeDetour.Apply();
  47. //UnityVersionHandler.Initialize(2019, 3, 15);
  48. }
  49. protected override void InitializeLoggers()
  50. {
  51. //Logger.Listeners.Add(new UnityLogListener());
  52. //if (ConfigUnityLogging.Value)
  53. // Logger.Sources.Add(new UnityLogSource());
  54. Logger.Sources.Add(UnityLogSource);
  55. ManualLogSource unhollowerLogSource = Logger.CreateLogSource("Unhollower");
  56. UnhollowerBaseLib.LogSupport.InfoHandler += s => unhollowerLogSource.LogInfo(s);
  57. UnhollowerBaseLib.LogSupport.WarningHandler += s => unhollowerLogSource.LogWarning(s);
  58. UnhollowerBaseLib.LogSupport.TraceHandler += s => unhollowerLogSource.LogDebug(s);
  59. UnhollowerBaseLib.LogSupport.ErrorHandler += s => unhollowerLogSource.LogError(s);
  60. base.InitializeLoggers();
  61. //if (!ConfigDiskWriteUnityLog.Value)
  62. //{
  63. // DiskLogListener.BlacklistedSources.Add("Unity Log");
  64. //}
  65. foreach (var preloaderLogEvent in PreloaderConsoleListener.LogEvents)
  66. {
  67. PreloaderLogger.Log.Log(preloaderLogEvent.Level, preloaderLogEvent.Data);
  68. }
  69. //UnityEngine.Application.s_LogCallbackHandler = DelegateSupport.ConvertDelegate<Application.LogCallback>(new Action<string>(UnityLogCallback));
  70. //UnityEngine.Application.s_LogCallbackHandler = (Application.LogCallback)new Action<string>(UnityLogCallback);
  71. var loggerPointer = Marshal.GetFunctionPointerForDelegate(new UnityLogCallbackDelegate(UnityLogCallback));
  72. UnhollowerBaseLib.IL2CPP.il2cpp_register_log_callback(loggerPointer);
  73. }
  74. public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly)
  75. {
  76. var type = pluginAssembly.GetType(pluginInfo.TypeName);
  77. var pluginInstance = (BasePlugin)Activator.CreateInstance(type);
  78. pluginInstance.Load();
  79. return pluginInstance;
  80. }
  81. }
  82. }