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

Throw ExecutionEngineException When the assembly path have double byte characters #431

Closed
magicskysword opened this issue Oct 16, 2021 · 5 comments
Assignees

Comments

@magicskysword
Copy link

Describe the bug
When I using BepinEx and Harmony to patch a method,it throw ExecutionEngineException: String conversion error: Illegal byte sequence encounted in the input.

To Reproduce
Steps to reproduce the behavior:

  1. The original method and its signature and class
Unity.Resources.Load(string path,Type systemTypeInstance);
  1. The patch code
[HarmonyPatch(typeof(Resources), "Load", new Type[] {typeof(string),typeof(Type)})]
public class ResourcesPatch
{
    [HarmonyPrefix]
    public static bool FixMethod(string path,Type systemTypeInstance,ref Object __result)
    {
        Main.LogInfo($"LoadAsset:<{systemTypeInstance}>({path}");
        if (Main.Instance.resourcesManager.TryGetAsset(path, systemTypeInstance, out var asset))
        {
            __result = asset;
            return true;
        }
        return false;
    }
}
  1. The output of the Harmony debug log
[Error  : Unity Log] ExecutionEngineException: String conversion error: Illegal byte sequence encounted in the input.
Stack trace:
System.Reflection.Assembly.GetCodeBase (System.Boolean escaped) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
(wrapper dynamic-method) System.Reflection.Assembly.DMD<System.Reflection.Assembly::get_CodeBase>(System.Reflection.Assembly)
System.Reflection.AssemblyName.Create (System.Reflection.Assembly assembly, System.Boolean fillCodebase) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
System.Reflection.RuntimeAssembly.GetName (System.Boolean copiedName) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
System.Reflection.Assembly.GetName () (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
UnityExplorer.ReflectionUtility.AssemblyLoaded (System.Object sender, System.AssemblyLoadEventArgs args) (at <7882e8efd4414f4ba2006db80ff80442>:0)
System.AppDomain.DoAssemblyLoad (System.Reflection.Assembly assembly) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
System.AppDomain.Load (System.Byte[] rawAssembly, System.Byte[] rawSymbolStore, System.Security.Policy.Evidence securityEvidence, System.Boolean refonly) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
System.AppDomain.Load (System.Byte[] rawAssembly, System.Byte[] rawSymbolStore, System.Security.Policy.Evidence securityEvidence) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
(wrapper remoting-invoke-with-check) System.AppDomain.Load(byte[],byte[],System.Security.Policy.Evidence)
System.AppDomain.Load (System.Byte[] rawAssembly) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
(wrapper remoting-invoke-with-check) System.AppDomain.Load(byte[])
System.Reflection.Assembly.Load (System.Byte[] rawAssembly) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
MonoMod.Utils.ReflectionHelper.Load (System.IO.Stream stream) (at <5be58f3c80ca41c4960cf35eb47d4341>:0)
MonoMod.Utils.ReflectionHelper.Load (Mono.Cecil.ModuleDefinition module) (at <5be58f3c80ca41c4960cf35eb47d4341>:0)
HarmonyLib.DelegateTypeFactory.CreateDelegateType (System.Type returnType, System.Type[] argTypes, System.Nullable`1[T] convention) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.DelegateTypeFactory.CreateDelegateType (System.Type returnType, System.Type[] argTypes) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.Public.Patching.NativeDetourMethodPatcher.Init () (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.Public.Patching.NativeDetourMethodPatcher..ctor (System.Reflection.MethodBase original) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.Public.Patching.NativeDetourMethodPatcher.TryResolve (System.Object sender, HarmonyLib.Public.Patching.PatchManager+PatcherResolverEventArgs args) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.Public.Patching.PatchManager.GetMethodPatcher (System.Reflection.MethodBase methodBase) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, HarmonyLib.PatchInfo patchInfo) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.PatchClassProcessor.ProcessPatchJob (HarmonyLib.PatchJobs`1+Job[T] job) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
Rethrow as HarmonyException: Patching exception in method static UnityEngine.Object UnityEngine.Resources::Load(string path, Type systemTypeInstance)
HarmonyLib.PatchClassProcessor.ReportException (System.Exception exception, System.Reflection.MethodBase original) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.PatchClassProcessor.Patch () (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.Harmony.PatchAll (System.Type type) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
HarmonyLib.Harmony.CreateAndPatchAll (System.Type type, System.String harmonyInstanceId) (at <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0)
SkySwordKill.Next.Main.Init () (at <f14fa6b0138f468e98b757c6a7cef1a3>:0)
SkySwordKill.Next.Main.Awake () (at <f14fa6b0138f468e98b757c6a7cef1a3>:0)
UnityEngine.GameObject:AddComponent(Type)
BepInEx.Bootstrap.Chainloader:Start()
UnityEngine.Application:.cctor()

4.How to reproduce
After discover the problem,I was trying to rename the game directory name.
When plugin path is D:\soft\steam\steamapps\common\觅长生\64\BepInEx\plugins\Next.dll,it throw the Exception.
When plguin path is D:\soft\steam\steamapps\common\M\64\BepInEx\plugins\Next.dll,it work well.
The application path is D:\soft\steam\steamapps\common\觅长生\64\觅长生.exe

Runtime environment:

  • OS: Windows 10, 64bit
  • .NET version: 4.7.2
  • Harmony version: 2.5.5
  • Name of game or host application: 觅长生
@pardeike
Copy link
Owner

The newest release of Harmony is 2.1.1 so something is wrong.

@magicskysword
Copy link
Author

Sorry,I found that the Harmony In BepinEx is HarmonryX fork.I will close the issue.

@garettbass
Copy link

garettbass commented Oct 23, 2023

Harmony will still run afoul of this issue whenever Assembly.GetName() is called on an assembly for which the full file path contains any multi-byte UTF-8 characters. We encountered this when the Unity project was in a user's desktop or documents directory and the user's name contained characters such as 'Á' or 'ü', e.g.

C:\Users\garett\my-ünity-pröject  # note umlauts in path

There are calls to Assembly.GetName().Name and Assembly.GetName().Version in 0Harmony.dll in older versions, such as from the tag ((Pre-MonoMod-Common)), which will produce the exception ExecutionEngineException: String conversion error: Illegal byte sequence encounted in the input., and in newer versions there are also calls to Assembly.GetName() in MonoMod.Common.dll (and perhaps other dependencies) which will also produce this exception.

I'm unable to use the newer MonoMod-dependent versions in our projects due to conflicts with some Unity packages like Burst, but I have made a fix atop the ((Pre-MonoMod-Common)) version which can be found on my fork here:
https://github.com/garettbass/Harmony/tree/users/garett/Pre-MonoMod-Common

@garettbass
Copy link

This is the relevant commit:
garettbass@c6bbea0

@pardeike
Copy link
Owner

@nike4613 might be interested why you cannot use new Harmony and his new dependencies.

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

No branches or pull requests

3 participants