gpt4 book ai didi

.net - CIL 委托(delegate)行为与目标方法的冲突 "staticness"

转载 作者:行者123 更新时间:2023-12-04 17:40:48 25 4
gpt4 key购买 nike

这个问题需要一些介绍。

我正在开展一个安全项目,该项目将分析 CIL 程序集并拒绝那些执行某些定义的“坏”事情的程序,同时还允许托管应用程序为某些方法提供“门”,以允许过滤某些调用。 (这是项目功能的一小部分,但这是我将在这里询问的部分。)

该项目扫描程序集中每个方法中的所有指令,并查找调用、callvirt、ldftn、ldvirtftn 和 newobj 操作码,因为这些是最终可以导致方法调用的唯一操作码。构造委托(delegate)时使用 ldftn 操作码,如下所示:

ldarg.1
ldftn instance bool string::EndsWith(string)
newobj instance void class [System.Core]System.Func`2<string, bool>::'.ctor'(object, native int)

在这个序列的末尾,一个 Func<string, bool>位于堆栈的顶部。

假设我想拦截对 String.EndsWith(String) 的所有调用.对于 call 和 callvirt,我可以将实例调用替换为签名的静态调用 Boolean(String,String) -- 第一个参数将是最初调用该方法的字符串实例。在 CIL 级别上,行为将是明确且定义明确的,因为这是调用静态方法的方式。

但是对于 ldftn?我尝试用用于替换 call/callvirt 操作数的相同静态方法替换 ldftn 指令的操作数:
ldarg.1
ldftn bool class Prototype.Program::EndsWithGate(string, string)
newobj instance void class [System.Core]System.Func`2<string, bool>::'.ctor'(object, native int)

我完全期望这会失败,因为委托(delegate)被赋予了一个目标对象(非空),同时传递了一个静态方法指针。令我惊讶的是,这实际上适用于 Microsoft .NET 运行时和 Mono。我知道 target/this 参数只是该方法的第一个参数,并且对于实例方法是隐藏的。 (该项目基于这些知识。)但是,代表实际上在这些情况下工作的事实让我有点困惑。

所以,我的问题是:这是定义和记录的行为吗?代理在调用时是否总是将其目标插入堆栈(如果它不为空)?构造一个将捕获目标并“正确”调用静态方法的闭包类会更好吗,即使这会更加复杂和烦人?

最佳答案

ECMA 335 规范第 2 部分 14.6.2 有一段关于此:
T 和 D 的调用约定应完全匹配,忽略静态方法和实例方法之间的区别。 (即 this 参数,如果有的话,不做特殊处理)。

对于静态方法,这对我来说听起来像是两种变体:

  • 没有这个,在这种情况下应该传递 NULL
  • 使用额外的第一个参数,假设类型与输入 newobj 调用的内容相匹配。
  • 关于.net - CIL 委托(delegate)行为与目标方法的冲突 "staticness",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424410/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com