パブリッククラスのパブリック仮想メソッドのldvirtftnによって、匿名でホストされた動的メソッドを使用すると誰が説明できないのですか?私は、次のアセンブリレベルが同様に属性を設定します。ここではLdvirtftnは確認できないのはなぜですか?
[assembly: SecurityTransparent]
[assembly: SecurityRules(SecurityRuleSet.Level2,SkipVerificationInFullTrust=true)]
は、サンプルコードです:メソッドを所有している場合
public class Program
{
public virtual void Foo() {}
public static void Main(string[] args)
{
Action<ILGenerator> genfunc = il => il
.newobj<Program>()
.ldvirtftn(typeof(Program).GetMethod("Foo"))
.ret();
try
{
Console.WriteLine(CodeGen.CreateDelegate<Func<IntPtr>>(genfunc).Invoke());
}
catch (System.Security.VerificationException) { }
Console.WriteLine(CodeGen.CreateDelegate<Func<IntPtr>>(genfunc,owner:typeof(Program)).Invoke());
}
}
、それは例外をスローしません。
さらに好奇心は、私は次のようにコードを変更した場合ので、その後、両方の方法は、コンパイルして問題なく実行することです:
public class Program
{
public virtual void Foo() {}
public static void Main(string[] args)
{
Action<ILGenerator> genfunc = il => il
.newobj<Program>()
.dup()
.ldvirtftn(typeof(Program).GetMethod("Foo"))
.newobj<Action>(typeof(object),typeof(IntPtr))
.ret();
try
{
Console.WriteLine(CodeGen.CreateDelegate<Func<Action>>(genfunc).Invoke());
}
catch (System.Security.VerificationException) { }
Console.WriteLine(CodeGen.CreateDelegate<Func<Action>>(genfunc,owner:typeof(Program)).Invoke());
}
}
このコードは、反射ライブラリで書かれていました。
CodeGen.CreateDelegateは、単にtypeパラメータを使用して動的メソッドのシグネチャを決定します。方法は次のとおりです。::
public static TDelegate CreateDelegate<TDelegate>(
Action<ILGenerator> genfunc, string name = "", object target = null, Type owner = null, bool skipVisibility = false)
where TDelegate : class
{
var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
var parameters = invokeMethod.GetParameters();
var paramTypes = new Type[parameters.Length + 1];
paramTypes[0] = typeof(object);
parameters.Select(p => p.ParameterType).ToArray().CopyTo(paramTypes, 1);
var method = owner != null ?
new DynamicMethod(name, invokeMethod.ReturnType, paramTypes, owner, skipVisibility) :
new DynamicMethod(name, invokeMethod.ReturnType, paramTypes, skipVisibility);
genfunc(method.GetILGenerator());
return method.CreateDelegate(typeof(TDelegate), target) as TDelegate;
}
MSILはマネージコードだけではありません。生のネイティブC++コードをILにコンパイルすることもできます。 C++/CLIコンパイラが完了しました。 Opcodes.Ldvirtfnが重要なコードの種類は、v-tableから関数ポインタを掘り下げます。ジッタ・ベリファイアがそれに当たったときに、生のアドレスIntPtrは検証のヘッケーフロールではありません。 –
真実ですが、なぜメソッドを所有する型にすると検証の問題はなくなりますか? –