Skip to content

Assembly injection #93

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

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Conversation

limoka
Copy link
Contributor

@limoka limoka commented May 29, 2023

This PR allows users classes to be injected into assembly with the same name as their mod assembly, instead of InjectedMonoTypes.
There are two benefits from this:

  1. Users can declare their assemblies in Unity Editor using asmdefs or use custom precompiled assemblies
  2. Because types exist in the correct assembly according to il2cpp runtime, any code which checks assembly will work correctly. For example Burst runtime checks assembly name, so with this change adding custom Bursted code becomes possible.

The changes are backwards compatible. Despite the classes now being defined in the mod assembly, they will still correctly deserialize because we inject classes into every assembly that exists.

To implement this I had to determine a list of possible assemblies very early, so plugins folder scanning is performed.
Also I needed to modify contents of ScriptingAssemblies.json file in the game Data folder, because Unity seems to get a list of assemblies from there. A backup of original is created.

I have implemented IAT hooking, so no files are modified now.
Assembly scanning now should be performed by mod loader by adding AssemblyInjectorComponent.

I have tested these changes on Core Keeper Unity 2021.3.14.

@ds5678
Copy link
Collaborator

ds5678 commented Dec 13, 2024

@limoka can you rebase?

@limoka limoka force-pushed the assembly-injection branch from 562a0ed to af8fb61 Compare January 16, 2025 18:42
@limoka
Copy link
Contributor Author

limoka commented Jan 16, 2025

@ds5678 rebased as you asked. Sorry it took a while, I was busy with IRL things.

As far as I remember this one is blocked by lack of Linux support. Unfortunately I don't actually use Linux, and don't have enough knowledge about it to make these changes work there.

I also included a commit I made, but never pushed. It should make this code work on Unity 2019.

@ds5678
Copy link
Collaborator

ds5678 commented Jan 16, 2025

I'm hesitant to dedicate time towards reviewing this if it does not support all platforms.

Copy link
Collaborator

@ds5678 ds5678 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a brief look over your changes.

// ReSharper disable BuiltInTypeReferenceStyle


namespace Il2CppInterop.Common
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't read over this file too closely, but a lot of it looks very similar to the AsmResolver code.

@@ -9,6 +9,7 @@
using System.Text.RegularExpressions;
using Il2CppInterop.Common;
using Il2CppInterop.Common.Attributes;
using Il2CppInterop.Runtime.Injection;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an unnecessary using.


public bool IsTargetFile(string originalFilePath)
{
return originalFilePath.Contains("globalgamemanagers");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

globalgamemanagers doesn't always exist.

return newFile;
}

private void CreateModifiedFile()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am strongly against a solution that requires modifying game files.

Copy link
Contributor Author

@limoka limoka Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if we don't actually touch original files? This PR uses hooks at runtime to provide files when the game requests them. Nothing is modified on disk.

Also sadly the only other solution would be patching native Unity code (not lib il2cpp), and according to author of FixPluginSerialization (mono version of this kind of solution), it's an awful idea: https://discord.com/channels/623153565053222947/985596870229385256/1113056578485092382

@ds5678
Copy link
Collaborator

ds5678 commented Feb 14, 2025

Why can't this be fixed by patching one or more of these?

DO_API(Il2CppDomain*, il2cpp_domain_get, ());
DO_API(const Il2CppAssembly*, il2cpp_domain_assembly_open, (Il2CppDomain * domain, const char* name));
DO_API(const Il2CppAssembly**, il2cpp_domain_get_assemblies, (const Il2CppDomain * domain, size_t * size));

@limoka
Copy link
Contributor Author

limoka commented Feb 14, 2025

@ds5678 I don't remember full details, but the reason is: they aren't connected to the root cause of the issue. They merely mirror what native Unity side knows.

And Native Unity code makes an assembly list some time really early, by reading one of the files I edit. Then whenever someone asks for assembly by name, it uses that list.

Because the aim of this is to allow scripts in other assemblies for serialization purposes, the code that asks also lives on native side. As such patching methods you mentioned won't do anything.

@ds5678
Copy link
Collaborator

ds5678 commented Feb 14, 2025

So then what are these exposed api used for?

@limoka
Copy link
Contributor Author

limoka commented Feb 14, 2025

In fact this is an issue that plagues all kinds of Unity modding: Assemblies added by mods never properly work for serialization purposes

Related project: https://github.com/xiaoxiao921/FixPluginTypesSerialization

@limoka
Copy link
Contributor Author

limoka commented Feb 14, 2025

So then what are these exposed api used for?

Unfortunately I don't remember, and can't answer right now. All I remember is that patching them does nothing to fix this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants