Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Commit

Permalink
Fix binary compatibility of ClassInjector
Browse files Browse the repository at this point in the history
  • Loading branch information
knah committed Oct 26, 2021
1 parent 169163d commit 3b7a542
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion AssemblyUnhollower/AssemblyUnhollower.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFrameworks>net4.7.2;net5.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
<Version>0.4.16.0</Version>
<Version>0.4.16.1</Version>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Limitations:
## Implementing interfaces with injected types
Starting with 0.4.16.0, injected types can implement IL2CPP interfaces.
Just like previously, your type can't implement the interface directly, as it's still generated as a class.
However, you can pass additional interface types to `RegisterTypeInIl2Cpp`, and they will be implemented as interfaces on the IL2CPP version of your type.
However, you can pass additional interface types to `RegisterTypeInIl2CppWithInterfaces`, and they will be implemented as interfaces on the IL2CPP version of your type.
Interface methods are matched to methods in your class by name, parameter count and genericness.
Known caveats:
* `obj.Cast<InterfaceType>()` will fail if you try to cast an object of your injected type to an interface. You can work around that with `new InterfaceType(obj.Pointer)` if you're absolutely sure it implements that interface.
Expand Down
1 change: 1 addition & 0 deletions ReleaseChangelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ Changes:
* Xref scanner now considers CMOVcc opcodes for string references
* Fixed deobfuscation map generator failing to run (it still generates bad maps for deobfuscated types though - some postprocessing is required)
* Fixed newer Unity versions failing due to wrong native struct description
* 0.4.16.1 - fixed binary compatibility of ClassInjector API (at the cost of breaking binary compatibility with 0.4.16.0)

22 changes: 17 additions & 5 deletions UnhollowerBaseLib/ClassInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,23 @@ public static void AssignGcHandle(IntPtr pointer, GCHandle gcHandle)
*(IntPtr*)targetGcHandlePointer = handleAsPointer;
}

public static void RegisterTypeInIl2Cpp<T>() where T : class => RegisterTypeInIl2Cpp(typeof(T), true);
public static void RegisterTypeInIl2Cpp<T>(params INativeClassStruct[] interfaces) where T : class => RegisterTypeInIl2Cpp(typeof(T), true, interfaces);
public static void RegisterTypeInIl2Cpp<T>(bool logSuccess, params INativeClassStruct[] interfaces) where T : class => RegisterTypeInIl2Cpp(typeof(T), logSuccess, interfaces);
public static void RegisterTypeInIl2Cpp(Type type, params INativeClassStruct[] interfaces) => RegisterTypeInIl2Cpp(type, true, interfaces);
public static void RegisterTypeInIl2Cpp(Type type, bool logSuccess, params INativeClassStruct[] interfaces)
public static void RegisterTypeInIl2Cpp<T>() where T : class => RegisterTypeInIl2CppImpl(typeof(T), true, Array.Empty<INativeClassStruct>());
public static void RegisterTypeInIl2Cpp<T>(bool logSuccess) where T : class => RegisterTypeInIl2CppImpl(typeof(T), logSuccess, Array.Empty<INativeClassStruct>());
public static void RegisterTypeInIl2Cpp(Type type, bool logSuccess) => RegisterTypeInIl2CppImpl(type, logSuccess, Array.Empty<INativeClassStruct>());
public static void RegisterTypeInIl2CppWithInterfaces<T>(params Type[] interfaces) where T : class => RegisterTypeInIl2CppWithInterfaces(typeof(T), true, interfaces);
public static void RegisterTypeInIl2CppWithInterfaces<T>(bool logSuccess, params Type[] interfaces) where T : class => RegisterTypeInIl2CppWithInterfaces(typeof(T), logSuccess, interfaces);
public static void RegisterTypeInIl2CppWithInterfaces(Type type, bool logSuccess, params Type[] interfaces)
{
RegisterTypeInIl2CppImpl(type, logSuccess, interfaces.Select(it =>
{
var classPointer = ReadClassPointerForType(it);
if (classPointer == IntPtr.Zero)
throw new ArgumentException($"Type {it} doesn't have an IL2CPP class pointer, which means it's not an IL2CPP interface");
return UnityVersionHandler.Wrap((Il2CppClass*)classPointer);
}).ToArray());
}

public static void RegisterTypeInIl2CppImpl(Type type, bool logSuccess, params INativeClassStruct[] interfaces)
{
if(type == null)
throw new ArgumentException($"Type argument cannot be null");
Expand Down
2 changes: 1 addition & 1 deletion UnhollowerBaseLib/UnhollowerBaseLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFrameworks>net4.7.2;netstandard2.1</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<Version>0.4.16.0</Version>
<Version>0.4.16.1</Version>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 3b7a542

Please sign in to comment.