CIL / IL能否在不同的环境中发生变化?

时间:2014-04-25 16:02:11

标签: c# reflection cil il

给定一个实用程序方法,用于搜索支持您没有Set访问权限的属性的Field。 一旦我在机器上工作,是否会导致这种情况失败? 无论您运行该应用程序的条件如何,从GetILAsByteArray返回的IL对于给定的程序集是否总是相同?

    public static class HackUtil
    {
        public static FieldInfo GetFieldBackingProperty(System.Reflection.PropertyInfo prop)
        {
            var acc = prop.GetAccessors().Where(x => x.ReturnType != typeof(void)).First();
            var mb = acc.GetMethodBody();
            var ilb = mb.GetILAsByteArray();
            var ldField = ilb.Skip(ilb.Length - 6).ToArray();

            // try to match a getter like: get { return myVar; }
            if (ldField[0] == 0x7b /*ldfield opcode*/ && ldField[ldField.Length - 1] == 0x2a /*ret opcode*/)
            {
                var fields = prop.DeclaringType.GetFields(System.Reflection.BindingFlags.Public
                    | System.Reflection.BindingFlags.NonPublic
                    | System.Reflection.BindingFlags.Static
                    | System.Reflection.BindingFlags.Instance
                    | System.Reflection.BindingFlags.DeclaredOnly);

                // so the 4 bytes between those two opcodes should be our metadatatoken
                var matchingField = (from f in fields
                                     where f.MetadataToken == BitConverter.ToUInt32(ldField, 1)
                                     select f).FirstOrDefault();

                return matchingField;
            }
            return null;
        }
    }

如果是这样,任何想法可以做些什么来弥补这个?

1 个答案:

答案 0 :(得分:2)

  

无论您运行该应用程序的条件如何,从GetILAsByteArray返回的IL对于给定的程序集是否总是相同?

,如果程序集仍然相同。

编译器生成程序集(因此其中包含IL)后,其内容将不会通过正常使用而更改。正常使用包括让.NET Framework将程序集加载到内存中,让它将IL代码编译为汇编代码,以及执行方法。

请记住,IL只是中间语言。可以将其视为生成汇编代码的蓝图。因此,运行时无需更改IL:如果他们想要更改方法的实现(例如出于优化原因),那么它们将调整汇编代码,而不是IL。

话虽如此,我可以看到一些可能性如何改变议会中的IL;但是,它们都与简单地在不同环境中运行程序有关。

  • 如果程序集没有强名称(即散列并使用安全证书进行签名),有人可以篡改 /在磁盘上修改它,例如使用Mono Cecil或Microsoft的通用编译器基础结构(CCI)等库。

    如果您希望保证装配体在生成之后无法修改,请确保其具有强烈的名称。

  • 公共语言运行时(CLR)的非托管性能分析API 提供了使用新实现替换方法的功能。

    例如参见MSDN Magazine article "Rewrite MSIL Code on the Fly with the .NET Framework Profiling API (.NET Internals)" by Aleksandr Mikunov

  • 在Visual Studio中调试程序集并在程序运行时对其进行更改(即编辑并继续功能)时,我不知道这些更改是否可以可以通过反思来看待。