简体   繁体   English

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

[英]Disassemble .NET c# library with dynamic types

I have binaries of .NET library and I have to restore all sources. 我有.NET库的二进制文件,我必须恢复所有源。 I used .NET Reflector and in most cases it works very well. 我使用.NET Reflector ,在大多数情况下它运行得很好。 But now I have problem with dynamic type. 但现在我有动态类型的问题。 I have following code and I dont really now how to understand it. 我有以下代码,我现在不知道如何理解它。

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
}

Any sugestions? 任何sugestions?

EDIT 编辑

I used ilspy.net and for me it is even worse 我使用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
}

This is not a problem with your disassembler, it is a problem with your expectations. 这对您的反汇编程序来说不是问题,这是您的期望问题。 Disassemblers in general tend to fall down in any scenario where the C# compiler auto-generates a non-trivial amount of code. 在C#编译器自动生成非平凡数量的代码的任何情况下,反汇编程序通常都会出现问题。 This is certainly the case for the dynamic keyword, the compiler makes calls to the binder in Microsoft.CSharp.dll. 这肯定是dynamic关键字的情况,编译器调用Microsoft.CSharp.dll中的binder。 And there tend to be a lot of it, the dynamic keyword is an expensive hobby. 并且往往会有很多 ,动态关键字是一种昂贵的爱好。

Things that disassemblers cannot do: 拆解者不能做的事情:

  • recover comments in your original source code 恢复原始源代码中的注释
  • recover const declarations in your original code 恢复原始代码中的const声明
  • recover the name of local variables in your methods 恢复方法中的局部变量名称
  • cleanly decompile anonymous delegates 干净地反编译匿名代表
  • cleanly decompile iterators 干净地反编译迭代器
  • cleanly decompile lambda expressions 干净地反编译lambda表达式
  • cleanly decompile Linq query comprehensions 干净地反编译Linq查询理解
  • cleanly decompile code that uses dynamic variables. 干净地反编译使用动态变量的代码。
  • cleanly decompile code that uses async/await 干净地反编译使用async / await的代码

Lambdas and Linq got added in 2008 with C# version 3.0 and were instant hits. Lambdas和Linq在2008年加入了C#3.0版,并且是即时点击。 Also the year that Lutz Roeder decided that he no longer wanted to work on Reflector and sold it to Redgate. 也是Lutz Roeder决定不再想要使用Reflector并将其卖给Redgate的那一年。 The timing was almost certainly not a coincidence. 时机几乎肯定不是巧合。

The list above is a decent guide for programmers that are concerned about having their code decompiled. 对于那些担心反编译代码的程序员来说,上面的列表是一个不错的指南。 Just add enough of those constructs to your program and you just don't have to bother with obfuscators anymore. 只需在程序中添加足够的构造,您就不必再为混淆器烦恼了。

Meanwhile, this certainly doesn't help you recover your code. 同时,这肯定无法帮助您恢复代码。 You'll have to do it by hand, relying on your memory of what it might have looked like before. 你必须手工完成它,依靠你对它之前的样子的记忆。 Of course, first thing to do is to take care of reliable and recoverable source control. 当然,首先要做的是处理可靠和可恢复的源控制。 That's a mistake you only make once. 这只是你做过一次的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM