Breaking .NET Compact Framework code - how easy is it

S

Simon Hart

Hi,

I am at a point where I will be releasing my product. The only thing I am
worried about is someone cracking it (as is anyone!). It is standard .NET
Compact Framework code which contains an inbuilt licensing algorithm which
is based on the DeviceID which only we can generate.

I will be looking at tools such as Dotfuscator to try and protect someone
from dissasembling the code, does anyone have any advice to make the code
more secure, or any tips of Dotfuscator?

Also when I run my executable through ILDASM and select View/Show source
lines, when I go into any methods and properties I can see source code,
surely this should not be possible!? or am I missing something?

Cheers
Simon.
 
G

Ginny Caughey [MVP]

Simon,

I'd recommend writing your licensing routine (or some small but critical
part of it) in C++.
 
G

Ginny Caughey [MVP]

Simon,

Yes unmanaged C++. It doesn't have to be a very long function to be
effective, and you can just Pinvoke it from your managed app.
 
M

Markus Humm

Ginny said:
Simon,

Yes unmanaged C++. It doesn't have to be a very long function to be
effective, and you can just Pinvoke it from your managed app.
Oh, but what if somebody simply sort of "commented out" that p/i call?
Then the complete protection sheme would not work, would it?

Greetings

Markus
 
I

Ilya Tumanov [MS]

You're right, if native DLL just returns true or false, this would take like
30 seconds to break.

You can make things a bit more difficult by making some important stuff in
native DLL.

Say, opening and decrypting license file with has vital information in it
and returning pointer to memory block with this information which your app
uses later on.


Best regards,


Ilya

This posting is provided "AS IS" with no warranties, and confers no rights.

*** Want to find answers instantly? Here's how... ***

1. Go to
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework?hl=en
2. Type your question in the text box near "Search this group" button.
3. Hit "Search this group" button.
4. Read answer(s).
 
S

Simon Hart

I think what Ginny is saying is put the algorithm in the C++ unmanaged
module, if this call fails (commented out whatever) then the calling C#
managed code will also fail if coded correctly.

Another thing if generating a licence number not to return true or false
from the algorithm as this makes your software easier to break. Instead,
return the correct licence number then do a comparison within the C# maybe
byte by byte, or even bit by bit to make it more difficult to crack. You
could even perform some unnecessary processing during this comparison stage
to confuse the cracker.

Other people might have other tips to make the cracking process more
difficult...

Bearing in mind 33% of software today is pirate software, this issue never
gets enough attention!

Cheers
Simon.
 
G

Ginny Caughey [MVP]

Thanks, Simon and Ilya. My routines like this (which by the way I have been
using in some form for my commercial apps since the Clipper/Valkyrie days
for you old timers) don't just return true or false. You have to be a little
creative with this stuff, but only a little. ;-)
 
C

Chris Tacke, eMVP

Put you license algorithm in a separate DLL - it can be managed or
unmanaged. Add that DLL to the project as a resource. At run time, extract
it and use reflection to call the algorithm. Reflector and the like cannot
punch through that barrier as easily.

--
Chris Tacke
Co-founder
OpenNETCF.org
Are you using the SDF? Let's do a case study.
Email us at d c s @ o p e n n e t c f . c o m
http://www.opennetcf.org/donate
 
N

n33470

At the risk of sounding naive, is this even a valid concern? If the
assemblies have been strong named, should that alone prevent the issue
of running a "tampered" assembly? I thought that was the whole point
of strong naming....to prevent running "hacked" assemblies.

As far as running ILDASM to look at source code, yes you can do that.
If viewing source code is a concern of yours, then use an obfuscator to
scramble the code before you release the app to production. The
downside of obfuscation, is that you cannot log a "readable" stack
trace in any error logs that you create.

Curious what your thoughts are on the strong naming issue.

--steve
 
G

Ginny Caughey [MVP]

steve,

If you use a tool like Reflector, you can sometimes get back source code
from an assembly that's good enough to recompile and run. For most apps this
really doesn't matter, but for a licensing routine you might want to prevent
this to prevent piracy. When you build a fort, you have to know what type of
enemy you're trying to keep out. With a lot of apps the most likely "enemy"
would be the end user who wouldn't be interested in decompiling and
recompiling your app and reselling it to others, but with some apps ...
 
N

n33470

Ginny,

I understand that you can get back source code and recompile it. My
point is that with the combination of obfuscation and strong naming of
assemblies (both of which can be defered until just before deployment)
aren't you in good enough shape against probably 99% of the hackers.

My feeling is that if you're a hacker that wants to take obfuscated
code and redesign it to hack out the licensing algorigthm....then I say
more power to you. This is no easy feat, but I will concede that it
can be done if you're diligent. I must admit that I've never tried
unassemble obfuscated code and actually read it, so maybe it's simpler
to understand than I give credit for.

I appreciate your thoughts and experience on this. I'd like to know if
I'm oversimplifying the situation.

Thanks!

--steve
 
S

Simon Hart

I have been thinking about this further. I know strong naming assemblies
should prevent a "hacked" version from running - strong nameing assemblies
should be common practice anyway. But lets say you are using a tool such as
Reflector (where can I get Reflector btw? - to test my own code) you are
able to decompile the assembly to source code successfully. In this case it
doesn't matter where you put the algorithm - whether its managed/unmanged or
embedded as a resource etc. All the cracker has to do is alter the condition
on return from the algorithm call to always pass regardless of the result.

So it seems the most effective way to stop pirate copies of your software is
to ensure it cannot be decompiled.

Cheers
Simon.
 
G

Ginny Caughey [MVP]

steve,

I don't think you're oversimplifying, but the result you get would depend on
the particular obfuscator. I think anybody who is concerned with that level
of security (and I definitely agree that for most situations it's not an
issue) should try to disassemble the obfuscator's output and then see if the
result is good enough.
 
S

Simon Hart

Ginny,

Thanks for that link I managed to google it after I asked...

Wow, that Reflector is quite amazing and worring!! I am using the DES
encryption algorithm to generate licence numbers. What I did find though
interestingly, that nor ILDASM and Reflector can decompile my IV and Key
bytes values as I declare these static fields as :

public static byte[] key_byte = Encoding.ASCII.GetBytes("mykey");

public static byte[] IV_byte = Encoding.ASCII.GetBytes("abcdefgh");



I guess is a good thing as it makes my code a little bit more secure.

Cheers

Simon.
 
N

n33470

Simon,

Now take that same assembly, run it through obfuscation and then look
at it in Reflector. Even if you use the VS built-in obfuscactor
(Tools/Dotfuscator Community Edition) you should see that the code is
very difficult to understand as it replaces all method and variable
names with a, b, c, etc.

Try it out, and then you make the call whether this technique is good
enough for you.

--steve

Simon said:
Ginny,

Thanks for that link I managed to google it after I asked...

Wow, that Reflector is quite amazing and worring!! I am using the DES
encryption algorithm to generate licence numbers. What I did find though
interestingly, that nor ILDASM and Reflector can decompile my IV and Key
bytes values as I declare these static fields as :

public static byte[] key_byte = Encoding.ASCII.GetBytes("mykey");

public static byte[] IV_byte = Encoding.ASCII.GetBytes("abcdefgh");



I guess is a good thing as it makes my code a little bit more secure.

Cheers

Simon.

Ginny Caughey said:
 
C

Chris Tacke, eMVP

Yep, and without the ability to pre-copmpile your binaries like on the
desktop, there's really no way around it. Obfuscation makes it less
obvious, and if you add an extra calling layer to everything it can be
pretty effective against casual hackers. Protection from a dedicated hacker
is probably not worth the time you'd spend.

--
Chris Tacke
Co-founder
OpenNETCF.org
Are you using the SDF? Let's do a case study.
Email us at d c s @ o p e n n e t c f . c o m
http://www.opennetcf.org/donate


Simon Hart said:
Ginny,

Thanks for that link I managed to google it after I asked...

Wow, that Reflector is quite amazing and worring!! I am using the DES
encryption algorithm to generate licence numbers. What I did find though
interestingly, that nor ILDASM and Reflector can decompile my IV and Key
bytes values as I declare these static fields as :

public static byte[] key_byte = Encoding.ASCII.GetBytes("mykey");

public static byte[] IV_byte = Encoding.ASCII.GetBytes("abcdefgh");



I guess is a good thing as it makes my code a little bit more secure.

Cheers

Simon.

Ginny Caughey said:
 
S

Simon Hart

Steve,

Yes I used Dotfuscator and this is definitely good enough for me, it
certainly makes it very difficult to break.

I tried using Dotfuscator but when deploying my EXE to my device it no
longer starts when I tap it. Any ideas or hvae you experienced this?

Cheers
Simon.

n33470 said:
Simon,

Now take that same assembly, run it through obfuscation and then look
at it in Reflector. Even if you use the VS built-in obfuscactor
(Tools/Dotfuscator Community Edition) you should see that the code is
very difficult to understand as it replaces all method and variable
names with a, b, c, etc.

Try it out, and then you make the call whether this technique is good
enough for you.

