Code Monkey home page Code Monkey logo

Comments (12)

 avatar commented on August 29, 2024

What fails, the resolver? Does it work if you force the assembly resolver to only resolve .NET 4.0 assemblies by updating the search paths?

Also, do you have a simple test program?

from dnlib.

yck1509 avatar yck1509 commented on August 29, 2024

I do have a test program, however it's quite complex:
First, create a library in .NET 3.5:

using System;
public class TestA {
    public static void Test(Action act) {
        act();
    }
}

Second, create an application in .NET 4.0, referencing the first library:

using System;
public class TestB {
    public static void Main() {
        TestA.Test(() => Console.WriteLine("OK"));
    }
}

Then the following code would demonstrate the issue:

using System;
using System.Diagnostics;
using dnlib;
using dnlib.DotNet;

class Program {
    static void Main(string[] args) {
        var module = ModuleDefMD.Load(@"SampleB.exe");
        var type = module.Find("TestB", true);
        var method = type.FindMethod("Main");
        foreach (var instr in method.Body.Instructions) {
            if (instr.Operand is IMethod && ((IMethod)instr.Operand).Name == "Test") {
                var methodRef = (IMethod)instr.Operand;
                var methodDef = methodRef.ResolveMethodDef();
                Debug.Assert(methodDef != null);
            }
        }
    }
}

The assertion failed here. It should be able to resolve to TestA.Test in the first library.
How to force the resolver to only resolve .NET 4 assemblies? Use PreSearchPaths/PostSearchPaths?
Also, Mono.Cecil can resolve it correctly, however they ignore the scope of method reference, marked as a TODO. The framework fusion worked by having a 'framework config' redirect:

LOG: Version redirect found in framework config: 3.5.0.0 redirected to 4.0.0.0.
LOG: Post-policy reference: System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

However, I'm unable to find where this 'framework config' is located.

from dnlib.

 avatar commented on August 29, 2024

How to force the resolver to only resolve .NET 4 assemblies? Use PreSearchPaths/PostSearchPaths?

Yes, and make sure they're empty first so it won't try to keep looking if it doesn't find the exact assembly (correct name + version). FindExactMatch prop should also be false.

from dnlib.

yck1509 avatar yck1509 commented on August 29, 2024

It works when I use the following module loading code:

        var resolver = new AssemblyResolver();
        resolver.PreSearchPaths.Clear();
        resolver.PreSearchPaths.Add(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\");
        resolver.FindExactMatch = false;
        var moduleCtx = ModuleDefMD.CreateModuleContext(false);
        moduleCtx.AssemblyResolver = resolver;

        var module = ModuleDefMD.Load(@"SampleB.exe", moduleCtx);

from dnlib.

 avatar commented on August 29, 2024

Cool, I might add some code (simple methods to call) to make that easier so you don't have to add the paths yourself like above. FindExactMatch should be false by default though, but I mentioned it above just in case you had set it to true.

from dnlib.

yck1509 avatar yck1509 commented on August 29, 2024

So does it mean there should be 2 different assembly resolvers, one for .NET 3.5, one for .NET 4, for dnlib to resolve the references correctly?

from dnlib.

 avatar commented on August 29, 2024

No, but if you have 2+ assemblies and you know that the main exe will use .NET 4.0, then you might need to make sure only .NET 4.0 search paths are used if the other one uses another earlier .NET version, as in your example above. This would match the runtime's behaviour: .NET 4.0 runtime only searches for .NET 4.0 DLLs. By default, dnlib will try to use the exact DLL file because I think this is what most people would want and expect.

from dnlib.

yck1509 avatar yck1509 commented on August 29, 2024

Okay, thanks for your help!

from dnlib.

yck1509 avatar yck1509 commented on August 29, 2024

I've finally find the information for framework version redirect by reversing the runtime. You can find my fix in bfc3340. I also fix the MemberRef resolving problem in quite complicated way in 4000f37. It might be useful.

from dnlib.

 avatar commented on August 29, 2024

Looks good! I'll add those to my dnlib too probably tomorrow. I noticed that you used default arguments, and I'll add a commmit that undoes that by adding extension methods or extra methods because VS2008 doesn't support default arguments (AFAICR).

BTW, are those redirects hardcoded or do they exist in some XML file?

from dnlib.

yck1509 avatar yck1509 commented on August 29, 2024

These redirects are hardcoded into clr.dll/mscorwks.dll, I extract them using the following code:

        static unsafe void frRedirV2() {
            // .NET 3.5, x86
            var clrBase = (byte*)Process.GetCurrentProcess().Modules.OfType<ProcessModule>().Single(m => m.ModuleName == "mscorwks.dll").BaseAddress;
            IntPtr* fXPolicy = (IntPtr*)(clrBase + 0xB98A0);                  // g_arFxPolicy

            var frRedirs = new List<Tuple<string, string, string>>();

            while (((uint)fXPolicy[0] & 0xff000000) == ((uint)fXPolicy[1] & 0xff000000)) {
                var frName = Marshal.PtrToStringUni(fXPolicy[0]);
                var frKey = Marshal.PtrToStringUni(fXPolicy[1]);
                var frVer = Marshal.PtrToStringUni(fXPolicy[2]);
                frRedirs.Add(Tuple.Create(frName, frKey, frVer));
                fXPolicy += 3;
            }
            var list = string.Join(Environment.NewLine, frRedirs.Select(redir => redir.ToString()).ToArray());
        }

        static unsafe void frRedirV4() {
            // .NET 4.5, x86
            var clrBase =
                (byte*)Process.GetCurrentProcess().Modules.OfType<ProcessModule>().Single(m => m.ModuleName == "clr.dll").BaseAddress;
            byte* fXPolicy = clrBase + 0x54380;                  // g_arFxPolicy
            IntPtr* partStrs = (IntPtr*)(clrBase + 0x54850);     // g_rgAssemblyNamePartStrings
            IntPtr* kVerStrs = (IntPtr*)(clrBase + 0x553D4);     // g_rgAssemblyKeyVersionStrings

            var frRedirs = new List<Tuple<string, string, string, bool>>();

            while (fXPolicy[5] != 0) {
                var frName = new StringBuilder();
                for (int i = 0; i < 4; i++) {
                    if (fXPolicy[i] != 0)
                        frName.Append(Marshal.PtrToStringAnsi(partStrs[fXPolicy[i]]) + ".");
                    else
                        break;
                }
                var frKey = Marshal.PtrToStringUni(kVerStrs[fXPolicy[4]]);
                var frVer = Marshal.PtrToStringUni(kVerStrs[fXPolicy[5] & 0x7f]);
                var flag = (fXPolicy[5] >> 7) != 0;
                frRedirs.Add(Tuple.Create(frName.ToString().Trim('.'), frKey, frVer, flag));
                fXPolicy += 6;
            }
            var list = string.Join(Environment.NewLine, frRedirs);
        }

Your addresses may vary.

from dnlib.

 avatar commented on August 29, 2024

I've now added your two commits

from dnlib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.