问题标签 [mono.cecil]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1076 浏览

c# - 如何在任何基于 CLR 的语言程序集中找到给定类型的所有类型依赖项?

我试图找到给定类型所依赖的所有类型,包括接口、抽象类、枚举、结构等。我想加载一个程序集,并打印出其中定义的所有类型的列表,并且他们的依赖。

到目前为止,我已经能够使用 Mono.Cecil 找到 CLR 程序集所依赖的所有外部类型,例如

该列表也可以使用单反汇编器获得,例如“monodis SomeAssembly.dll --typeref”,但该列表似乎不包括原语,例如 System.Void、System.Int32 等

我需要单独处理每种类型,并获取给定类型所依赖的所有类型,即使这些类型是在同一个程序集中定义的。有没有办法使用 Mono.Cecil 或任何其他项目来做到这一点?

我知道这可以通过加载程序集,然后迭代每个定义的类型,然后加载该类型的 IL 并扫描它以查找引用来完成,但我确信有更好的方法。理想情况下,它也适用于匿名内部类。

如果在同一个程序集中定义了多个模块,它也应该工作。

0 投票
1 回答
837 浏览

.net - 这些属性在 Mono.Cecil 中意味着什么?

我正在使用 Lokad 共享库,而后者又依赖于 Mono.Cecil。

我有点困惑以下属性的含义(它们与 .NET 内部结构有关,因此具有等效的 .NET 内部结构):

  • PackingSize(它们与 TypeDefinition 中的类型有关)。
  • Mvid(在 ModuleDefinition 中)。
  • ExplicitThis(与我知道的 this 关键字有关,但在 MethodDefinition 中)。
  • 呼叫会议。
  • GetSentinel(在 MethodReference 中返回 int 的方法)。
  • RVA。
  • 语义属性。
  • IsHideBySig。

知道这些是什么意思/做什么吗?

0 投票
1 回答
774 浏览

c# - 用 Mono.Cecil 替换一个类

假设我有程序集 A。它用 Mono.Cecil 进行了一些修改。现在假设我有程序集 B。它有一个名为SomeClass. 程序集 A 还有一个名为 的类SomeClass。现在我想用SomeClass程序集 B 中的替换程序集 A。我尝试了一些事情,但我知道对于我的一次尝试,它实际上重新映射了一个方法调用,如下所示:

...进入这个:

这不可能。用 Mono.Cecil 替换类的正确方法是什么?

0 投票
1 回答
1027 浏览

mono - 塞西尔中的动态方法

Cecil 中是否有类似 Reflection.Emit.DynamicMethod 的东西?谢谢。

  1. 动态法

编辑:

下面的事情怎么办?

  1. EmitCall (例如
    IL.EmitCall(OpCodes.Callvirt, GetBuildKey, null); IL.Emit(OpCodes.Unbox_Any, dependencyType); )
  2. LocalBuilder (例如 LocalBuilder 解析 = ilContext.IL.DeclareLocal(typeof(bool));)
  3. System.Reflection.Emit.Label (eg Label existingObjectNotNull = buildContext.IL.DefineLabel();) //一定要用TextMap吗?
  4. ILGenerator.BeginCatchBlock (例如 ilContext.IL.BeginCatchBlock(typeof(Exception)); )
  5. ILGenerator.MarkLabel (例如 ilContext.IL.MarkLabel(parameterResolveFailed); )
  6. ILGenerator.EndExceptionBlock() (例如 ilContext.IL.EndExceptionBlock(); )
0 投票
2 回答
2961 浏览

c# - Mono.Cecil 可以修改 AppDomain 中已经加载的代码吗?

我想在运行时向某个类添加一些行为。我知道如何在运行时使用 Reflection.Emit 进行子类化,但这还不够。根据一些外部配置,我需要在类型 T 的方法中注入操作码,以便从它继承的所有类自动获得此行为。(我不能使用 .NET Profiling API)。

可以用 Mono.Cecil 完成这样的事情吗?

如果无法在加载的程序集上修改代码,那很好,如果我可以在加载程序集之前进行修改,然后将修改后的程序集加载到内存中,但我不知道如何控制程序集加载。

0 投票
6 回答
6523 浏览

c# - 替换方法的 MethodBody 中的指令

(首先,这是一篇很长的帖子,但别担心:我已经实现了所有这些,我只是在问你的意见,或者可能的替代方案。)

我在执行以下操作时遇到了麻烦;我很感激一些帮助:

  1. 我得到一个Typeas 参数。
  2. 我使用反射定义了一个子类。请注意,我不打算修改原始类型,而是创建一个新类型。
  3. 我为原始类的每个字段创建一个属性,如下所示:

    /li>
  4. 对于超类的每个方法,我都会在子类中创建一个类似的方法。方法的主体必须相同,只是我将指令替换为ldfld xcallvirt this.get_X也就是说,我调用 get 访问器,而不是直接从字段中读取。

我在第 4 步遇到问题。我知道您不应该像这样操作代码,但我真的需要这样做。

这是我尝试过的:

尝试 #1:使用 Mono.Cecil。这将允许我将方法的主体解析为人类可读的Instructions,并轻松替换指令。但是,原始类型不在 .dll 文件中,所以我找不到使用 Mono.Cecil 加载它的方法。将类型写入 .dll,然后加载它,然后修改它并将新类型写入磁盘(我认为这是使用 Mono.Cecil 创建类型的方式),然后加载它似乎是一个巨大的开销。

尝试#2:使用 Mono.Reflection。这也将允许我将正文解析为Instructions,但我不支持替换指令。我使用 Mono.Reflection 实现了一个非常丑陋且效率低下的解决方案,但它还不支持包含 try-catch 语句的方法(尽管我想我可以实现这个)并且我担心可能存在其他场景它不起作用,因为我ILGenerator以一种不寻常的方式使用它。此外,它非常难看;)。这是我所做的:

这是可怕的,可怕的Reemit方法:

分支指令是一种特殊情况,因为instr.Operandis SByte,但Emit需要类型为 的操作数Label。因此需要Dictionary labels.

如您所见,这非常可怕。更重要的是,它并非在所有情况下都有效,例如包含 try- catch语句的方法BeginExceptionBlock,因为我没有使用. 这变得越来越复杂。我想我可以做到:有一个列表应该包含执行此操作的必要信息。但无论如何我都不喜欢这个解决方案,所以我会把它保存为最后的解决方案。BeginCatchBlockILGeneratorMethodBodyExceptionHandlingClause

尝试#3:直接复制返回的字节数组MethodBody.GetILAsByteArray(),因为我只想将一条指令替换为另一条相同大小的单条指令,该指令产生完全相同的结果:它在堆栈等。所以不会有任何标签移动,一切都应该完全一样。我已经这样做了,替换了数组的特定字节,然后调用MethodBuilder.CreateMethodBody(byte[], int),但我仍然得到同样的异常错误,我仍然需要声明局部变量,否则我会得到一个错误......即使我只是复制方法的主体,不要改变任何东西。所以这更有效,但我仍然需要处理异常等。

叹。

这是尝试#3的实现,以防有人感兴趣:

(我知道它不漂亮。对不起。我很快把它放在一起看看它是否有用。)

我不抱太大希望,但有人能提出比这更好的建议吗?

很抱歉这篇文章太长了,谢谢。


更新#1: Aggh ...我刚刚在msdn文档中阅读了这个:

[CreateMethodBody 方法] 目前不完全支持。用户无法提供令牌修复和异常处理程序的位置。

在尝试任何事情之前,我真的应该阅读文档。总有一天我会学...

这意味着选项 #3 不支持 try-catch 语句,这对我来说毫无用处。我真的必须使用可怕的#2吗?:/ 帮助!:P


更新#2:我已经成功实现了尝试#2,支持异常。这很丑陋,但它有效。当我稍微改进代码时,我会在这里发布。这不是优先事项,因此可能需要几周后。只是让你知道,以防有人对此感兴趣。

感谢您的建议。

0 投票
1 回答
2458 浏览

.net - Mono-Cecil:如何获得 mscorlib 的 ModuleDefinition?

我正在尝试编写调用 mscorlib 中的方法的 IL,但我无法弄清楚如何让ModuleDefinitionmscorlib 实际引用类型和方法,并且缺少文档和谷歌。

0 投票
1 回答
1403 浏览

c# - 如何使用 Mono.Cecil 为接口方法实现起别名?

我正在使用Mono.Cecil(版本 0.6.9.0)为实现接口方法的方法设置别名。为此,我必须Override在目标方法中添加一个指向接口方法的方法(很像 VB.NET 的可能性),如下所示:

我得到的是一个PEVerify.exe错误,表明我的类不再实现接口方法。覆盖引用和接口中的方法之间的更改程序集似乎存在令牌不匹配:

我知道如果我MethodDefinition直接使用它会起作用:

但我真的需要使用 aMethodReference因为我可能在所涉及的类型中有泛型参数和参数,而简单的MethodDefinition不会这样做。

更新:根据Jb Evain的建议,我已迁移到 0.9.3.0 版。但是,同样的错误仍然发生。这是迁移的代码:

0 投票
3 回答
2938 浏览

c# - 如何判断一个方法中调用了哪些方法?

我想列出从特定方法调用的所有方法。例如,如果我有以下代码:

该列表应包含 test2() 和 test3()。如果可以列出同一类的方法以及另一个类的方法,那就太好了。

另外,我想找到一种方法来检测方法中使用了哪些字段:

因此应该列出 test1。

我尝试使用 Mono.Cecil 进行此操作,但不幸的是我找不到有关该项目的大量文档。那么有人知道该怎么做吗?

编辑:我想用 Mono.Cecil 来做,因为通过它的 API,我可以直接在我的应用程序中使用结果。如果我使用 Visual Studio 或类似工具中的内置工具,则很难进一步处理结果。

0 投票
2 回答
8952 浏览

c# - Mono.Cecil TypeReference to Type?

无论如何从 Mono.Cecil 中的 TypeReference 到 Type 吗?