--steve

Simon said:
Ginny,

Thanks for that link I managed to google it after I asked...

Wow, that Reflector is quite amazing and worring!! I am using the DES
encryption algorithm to generate licence numbers. What I did find though
interestingly, that nor ILDASM and Reflector can decompile my IV and Key
bytes values as I declare these static fields as :

public static byte[] key_byte = Encoding.ASCII.GetBytes("mykey");

public static byte[] IV_byte = Encoding.ASCII.GetBytes("abcdefgh");



I guess is a good thing as it makes my code a little bit more secure.

Cheers

Simon.

message
Simon,

Here's Reflector: http://www.aisto.com/roeder/dotnet/

--
Ginny Caughey
.NET Compact Framework MVP


I have been thinking about this further. I know strong naming
assemblies
should prevent a "hacked" version from running - strong nameing
assemblies
should be common practice anyway. But lets say you are using a tool
such
as Reflector (where can I get Reflector btw? - to test my own code) you
are able to decompile the assembly to source code successfully. In this
case it doesn't matter where you put the algorithm - whether its
managed/unmanged or embedded as a resource etc. All the cracker has to
do
is alter the condition on return from the algorithm call to always pass
regardless of the result.

So it seems the most effective way to stop pirate copies of your
software
is to ensure it cannot be decompiled.

Cheers
Simon.

At the risk of sounding naive, is this even a valid concern? If the
assemblies have been strong named, should that alone prevent the
issue
of running a "tampered" assembly? I thought that was the whole
point
of strong naming....to prevent running "hacked" assemblies.

As far as running ILDASM to look at source code, yes you can do that.
If viewing source code is a concern of yours, then use an obfuscator
to
scramble the code before you release the app to production. The
downside of obfuscation, is that you cannot log a "readable" stack
trace in any error logs that you create.

Curious what your thoughts are on the strong naming issue.

--steve
 
S

Simon Hart

I have found if strong naming my assembly the obfuscated assembly will not
load. When removing the strong named key, it worked like a gem on the
device.

The exe is around 30k smaller too.

Cheers
Simon.

Simon Hart said:
Steve,

Yes I used Dotfuscator and this is definitely good enough for me, it
certainly makes it very difficult to break.

I tried using Dotfuscator but when deploying my EXE to my device it no
longer starts when I tap it. Any ideas or hvae you experienced this?

Cheers
Simon.

n33470 said:
Simon,

Now take that same assembly, run it through obfuscation and then look
at it in Reflector. Even if you use the VS built-in obfuscactor
(Tools/Dotfuscator Community Edition) you should see that the code is
very difficult to understand as it replaces all method and variable
names with a, b, c, etc.

Try it out, and then you make the call whether this technique is good
enough for you.

--steve

Simon said:
Ginny,

Thanks for that link I managed to google it after I asked...

Wow, that Reflector is quite amazing and worring!! I am using the DES
encryption algorithm to generate licence numbers. What I did find though
interestingly, that nor ILDASM and Reflector can decompile my IV and Key
bytes values as I declare these static fields as :

public static byte[] key_byte = Encoding.ASCII.GetBytes("mykey");

public static byte[] IV_byte = Encoding.ASCII.GetBytes("abcdefgh");



I guess is a good thing as it makes my code a little bit more secure.

Cheers

Simon.

message
Simon,

Here's Reflector: http://www.aisto.com/roeder/dotnet/

--
Ginny Caughey
.NET Compact Framework MVP


I have been thinking about this further. I know strong naming
assemblies
should prevent a "hacked" version from running - strong nameing
assemblies
should be common practice anyway. But lets say you are using a tool
such
as Reflector (where can I get Reflector btw? - to test my own code)
you
are able to decompile the assembly to source code successfully. In
this
case it doesn't matter where you put the algorithm - whether its
managed/unmanged or embedded as a resource etc. All the cracker has to
do
is alter the condition on return from the algorithm call to always
pass
regardless of the result.

So it seems the most effective way to stop pirate copies of your
software
is to ensure it cannot be decompiled.

Cheers
Simon.

At the risk of sounding naive, is this even a valid concern? If the
assemblies have been strong named, should that alone prevent the
issue
of running a "tampered" assembly? I thought that was the whole
point
of strong naming....to prevent running "hacked" assemblies.

As far as running ILDASM to look at source code, yes you can do
that.
If viewing source code is a concern of yours, then use an obfuscator
to
scramble the code before you release the app to production. The
downside of obfuscation, is that you cannot log a "readable" stack
trace in any error logs that you create.

Curious what your thoughts are on the strong naming issue.

--steve
 

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