Skip to content

Commit

Permalink
General Cleanup, Added Logging to Il2CppICallInjector
Browse files Browse the repository at this point in the history
  • Loading branch information
HerpDerpinstine committed Sep 15, 2024
1 parent 4e1ae3f commit ebf109a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
4 changes: 2 additions & 2 deletions MelonLoader/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ internal static int Initialize()

#if NET6_0_OR_GREATER
Fixes.Il2CppInteropFixes.Install();
Fixes.InjectedInternalCalls.Install();
Fixes.Il2CppICallInjector.Install();
#endif

PatchShield.Install();
Expand Down Expand Up @@ -191,7 +191,7 @@ internal static void Quit()

#if NET6_0_OR_GREATER
Fixes.Il2CppInteropFixes.Shutdown();
Fixes.InjectedInternalCalls.Shutdown();
Fixes.Il2CppICallInjector.Shutdown();
#endif

MelonLogger.Flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@

namespace MelonLoader.Fixes
{
internal static class InjectedInternalCalls
internal static class Il2CppICallInjector
{
private const string _unityInjectedSuffix = "_Injected";
private const string _customICallSuffix = "_INative";

private static Dictionary<string, (DynamicMethodDefinition, MethodInfo, IntPtr)> _lookup = new();

private delegate IntPtr dil2cpp_resolve_icall(IntPtr signature);
private static NativeHook<dil2cpp_resolve_icall> il2cpp_resolve_icall_hook;

private delegate void dil2cpp_add_internal_call(IntPtr signature, IntPtr funcPtr);
private static dil2cpp_add_internal_call il2cpp_add_internal_call;

private static Type _stringType;
private static Type _intPtrType;
private static Type _exceptionType;
Expand All @@ -35,10 +37,15 @@ internal static class InjectedInternalCalls
private static MethodInfo _il2CppPtrToString;
private static MethodInfo _il2CppObjectBaseGetPointer;

private static MelonLogger.Instance _logger;

internal static unsafe void Install()
{
try
{
_logger = new MelonLogger.Instance(nameof(Il2CppICallInjector));

Type thisType = typeof(Il2CppICallInjector);
Type objectType = typeof(object);
Type il2cppType = typeof(IL2CPP);
Type melonLoggerType = typeof(MelonLogger);
Expand All @@ -60,8 +67,8 @@ internal static unsafe void Install()
if (_stringToIl2CppPtr == null)
throw new Exception("Failed to get IL2CPP.ManagedStringToIl2Cpp");

_melonLoggerError = melonLoggerType.GetMethod(nameof(MelonLogger.Error),
BindingFlags.Static | BindingFlags.Public,
_melonLoggerError = thisType.GetMethod(nameof(LogError),
BindingFlags.Static | BindingFlags.NonPublic,
[_stringType]);
if (_melonLoggerError == null)
throw new Exception("Failed to get MelonLogger.Error");
Expand All @@ -84,14 +91,18 @@ internal static unsafe void Install()
if (il2cpp_resolve_icall == IntPtr.Zero)
throw new Exception($"Failed to get {nameof(il2cpp_resolve_icall)} Native Export");

il2cpp_add_internal_call = gameAssemblyLib.GetExport<dil2cpp_add_internal_call>(nameof(il2cpp_add_internal_call));
if (il2cpp_add_internal_call == null)
throw new Exception($"Failed to get {nameof(il2cpp_add_internal_call)} Native Export");

MelonDebug.Msg("Patching il2cpp_resolve_icall...");
IntPtr detourPtr = Marshal.GetFunctionPointerForDelegate((dil2cpp_resolve_icall)il2cpp_resolve_icall_Detour);
il2cpp_resolve_icall_hook = new NativeHook<dil2cpp_resolve_icall>(il2cpp_resolve_icall, detourPtr);
il2cpp_resolve_icall_hook.Attach();
}
catch (Exception e)
{
MelonLogger.Error(e);
LogError(e.ToString());
}
}

Expand All @@ -112,6 +123,9 @@ internal static void Shutdown()
}
}

private static void LogError(string msg)
=> _logger.Error(msg);

private static IntPtr il2cpp_resolve_icall_Detour(IntPtr signature)
{
// Convert Pointer to String
Expand All @@ -136,21 +150,22 @@ private static IntPtr il2cpp_resolve_icall_Detour(IntPtr signature)
if (!ShouldInject(signatureStr, out MethodInfo unityShimMethod))
return IntPtr.Zero;

// Create Injected Function
var pair = _lookup[signatureStr] = GenerateTrampoline(unityShimMethod);
// Create Injected Function and Cache Return
var pair =
_lookup[signatureStr] = GenerateTrampoline(unityShimMethod);

// Add New ICall to Il2Cpp Domain
il2cpp_add_internal_call(signature, pair.Item3);
_logger.Msg($"Registered mono icall {signatureStr} in il2cpp domain");

// Return New Function Pointer
return pair.Item3;
}

private static bool ShouldInject(string signature, out MethodInfo unityShimMethod)
{
unityShimMethod = null;

// Check if the Unity Injected Shim ICall Exists
IntPtr unityInjectedShimResult = il2cpp_resolve_icall_hook.Trampoline(
Marshal.StringToHGlobalAnsi($"{signature}{_unityInjectedSuffix}"));
if (unityInjectedShimResult == IntPtr.Zero)
return false;

// Split the Signature
string[] split = signature.Split("::");
string typeName = split[0];
Expand Down

0 comments on commit ebf109a

Please sign in to comment.