Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ubisoft+ IL2CPP Support. They bundle two different EXE/GameAssembly files for retail and subscription versions. #114

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion Il2CppInterop.Common/XrefScans/XrefScanMethodDb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static XrefScanMethodDb()
XrefScanCache = new MethodXrefScanCache(GeneratedDatabasesUtil.GetDatabasePath(MethodXrefScanCache.FileName));

foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
if (module.ModuleName == "GameAssembly.dll")
if (module.ModuleName is "GameAssembly.dll" or "GameAssembly_plus.dll")
{
GameAssemblyBase = (long)module.BaseAddress;
break;
Expand Down
35 changes: 27 additions & 8 deletions Il2CppInterop.Runtime/Injection/InjectorHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,43 @@
using System.Runtime.InteropServices;
using System.Threading;
using Il2CppInterop.Common;
using Il2CppInterop.Common.Extensions;
using Il2CppInterop.Common.XrefScans;
using Il2CppInterop.Runtime.Injection.Hooks;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Assembly;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.FieldInfo;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Image;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo;
using Il2CppInterop.Runtime.Startup;
using Microsoft.Extensions.Logging;

namespace Il2CppInterop.Runtime.Injection
{
internal static unsafe class InjectorHelpers
{
private static readonly string[] s_assemblies =
{
"GameAssembly.dll",
"GameAssembly_plus.dll",
"GameAssembly.so",
"GameAssembly_plus.so",
"UserAssembly.dll",
"UserAssembly_plus.dll"
};

internal static Assembly Il2CppMscorlib = typeof(Il2CppSystem.Type).Assembly;
internal static INativeAssemblyStruct InjectedAssembly;
internal static INativeImageStruct InjectedImage;

internal static ProcessModule Il2CppModule = Process.GetCurrentProcess()
.Modules.OfType<ProcessModule>()
.Single((x) => x.ModuleName is "GameAssembly.dll" or "GameAssembly.so" or "UserAssembly.dll");
.Single(x => s_assemblies.Contains(x.ModuleName, StringComparer.OrdinalIgnoreCase));

internal static IntPtr Il2CppHandle = NativeLibrary.Load("GameAssembly", typeof(InjectorHelpers).Assembly, null);
internal static IntPtr Il2CppHandle
{
get
{
var assembly = Il2CppModule.ModuleName != null && Il2CppModule.ModuleName.Contains("_plus") ? "GameAssembly_plus" : "GameAssembly";
return NativeLibrary.Load(assembly, typeof(InjectorHelpers).Assembly, null);
}
}

internal static readonly Dictionary<Type, OpCode> StIndOpcodes = new()
{
Expand All @@ -51,6 +64,7 @@ internal static unsafe class InjectorHelpers
private static void CreateInjectedAssembly()
{
InjectedAssembly = UnityVersionHandler.NewAssembly();

InjectedImage = UnityVersionHandler.NewImage();

InjectedAssembly.Name.Name = Marshal.StringToHGlobalAnsi("InjectedMonoTypes");
Expand Down Expand Up @@ -137,12 +151,15 @@ internal static IntPtr GetIl2CppMethodPointer(MethodBase proxyMethod)

private static long s_LastInjectedToken = -2;
internal static readonly ConcurrentDictionary<long, IntPtr> s_InjectedClasses = new();

/// <summary> (namespace, class, image) : class </summary>
internal static readonly Dictionary<(string _namespace, string _class, IntPtr imagePtr), IntPtr> s_ClassNameLookup = new();

#region Class::Init

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void d_ClassInit(Il2CppClass* klass);

internal static d_ClassInit ClassInit;

private static readonly MemoryUtils.SignatureDefinition[] s_ClassInitSignatures =
Expand All @@ -160,7 +177,6 @@ internal static IntPtr GetIl2CppMethodPointer(MethodBase proxyMethod)
xref = true
}
};

private static d_ClassInit FindClassInit()
{
static nint GetClassInitSubstitute()
Expand All @@ -184,6 +200,7 @@ static nint GetClassInitSubstitute()
Logger.Instance.LogTrace("GameAssembly.dll: 0x{Il2CppModuleAddress}", Il2CppModule.BaseAddress.ToInt64().ToString("X2"));
throw new NotSupportedException("Failed to use signature for Class::Init and a substitute cannot be found, please create an issue and report your unity version & game");
}

nint pClassInit = s_ClassInitSignatures
.Select(s => MemoryUtils.FindSignatureInModule(Il2CppModule, s))
.FirstOrDefault(p => p != 0);
Expand All @@ -198,6 +215,8 @@ static nint GetClassInitSubstitute()

return Marshal.GetDelegateForFunctionPointer<d_ClassInit>(pClassInit);
}

#endregion

}
}
Loading