反编译 VB.Net 程序集会生成具有无效成员变量名称的代码;以 $STATIC$ 开头的名称
我正在为一位客户工作,该客户丢失了其中一个 VB.Net WinForms 应用程序的源代码。他们所拥有的程序集一点也不混乱。我正在尝试尽可能多地恢复 C# 源代码,并尝试了几种反编译程序集的工具,包括 Reflector、ILSpy 和 JustDecompile(所有最新版本),但它们都会生成带有大量错误的代码他们。由于生成的代码中存在大量错误,我将询问具体的错误(在不同的问题中),希望得到更有针对性的答案,并通过这种方式尝试阐明为什么所有工具都难以反编译这次大会。
这个问题涉及这样一个事实:所有这些工具生成的代码总是具有大量无效的成员变量(字段),如下所示:
private short $STATIC$Report_Print$20211C1280B1$nHeight;
private ArrayList $STATIC$Report_Print$20211C1280B1$oColumnLefts;
private StaticLocalInitFlag $STATIC$Report_Print$20211C1280B1$oColumnLefts$Init;
有人可以解释为什么生成的代码具有这些无效的成员变量以及如何解决这些问题吗?
I am doing work for a client who has lost the source code for one of their VB.Net WinForms applications. The assembly they have is not obfuscated at all. I am trying to recover as much of the source as I can as C# source and have tried several tools for decompiling assemblies, including Reflector, ILSpy and JustDecompile (all the latest versions), but they all produce code with a huge number of errors in them. Because of the large number of errors in the generated code, I am going to ask about the specific errors (in different questions), hopefully to get more directed answers and in this way try shed some light on why all the tools are having difficulty decompiling this assembly.
This question pertains to the fact that the code generated by all these tools always have a large number of invalid member variables (fields) such as the following:
private short $STATIC$Report_Print$20211C1280B1$nHeight;
private ArrayList $STATIC$Report_Print$20211C1280B1$oColumnLefts;
private StaticLocalInitFlag $STATIC$Report_Print$20211C1280B1$oColumnLefts$Init;
Can someone explain why the generated code has these invalid member variables and how I can resolve these?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
那些不是变量,它们是字段(它们具有访问修饰符)。它们将是编译器生成的字段,将在许多不同的情况下生成。这些名称故意无效,以避免与“正常”字段发生冲突。
如果您可以提供更多上下文,聪明的人可能会弄清楚编译器发出这些字段的源代码最初是什么样子。
Those aren't variables, they are fields (they have access modifiers).They will be compiler generated fields which will be generated in a number of different circumstances. The names are purposely invalid to avoid conflicts with "normal" fields.
If you can provide a little more context someone clever can probably figure out what the source originally looked like for the compiler to emit those fields.
这些是由 VB.NET 编译器生成的标识符,用于实现Static关键字。例如:
生成此 IL:
通过在字段名称中使用保留字母,编译器可以确保永远不会与其他字段发生意外冲突。 C# 语言中没有与静态直接等效的东西。您可以将它们保留为类中的私有字段,但必须注意初始化。 $Init 标志以及大量 IL 的目的是确保变量正确初始化。您需要手动重命名它们。
Those are identifiers generated by the VB.NET compiler to implement the Static keyword. For example:
generates this IL:
By using reserved letters in the field name, the compiler can be sure there will never be an accidental collision with another field. There's no direct equivalent to Static in the C# language. You can leave them as private fields in the class but you have to watch out for initialization. The purpose of the $Init flag and rather a lot of IL that ensures the variable is correctly initialized. You'll need to rename them by hand.
简而言之,IL 中有效的内容不一定与源语言中有效的内容相同。为编译器生成的(在某些圈子中又称为“合成的”)成员名称提供在语言中无效的名称是相当常见的,因为它可以避免任何可能的冲突。这些有时被称为无法说出的名称,因为它们无法在源语言中“说出”。例如,C# 编译器通常在此类名称中包含
<>
。至于解决问题 - 一些反编译器会自动找出这些名称的来源,但您通常可以简单地在各处更改名称。您最终不会得到原始源代码,但如果您查看您最终得到的内容,您可能能够更轻松地弄清楚原始源代码做了什么 /em> 看起来像。
请注意,编译器可能生成的不仅仅是无效名称:例如,在 C# 中,迭代器块生成 IL,在某些情况下无法直接用“正常”C# 本身表达。这对您来说可能不是问题,但值得注意。
In short, what's valid in IL isn't necessarily the same as what's valid in the source language. It's fairly common to give compiler-generated (aka synthetic in some circles) members name which are invalid in the language, as it avoids any possible clashes. These are sometimes called unspeakable names as they can't be "spoken" in the source language. For example, the C# compiler usually includes
<>
in such names.As for resolving the issue - some decompilers will work out where such names have come from automatically, but you can usually simply change the name everywhere. You won't end up with the original source code, but if you look at what you do end up with, you may be able to then work out more easily what the original source did look like.
Note that the compiler may generate more than just invalid names: in C#, for example, iterators blocks generate IL which in some cases can't be expressed directly in "normal" C# itself. This may not be a problem for you, but it's worth being aware of.