I have binaries of .NET library and I have to restore all sources. I used .NET Reflector and in most cases it works very well. 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?
EDIT
I used ilspy.net and for me it is even worse
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. This is certainly the case for the dynamic keyword, the compiler makes calls to the binder in Microsoft.CSharp.dll. And there tend to be a lot of it, the dynamic keyword is an expensive hobby.
Things that disassemblers cannot do:
Lambdas and Linq got added in 2008 with C# version 3.0 and were instant hits. Also the year that Lutz Roeder decided that he no longer wanted to work on Reflector and sold it to 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With