5

I'm trying to get the {smartassembly} .NET obfuscator to work with my system. I currently store user data in a series of serialized dictionary classes, and then deserialize those classes to get the data back. I'm already ignoring assembly version information, just because that way making life a pain. That code is adapted from MSDN:

//to avoid cross-versioning problems
public sealed class CrossVersionDeserializationBinder : SerializationBinder {
    public override Type BindToType(string assemblyName, string typeName) {
        Type typeToDeserialize = null;

        typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
            typeName, assemblyName));

        return typeToDeserialize;
    }
}

Problem is, now my obfuscated app will ignore versioning information, but can't read data saved by the non-obfuscated app, and vice versa. We'll need to have a non-obfuscated version in order to debug the application, so this is a pretty big showstopper for us. Any way to get around this problem? Should I just not obfuscate the data classes? That seems like a pretty large security hole.

mmr
  • 14,781
  • 29
  • 95
  • 145

2 Answers2

7

Perhaps consider a serializer that isn't tied to the type and field-names? For example, protobuf-net is a binary serializer, but uses numeric tags set (via an attribute) against each member. This means:

  • serialization isn't tied to the assembly version at all
  • the field name information isn't in the serialized file
  • (by the above) it won't matter whether the code is obfuscated
  • (and) the file can't be used to trivially break the obfuscation (although the data might still suggest intent unless encrypted)

For example:

[ProtoContract]
public class Foo {
    [ProtoMember(1)]
    public string Bar {get;set;}
}

Here, the 1 is all that identified the member in the file. The key here is that it is contract-based, so can be deserialized later with an unrelated type:

[ProtoContract]
public class a12 {
    [ProtoMember(1)]
    public string a {get;set;}
}

(which is fine since obfuscation preserves metadata, IIRC).

Contrast this to other contract-based serializers (such as XmlSerializer or DataContractSerializer) - where you would be forced to put the member-name in the attributes, which would pretty much render obfuscation pointless:

[DataContract]
public class a12 {
    [DataMember(Name="Bar")]
    public string a {get;set;}
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
-1

Obfuscation doesn't provide security in the first place. So, you may want to consider dropping it, period.

The two options I see are:

  1. Don't obfuscate those types. This will make things just work.
  2. Write your own serializer code.

Since you gain nothing by obfuscating, I'd go with #1.

MichaelGG
  • 9,976
  • 1
  • 39
  • 82
  • I need to obfuscate in order to make a dongle work, because without obfuscation, it will be easy to remove dongle calls. – mmr Feb 05 '09 at 04:05
  • Newsflash: it's gonna be real easy to remove the dongle calls even with the obfuscation. – MichaelGG Feb 05 '09 at 16:44
  • Maybe-- even with all the app-specific stuff we're going to put on the dongle. It's not meant to stop the dedicated hacker, it's meant to stop the idler who removes the key and can keep using the software. – mmr Feb 05 '09 at 16:58
  • Well, I don't know your business so maybe it's an excellent idea. But the risk of dongles for customers (dongle breaks = software dead?), coupled with the fact that only one person needs to break it... – MichaelGG Feb 05 '09 at 17:20
  • Typically, what happens is that the customer refuses to pay, and then the dongle just times out on them. Then, once they pay, we give them a functioning dongle. A savvy person with Reflector or Ildasm would just ignore the problem. – mmr Feb 05 '09 at 18:43
  • Well, like I said, I don't know your customers, etc. If that works for your company, great. It just seems interesting that you have customers smart enough to disassemble and reassemble, but not smart enough to use something like Cecil. – MichaelGG Feb 05 '09 at 18:56
  • But that's the point-- Cecil and Reflector and IlDasm are all from the same class of decompilers, and obfuscation is intended to hinder that approach. Obfuscation vendors pride themselves on breaking decompilers. – mmr Feb 05 '09 at 22:03
  • Disassemblers and metadata inspectors are not decompilers. Example: Switching Reflector into IL mode allows inspection of methods that otherwise might crash another system. Cecil also seems to tear right through everything. But hey, if it makes you happy, go for it. – MichaelGG Feb 05 '09 at 22:18