Copy protection for a .NET application

M

Massimo

I'm planning to develop a .NET application using C#, in order to sell it as
a shareware and/or as a full package, so I'll need a good way to protect it
against piracy. I know some ways to protect it (activation, serial keys,
etc.), but my concern is: how can any copy protection mechanism work when
you can always disassemble it and read the source code? Even if I use a
native C++ DLL for my copy protection, the point where it's called from the
C# code can always be found.
Any good tips about this?

Thanks


Massimo
 
J

Jon Skeet [C# MVP]

Massimo said:
I'm planning to develop a .NET application using C#, in order to sell it as
a shareware and/or as a full package, so I'll need a good way to protect it
against piracy. I know some ways to protect it (activation, serial keys,
etc.), but my concern is: how can any copy protection mechanism work when
you can always disassemble it and read the source code? Even if I use a
native C++ DLL for my copy protection, the point where it's called from the
C# code can always be found.
Any good tips about this?

Yes - don't worry. Obfuscate your code if you particularly want to, but
I wouldn't bother going any further than that unless you're *really*
sure that:

a) There'll be lots of demand for pirate copies
b) There'll be technically competent people who are willing to spend
time decompiling your obfuscated code
 
M

Michael Giagnocavo [MVP]

You can check into obfuscating. But depending on the obfuscator, that might
not buy you much. Getting thru obfuscated code can be simple:
http://www.atrevido.net/blog/PermaLink.aspx?guid=8315fa01-0286-47ce-a20b-fcc15eb297c3

The real way is to use a tool that does a lot more than just simple naming
obfuscation (say, type obfuscation as well, call obfuscation), encrypts your
assembly, and then, write really messed up code for the critical part. For
instance, you might try some tricks to fake your stack trace, use multiple
threads, etc. in the "serial checking" part.

Also remember, if there's demand, people will get through and crack your
app. Even MS Window's activation has been cracked (and the Windows
programmers are extremely intelligent).
 
W

William Stacey [MVP]

Very true. Just some random thoughts. I got to the point where all the fancy
stuff is a waste of time if your protecting against code modification or
round-tripping. You can use threads, jumps, or Egyptian carrier pigeons to
confuse, but it normally all comes down to one single "if" statement to
continue. This is one way to even get around RSA...just walk around it.
You can obfuscate to help keep logic and secrets hidden so they ~can't
generate external key gens or repro your license stuff, but if they will mod
the code, then none of that really matters. So your really protecting again
those that don't/can't mod the code - the others you can't really stop (not
even with smartcards, strong names, etc.). Most of your protections will be
in a single constructor, so not too hard to drill in on that. In this case
obfuscation still helps a bit as it makes it harder to figure out where/what
to mod the code(hopefully). Some obfuscators also help prevent ildasm to
raise the bar even farther.
 
M

Massimo

Very true. Just some random thoughts. I got to the point where all the
fancy
stuff is a waste of time if your protecting against code modification or
round-tripping. You can use threads, jumps, or Egyptian carrier pigeons
to
confuse, but it normally all comes down to one single "if" statement to
continue.

That's exactly my point of view on the subject.
So, in a higly disassemblable environment such a .NET (or Java, for that
matter), isn't there any way to really protect applications against piracy?

Massimo
 
J

