像Red Gate Ant Profiler或Reflector这样的工具如何将IL转换为C#或VB.NET代码?
我最近注意到Red Gate Ant Profiler不会生成最初编写的源代码。
在我使用foreach的地方,它生成了一个while循环。
这让我开始思考。我在Reflector中打开了Reflector.exe本身,但他们的代码大部分(不是全部)是模糊的。
发布于 2014-01-22 06:34:38
通常情况下,反编译器通过查看IL并构建在语义上与IL等效的源代码来工作。这并不总是产生原始的源代码,因为IL丢弃了一些高级信息(尽管没有机器代码那么多),而且通常有几段代码编译成同一个IL。例如,foreach循环等同于某种类型的while循环(首先设置枚举器,然后循环直到枚举器耗尽,然后在每一步推进枚举器)。
发布于 2014-02-10 09:52:50
实现反编译的一种常见技术是使用一种称为“区间分析”的方法来识别循环的范围。
当与习惯用法识别和被称为“派生图序列”的模式相结合时,可以从包含汇编语言(或MSIL)的控制流图开始,迭代地简化它,直到有一个表示程序(或方法)的“源代码级”视图的AST (抽象语法树)节点。给定AST之后,生成源代码就很简单了:您只需打印生成的AST即可。
以下是一些指向更多信息的链接:
http://en.wikipedia.org/wiki/Interval_(graph_theory)
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.50.8004&rep=rep1&type=pdf
一般来说,你永远不会在原始源和反编译的源代码之间有完全的保真度。
foreach循环的控制流图看起来像while循环的控制流图。这在很大程度上是因为以下代码:
foreach (var x in xs) {
//body
}实际上是语法上的糖:
var enumerator = xs.GetEnumerator()
try {
while (enumerator.MoveNext()) {
var x = xs.Current;
//body
}
}
finally {
enumerator.dispose();
}也就是说,foreach循环基本上被转换成while循环,然后while循环被编译成MSIL。
为了让反编译器生成for-each循环,它必须添加特殊支持来尝试猜测while循环实际上是foreach循环。任何这样的逻辑都不是完美的(上面的while循环和foreach循环都应该产生相同(或非常相似)的MSIL代码)。
在某些情况下,它会与您编写的源代码相匹配,而在另一些情况下,则不会。
您可能已经编写了for-each循环,因此从可用性的角度来看,在for-each循环与while循环的一侧出错是一个很好的选择。
然而,这是额外的工作。反编译器编写者必须开始说“我想添加一堆启发式方法来尝试检测for-each循环”。
最后,有很多事情会阻碍反编译。例如,"break“和"continue”语句的出现可能会使事情变得复杂。某些类型的嵌套也是如此( switch语句中的循环,反之亦然)。它们都可能导致CFG循环具有多个入口点和多个出口点。这增加了生成可读源代码的难度。
通常,处理这些情况的唯一方法是使用启发式方法。这些启发式方法有时会“做错事”。
此外,即使是很小的东西,比如用于循环边界的特定表达式,也会破坏习惯用法识别。有时编译器会引入临时变量(源代码中没有的)。这可能需要额外的习惯检查,或者更高级的技术,如数据流分析(实时变量分析,定义-使用链等)。
总而言之:反编译是困难的,而且永远不会完美。此外,我确信实现者必须考虑权衡。例如,投资于检测for-each循环有意义吗?还是应该把时间花在反编译lambdas和推断LINQ查询上?
https://stackoverflow.com/questions/21270436
复制相似问题