holly-hacker/EazFixer

Failed reflection resolving for .NET Core runtimes

Duskfall opened this issue · 14 comments

Thanks for this!
For string encryption I get this error
image

Could you upload the sample you're testing on?

The problem occurs while resolving types through reflection, but I'm not sure why.

Although, something else that I noticed is that I was unable to enumerate Assembly.DefinedTypes because it could not resolve System.Runtime (yet dnSpy has no problems with it). I did some checking and it turns out that it is a .NET Core dll. Perhaps the problem lies there.

The real problem is probably that the tool uses .NET 4.6.x, while your DLL uses .NET Core 2.0. So, .NET will get confused while trying to resolve the referenced assembly and not look in the .NET Core assembly locations (C:\Program Files\dotnet\shared\Microsoft.NETCore.App). Adding a custom AssemblyResolver will probably fix it.

Cool that makes sense! If I have time, I'll try forking the project and add a custom resolver like this https://stackoverflow.com/questions/1561806/looking-for-net-assembly-in-a-different-place.
I have done something similar in the past though I don't really remember clearly, it has been like 3 years :P

Don't worry, I'm on it. There will be a problem if the .NET Core runtimes aren't installed though.

Looks like you are unable to load System.Private.CoreLib (which the other .NET Core runtimes rely on) through Assembly.LoadFile, meaning no .NET Core assemblies can actually be loaded from the .NET Framework.

The natural fix would be to compile the tool itself for .NET Core, but Harmony doesn't have support for it yet so the anti-invoke protection would not be removed. I would suggest you take a look at de4dot, but that didn't seem to work for me either.

If you want to try to find a fix yourself using assembly resolving, my code is below. Simply call it at the start of the program.

public static void AddNetCoreResolvers()
{
    AppDomain.CurrentDomain.AssemblyResolve += OnNetCoreResolve;
}

private static Assembly OnNetCoreResolve(object sender, ResolveEventArgs args)
{
    var an = new AssemblyName(args.Name);

    var pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);

    //dotnet\shared\Microsoft.NETCore.App\2.0.0-preview2-25407-01
    var masterFolder = Path.Combine(pf, "dotnet", "shared", "Microsoft.NETCore.App");

    //TODO: perhaps check snk too?
    var asmName = Directory.EnumerateFiles(masterFolder, $"{an.Name}.dll", SearchOption.AllDirectories)
        .Reverse()
        .FirstOrDefault();

    if (asmName == null) return null;
    else return Assembly.LoadFile(asmName);
    //return asmName != null ? Assembly.LoadFile(asmName) : null;
}

I have already tried de4dot and also tried the different params but no luck. :/ I managed to debug it with dnSpy and got it working that way :P Thanks anyway!

Alright, glad to hear that :)

I'll keep this issue open, in case Harmony updates.

Hi Holly, i've the very same problem on a .NET 3.5 dll
Could u suggest me a fix to try your library?

Thx!
A.

Your assembly was probably protected with an older version of Eazfuscator. Try de4dot.

This is an issue related to reflection resolving, not a support thread.

Closing since EazFixer now targets both .NET Framework 4.7.2 and .NET Core 3.1, and Harmony has been updated to v2.x.