给定一个实用程序方法,用于搜索支持您没有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;
}
}
如果是这样,任何想法可以做些什么来弥补这个?
答案 0 :(得分:2)
无论您运行该应用程序的条件如何,从
GetILAsByteArray
返回的IL对于给定的程序集是否总是相同?
是,如果程序集仍然相同。
编译器生成程序集(因此其中包含IL)后,其内容将不会通过正常使用而更改。正常使用包括让.NET Framework将程序集加载到内存中,让它将IL代码编译为汇编代码,以及执行方法。
请记住,IL只是中间语言。可以将其视为生成汇编代码的蓝图。因此,运行时无需更改IL:如果他们想要更改方法的实现(例如出于优化原因),那么它们将调整汇编代码,而不是IL。
话虽如此,我可以看到一些可能性如何改变议会中的IL;但是,它们都与简单地在不同环境中运行程序有关。
如果程序集没有强名称(即散列并使用安全证书进行签名),有人可以篡改 /在磁盘上修改它,例如使用Mono Cecil或Microsoft的通用编译器基础结构(CCI)等库。
如果您希望保证装配体在生成之后无法修改,请确保其具有强烈的名称。
公共语言运行时(CLR)的非托管性能分析API 提供了使用新实现替换方法的功能。
在Visual Studio中调试程序集并在程序运行时对其进行更改(即编辑并继续功能)时,我不知道这些更改是否可以可以通过反思来看待。