Jon Skeet [C# MVP]

Massimo said:
That's exactly my point of view on the subject.
So, in a higly disassemblable environment such a .NET (or Java, for that
matter), isn't there any way to really protect applications against piracy?

Well, there's protection and there's protection. There's no foolproof
way of protecting software whether it's Java or native code. You can
make things harder by using an obfuscator, but if the code is going to
run on a user's box, that user can (with appropriate skill) work out
what it's doing.

Usually, however, the concept behind a piece of software (which is
plainly visible anyway) is more important than the implementation, IMO.
 
R

Robby

You can skip MSIL and compile directly to machine code if you want. In
fact, you can obfuscate and then compile to machine code for double
protection. You don't have to release your program in MSIL. However, if
you do go straight to machine code then you will loose the cross platform
benefits of MSIL. That means you will have to complie separate assembiles
for PC, MAC and so on.

-Robby
 
M

Massimo

Usually, however, the concept behind a piece of software (which is
plainly visible anyway) is more important than the implementation, IMO.

I agree on this, but I'm not talking about protecting intellectual rights
(i.e. algorithms), but the software itself, which can be easily copied.

Massimo
 
M

Massimo

You can skip MSIL and compile directly to machine code if you want. In
fact, you can obfuscate and then compile to machine code for double
protection. You don't have to release your program in MSIL. However, if
you do go straight to machine code then you will loose the cross platform
benefits of MSIL. That means you will have to complie separate assembiles
for PC, MAC and so on.

Didn't know about this; how can I generate machine code? I was talking about
a Windows application here.

Massimo
 
J

Jon Skeet [C# MVP]

Massimo said:
I agree on this, but I'm not talking about protecting intellectual rights
(i.e. algorithms), but the software itself, which can be easily copied.

And native code can fairly easily be copied too - look how much effort
the games industry is constantly putting into making games as hard to
crack as possible.
 
J

Jon Skeet [C# MVP]

Massimo said:
Didn't know about this; how can I generate machine code? I was talking about
a Windows application here.

See http://www.pobox.com/~skeet/csharp/faq/#framework.required

I can't say I'd recommend going that route though - while I haven't
used the products in question, the .NET framework will clearly have
gone through a lot more testing (especially if you include the
"testing" which all of us are doing every time we run some .NET code)
than the linkers. I'd certainly recommend that if you take that route,
you do it early on and do as much of your development and testing using
the product as possible, largely ignoring the normal framework. That
may well end up costing a lot in terms of ease of development, of
course...
 
R

Robby

Using the NGEN utility is not ignoring the .Net Framework. It is a part of
the .Net Framework. Machine code compiled assembiles still need the .Net
Framework installed to run. You should not make grossly incorrect
statements like that.

Robby
 
M

Massimo

And native code can fairly easily be copied too - look how much effort
the games industry is constantly putting into making games as hard to
crack as possible.

Yes, I know this, and in fact I'm quite unsure about native code safety,
too. But IL is definitely *a lot* simpler to understand, when disassembled.

Massimo
 
J

Jon Skeet [C# MVP]

Massimo said:
Yes, I know this, and in fact I'm quite unsure about native code safety,
too. But IL is definitely *a lot* simpler to understand, when disassembled.

Have you tried decompiling a real application of significant size,
after it's been obfuscated? It takes a fair amount of skill and
patience to understand it.
 
J

Jon Skeet [C# MVP]

Robby said:
Using the NGEN utility is not ignoring the .Net Framework. It is a part of
the .Net Framework. Machine code compiled assembiles still need the .Net
Framework installed to run. You should not make grossly incorrect
statements like that.

I think you should be careful about the fact before accusing others of
making grossly incorrect statements:

1) NGENed assemblies still require the original IL, so don't help in
the slightest.
2) If you'd followed the link I provided, you'd see that the products I
was referring to *don't* require the .NET framework to be installed
- they include everything that's required. I wasn't talking about
NGEN, as it doesn't accomplish the desired goal.

Of course, if you don't believe me about the first point, you'd
presumably be happy to send me an NGENed executable which you believe
doesn't contain any IL. If you can do so, *then* I'll apologise for
making a grossly incorrect statement.
 
R

Robby

Well, I was talking about NGEN so your statements are incorrect. NGEN
assemblies do not require you to distribute MSIL.

Robby
 
J

Jon Skeet [C# MVP]

Robby said:
Well, I was talking about NGEN so your statements are incorrect.

You may have been talking about NGEN, but you didn't specify that. My
statements concerned the products I referred to, and were correct in
that context. I answered a question from Massimo, and all my statements
in that answer were correct.
NGEN assemblies do not require you to distribute MSIL.

So I should expect an executable (compiled from C# source) in my inbox
which doesn't have any IL in pretty soon, right? I'll be very surprised
if you can produce one (using ngen).

Just out of interest, I NGENed a small test executable, copied the
native file out of the GAC, and tried to run it directly. No dice. You
need the assembly containing the IL in order to get the framework to
use the native image in the GAC.

There *may* be ways of removing the IL from the original assembly after
NGENing it, but in a way that fools the framework into using the image
from GAC - but I haven't seen anyone writing about that, and you'd need
fairly deep knowledge of exactly how the GAC works to try it out. (If
the framework checks the hash of the assembly against the original, for
instance, you're in trouble unless you can also change the hash that's
stored in the native code file.)

I'm off to bed now, but I'll be fascinated to see that executable
(along with exact details of how you produced it) in the morning...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top