使用动态类型反汇编.NET c#库

时间:2013-08-01 08:00:36

标签: c# .net dynamic

我有.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
}

任何sugestions?

修改

我使用 ilspy.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
}

1 个答案:

答案 0 :(得分:13)

这对您的反汇编程序来说不是问题,这是您的期望问题。在C#编译器自动生成非平凡数量的代码的任何情况下,反汇编程序通常都会出现问题。对于 dynamic 关键字来说肯定是这种情况,编译器会调用Microsoft.CSharp.dll中的binder。并且它往往是很多,动态关键字是一种昂贵的爱好。

反汇编者无法做到的事情:

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

Lambda和Linq在2008年加入了C#3.0版,并且是即时点击。也是Lutz Roeder决定不再想要使用Reflector并将其卖给Redgate的那一年。时机几乎肯定不是巧合。

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

与此同时,这肯定无法帮助您恢复代码。你必须手工完成它,依靠你对它之前的样子的记忆。当然,首先要做的是处理可靠和可恢复的源控制。这只是你做过一次的错误。