4

我有 .NET 库的二进制文件,我必须恢复所有源。我使用了.NET Reflector,在大多数情况下效果很好。但是现在我遇到了动态类型的问题。我有以下代码,我现在真的不知道如何理解它。

dynamic obj2 = component;
if (<SetValue>o__SiteContainer0<T>.<>p__Site1 == null)
{
     <SetValue>o__SiteContainer0<T>.<>p__Site1 = CallSite<Func<CallSite, object, bool>>.Create(Binder.UnaryOperation(CSharpBinderFlags.None, ExpressionType.IsTrue, typeof(RecordPropertyDescriptor<T>), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
}
if (<SetValue>o__SiteContainer0<T>.<>p__Site2 == null)
{
      <SetValue>o__SiteContainer0<T>.<>p__Site2 = CallSite<Func<CallSite, object, object, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.None, ExpressionType.NotEqual, typeof(RecordPropertyDescriptor<T>), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) }));
}
if (<SetValue>o__SiteContainer0<T>.<>p__Site1.Target(<SetValue>o__SiteContainer0<T>.<>p__Site1, <SetValue>o__SiteContainer0<T>.<>p__Site2.Target(<SetValue>o__SiteContainer0<T>.<>p__Site2, obj2[this.Name], value)))
{
    // some simple code
}

有什么建议吗?

编辑

我使用了 il​​spy.net,对我来说更糟

Func<CallSite, object, bool> arg_163_0 = RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site1.Target;
CallSite arg_163_1 = RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site1;
if (RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site2 == null)
{
    RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site2 = CallSite<Func<CallSite, object, object>>.Create(Binder.UnaryOperation(CSharpBinderFlags.None, ExpressionType.Not, typeof(RecordPropertyDescriptor<T>), new CSharpArgumentInfo[]
    {
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
    }));
}
Func<CallSite, object, object> arg_15E_0 = RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site2.Target;
CallSite arg_15E_1 = RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site2;
if (RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site3 == null)
{
    RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site3 = CallSite<Func<CallSite, Type, object, object, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.None, "Equals", null, typeof(RecordPropertyDescriptor<T>), new CSharpArgumentInfo[]
    {
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.IsStaticType, null),
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
    }));
}
Func<CallSite, Type, object, object, object> arg_159_0 = RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site3.Target;
CallSite arg_159_1 = RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site3;
Type arg_159_2 = typeof(object);
if (RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site4 == null)
{
    RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site4 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.GetIndex(CSharpBinderFlags.None, typeof(RecordPropertyDescriptor<T>), new CSharpArgumentInfo[]
    {
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
    }));
}
if (arg_163_0(arg_163_1, arg_15E_0(arg_15E_1, arg_159_0(arg_159_1, arg_159_2, RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site4.Target(RecordPropertyDescriptor<T>.<SetValue>o__SiteContainer0.<>p__Site4, component, this.Name), value))))
{
    // some (not so) simple code
}
4

1 回答 1

13

这不是您的反汇编程序的问题,而是您的期望的问题。在 C# 编译器自动生成大量代码的任何情况下,反汇编程序通常都会崩溃。动态关键字肯定是这种情况,编译器调用 Microsoft.CSharp.dll 中的绑定程序。而且往往有很多,动态关键字是一种昂贵的爱好。

反汇编程序不能做的事情:

  • 恢复原始源代码中的注释
  • 恢复原始代码中的 const 声明
  • 在您的方法中恢复局部变量的名称
  • 干净地反编译匿名委托
  • 干净地反编译迭代器
  • 干净地反编译 lambda 表达式
  • 干净地反编译 Linq 查询理解
  • 干净地反编译使用动态变量的代码。
  • 干净地反编译使用 async/await 的代码

Lambdas 和 Linq 在 2008 年与 C# 版本 3.0 一起被添加,并且一炮而红。也是 Lutz Roeder 决定不再为 Reflector 工作并将其卖给 Redgate 的那一年。这个时机几乎可以肯定不是巧合。

上面的列表对于担心代码被反编译的程序员来说是一个不错的指南。只需将足够多的这些构造添加到您的程序中,您就不必再为混淆器而烦恼了。

同时,这当然不能帮助您恢复代码。您必须手动完成,这取决于您对它以前的样子的记忆。当然,首先要做的是处理可靠和可恢复的源代码控制。这是你只犯一次的错误。

于 2013-08-01T10:36:48.807 回答