反编译VB.Net程序集会生成带有无效成员变量名的代码;名称以$ STATIC $开头

时间:2011-09-05 15:57:23

标签: c# vb.net decompiling reflector

我正在为一个丢失了其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;

有人能解释为什么生成的代码有这些无效的成员变量以及我如何解决这些变量?

3 个答案:

答案 0 :(得分:10)

这些是由VB.NET编译器生成的用于实现 Static 关键字的标识符。例如:

Class Example
    Public Sub test()
        Static lookhere As Integer = 42
    End Sub
End Class

生成此IL:

.field private specialname int32 $STATIC$test$2001$lookhere
.field private specialname class [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag $STATIC$test$2001$lookhere$Init

通过在字段名称中使用保留字母,编译器可以确保永远不会与其他字段发生意外冲突。在C#语言中没有直接等同于 Static 。您可以将它们保留为类中的私有字段,但您必须注意初始化。 $ Init标志的目的,而不是很多确保变量被正确初始化的IL。您需要手动重命名。

答案 1 :(得分:9)

简而言之,IL中的有效内容不一定与源语言中的有效内容相同。在编译器生成的(在某些圈子中也称为合成)成员名称在语言中无效是相当常见的,因为它避免了任何可能的冲突。这些有时被称为不可言说的名称,因为它们不能在源语言中“说出”。例如,C#编译器通常包含<>这样的名称。

至于解决问题 - 一些反编译器会解决这些名称来自哪里,但你通常只需在任何地方更改名称。您最终不会得到原始源代码,但如果您查看最终的内容,您可以更轻松地解决原始源所做的事情< / em>看起来像。

请注意,编译器可能生成的不仅仅是无效的名称:例如,在C#中,迭代器块生成IL,在某些情况下,不能直接在“普通”C#本身中表示。这对你来说可能不是问题,但值得注意。

答案 2 :(得分:2)

这些不是变量,它们是字段(它们具有访问修饰符)。

它们将是编译器生成的字段,将在许多不同的情况下生成。这些名称故意无效,以避免与“正常”字段发生冲突。

如果你能提供更多的上下文,有些聪明的人可能会弄清楚源代码最初看起来像是什么,以便编译器发出这些字段。