Copy protection for a .NET application

M

Massimo

Thanks Rinze. Was not trying to be flippant with response. I assume your
talking license management here. If something else, please expand. To
have
context here, lets assume we are talking license check as that is what
site
mainly talks about. And your right, we probably can't crack the device or
internal structures. However, I still don't need to. Pretend we call an
IsValid() method in the hardlock. It does and does its thing with
checking
keys, decrypting, xyz, etc. That is fine and good. But now, my main code
at some point need to check some reply from the hardlock to see if that
was
valid or license failure. So my code my look like this (could be
anything)
:

private void MainForm_Load(object sender, System.EventArgs e)
{
bool valid = HardLock.IsValid(); // HardLock goes and does its
magic.
if ( ! valid )
MessageBox.Show("Thank you for using our software. Please
obtain a valid license at xyz.com.");
}

So I can still bypass your HardLock all together with a mod to the code.

I think he was talking about encrypting a DLL using some key stored inside a
dongle/smart card/whatever. That way, nobody could even access the code
without the key, so no patching could actually crack this system.
Howewer, a lot of copy protections from games take exactly this approach
(enrypting the main executable using data stored in the CD-ROM subchannel),
and no one of them has been cracked, but the games are still being copied...
by distributing a copy of the decrypted executable along with them.

Massimo
 
C

C-Services Holland b.v.

You don't seem to understand the crypting process.

quote: "Pretend we call an IsValid() method in the hardlock."

That is where you go wrong, in my code I don't even have to check for
the presence of the hardlock. The entire executable/dll is crypted with
a 128bit encryption method. It needs the hardlock to first decrypt the
code then run it. Code similar to what you showed is nowhere to be found
in my software. I'll describe the process:

1. I create and compile program just like any other
2. attach the customers hardlock with a specific module address
3. attach our company specific crypt lock
4. run the compiled program through a crypt program that crypts the
executable with the customers hardlock
5. burn it on CD and ship it and the hardlock to the customer

Now the executable/dll has changed alot. Aside from the encryption, it
is encapsulated in a software envelope that will automatically decrypt
it when needed. The envelope doesn't simply check if the hardlock is
available, it NEEDS it to be there to even be able to decrypt the
machine code and run it.

Think of PGP. PGP encrypt your program. Can you run it? No. Can you go
in there, change 1 bit and have you then defeated the PGP encryption?
No. You need to decrypt the program first before you can use it. The
hardlock does this on the fly, but all the while it obfuscates it
behaviour making it very hard for anyone with special software (like
WinIce) to see what is going on.

You can use it like you described, but that would defeat the purpose of
having one simply because it can be broken like you showed. But proper
use of the hardlock makes it very very hard to break.
 
W

William Stacey [MVP]

I gotta now. I see what they are doing. I would never spend time on it,
but from a discussion standpoint, I still wonder how much better that is
then encrypting the dll yourself and encrypting the key in the loader or
something. I think under both (hardlock and self encrypted dll) you have
some key used for decryption into memory and/or disk. Naturally, one could
use "corddb myapp.exe" to find the plain key passed to Rijndael (et al) for
decryption and just use that to manually decrypt the dlls. That is an
additional step that takes most folks out-of-the-game. But your not really
protecting from them. Your really protecting from the crackers that live
inside debuggers and read asm like the morning paper just to publish a crack
or keygen to their buddies on the INET.
Still sounds interesting, but don't think majority would ever buy sw that
requires dongles (as history shows us.) Also not sure how much better this
is (in reality) then decrypting and loading your own dll in a loader?

Just curious, now that we spent time on this, what kind of application are
your protecting? Thanks for your patience and helping me understand.
Cheers.
 
G

Guest

Have you considered Protector from Remotesoft.com?
It "completely stops MSIL disassembly and decompilation"
Mike Marsh

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

Robby
 
C

C-Services Holland b.v.

William said:
I gotta now. I see what they are doing. I would never spend time on it,
but from a discussion standpoint, I still wonder how much better that is
then encrypting the dll yourself and encrypting the key in the loader or
something. I think under both (hardlock and self encrypted dll) you have
some key used for decryption into memory and/or disk. Naturally, one could
use "corddb myapp.exe" to find the plain key passed to Rijndael (et al) for
decryption and just use that to manually decrypt the dlls. That is an
additional step that takes most folks out-of-the-game. But your not really
protecting from them. Your really protecting from the crackers that live
inside debuggers and read asm like the morning paper just to publish a crack
or keygen to their buddies on the INET.
Still sounds interesting, but don't think majority would ever buy sw that
requires dongles (as history shows us.) Also not sure how much better this
is (in reality) then decrypting and loading your own dll in a loader?

Just curious, now that we spent time on this, what kind of application are
your protecting? Thanks for your patience and helping me understand.
Cheers.

The problem with decrypting the code yourself is that you have a readily
accessable decryption module in your software to decrypt the DLL. That
would make it a breeze for any decent cracker to break your protection.

We have engineering software for factories and such where very simply
put they store every connection (power/signal lines etc) and instrument
and what not in a database. It's a very expensive piece of software.

One of our other leading products is software for calculating
powercables to conform to the Dutch NEN norm. That ranges from wiring in
your home to streetlighting. Our main concern in the early days was
decompilation protection (VB4, easily decompiled to vb source). So we
used the hardlock encryption to stop people getting at our math modules.
These days it's a bit harder, but we still use it for licencing purposes
so we can control how many copies can be started at one time,
serverlocks are available so they can just plug it onto a Novell or
Windows server for instance.

Now I agree with you that for most software packages this solution is
way to expensive. The hardlock itself costs about as much as the average
game. But the same company also provides a software solution
(http://www.ealaddin.com/HASPSL/default.asp) which may be much more
interesting to more developers since it doesn't require a piece of
hardware and this distribution via the web is so much easier. How secure
that is, I can't say. But I do know the hardlock encryption is very
tough to crack.

In the end, any protection can be broken. I think our software is too
specific to be interesting enough for any hacking group to spend it's
efforts on, so we (our company that is) are reasonably safe.
 
G

Guest

Hi,

I'm working with C# now for the last months and just discovered that
obfuscating is not enough. My sourcecode is not considered safe anymore
because it can now be easily decoded with products like Remotesoft's software.

How can I protect myself? An answer could be using the protector software
from Remotesoftware but how sure can I be that this is also not breakable.
What is the technique used by Protector and is it considered safe?

Is it possible in anyway to link my assemblies into native code without
having to include my IL code. Even obfuscating IL code is not really safe
because the algorithm is 'easily' breakable.

Anyone?

mmarsh said:
Have you considered Protector from Remotesoft.com?
It "completely stops MSIL disassembly and decompilation"
Mike Marsh
 
C

Christian Gudrian

Massimo said:
Find that statement, and you crack the program...

But if the assembly is signed it will fail to load when patched. Or has
the framework already been hacked in a way that prevents signed
assemblies from getting verified?

Christian
 
J

Jon Skeet [C# MVP]

Marco van Nieuwenhoven said:
I'm working with C# now for the last months and just discovered that
obfuscating is not enough. My sourcecode is not considered safe anymore
because it can now be easily decoded with products like Remotesoft's software.

But can it actually be *understood*?
How can I protect myself? An answer could be using the protector software
from Remotesoftware but how sure can I be that this is also not breakable.
What is the technique used by Protector and is it considered safe?

You'd have to ask RemoteSoft.
Is it possible in anyway to link my assemblies into native code without
having to include my IL code. Even obfuscating IL code is not really safe
because the algorithm is 'easily' breakable.

Yes - follow the links I posted before. However, people will still be
able to decompile your code. It'll take a bit longer, but it's far from
impossible.
 
J

Jon Skeet [C# MVP]

Christian Gudrian said:
But if the assembly is signed it will fail to load when patched. Or has
the framework already been hacked in a way that prevents signed
assemblies from getting verified?

So when you patch the assembly, you don't sign it - or anything that
relies on it. You remove anything which demands that the assembly is
signed - it's not hard to do.
 
G

Guest

Jon Skeet said:
But can it actually be *understood*?

I think the code can still be understood because the calls to the .net
framework are still understood and there you can fiddle out the function of a
function :) When getting a message of a customer that a crash has occurred
this will also cause you a problem as well. You will then not be able to
understand what went wrong.
You'd have to ask RemoteSoft.

I don't think I will get a clean answer from them because this will give
away a big hint on how to hack their tool. A disadvantage of their solution
is also that the solution is: *BeginQuote* This method is not compatible
across .NET Framework Service packs. For example EXE files created using .NET
Framework Service Initial Release do not work with installations of Service
Pack 2. Because many users may
have different installations of the framework installed, this solution
becomes useful only in very controlled environments - but usually in these
environments protection is not strongly needed. *EndQuote*
This is why I am looking for a solution which does not include the IL code
inside an executable. This will make it more difficult to hack. x86 code is
more difficult to read than IL (obfuscated or not)
Yes - follow the links I posted before. However, people will still be
able to decompile your code. It'll take a bit longer, but it's far from
impossible.

I may be a fool but I could not find the reference you told me of. I could
only find the qoute from below. This does confuse me.
 
J

Jon Skeet [C# MVP]

Marco van Nieuwenhoven said:
I think the code can still be understood because the calls to the .net
framework are still understood and there you can fiddle out the function of a
function :)

You can see what it does, but actual semantic meaning is a lot harder
to understand without any reasonable names. Try decompiling any large
obfuscated app and see how easy it is to understand.
When getting a message of a customer that a crash has occurred
this will also cause you a problem as well. You will then not be able to
understand what went wrong.

Most obfuscators build a map so that you can get back from an
obfuscated stack trace to a nicely named one (with the map).
I don't think I will get a clean answer from them because this will give
away a big hint on how to hack their tool. A disadvantage of their solution
is also that the solution is: *BeginQuote* This method is not compatible
across .NET Framework Service packs. For example EXE files created using .NET
Framework Service Initial Release do not work with installations of Service
Pack 2. Because many users may
have different installations of the framework installed, this solution
becomes useful only in very controlled environments - but usually in these
environments protection is not strongly needed. *EndQuote*
This is why I am looking for a solution which does not include the IL code
inside an executable. This will make it more difficult to hack. x86 code is
more difficult to read than IL (obfuscated or not)

Yes, it's more difficult to read. Not impossible though.
I may be a fool but I could not find the reference you told me of. I could
only find the qoute from below. This does confuse me.

The link was
http://www.yoda.arachsys.com/csharp/faq/#framework.required - there are
links there to linkers which produce native code.

I'd ignore that if I were you - that was trying to understand how Robby
thought you could use an NGENed image without the original assembly. I
assume from his silence on the topic that he's now accepted that you
can't do it...
 
W

William Stacey [MVP]

Are you talking hacking/cracking or getting the code posted at the code
project? They are different.
Actually, cracking is just as simple on x86 code as it is with IL. That is
because crackers live in debuggers and asm anyway. From that perspective
obfuscated IL is harder for them as you add obfuscation and is different
then what they are used to. So you will be able hack any app that lives on
a w/r medium. But can you understand it is the other another problem and
the one you want to control as well as possible. I really like Xeno code.
Is a fair price and works really well. With conservitive settings and
control flow obfus, and ILDasm breaking turned on is great. Can not use std
ILdasm to round trip, can not understand from Reflector or others and can
not reverse it. Saying "can not" is misleading. As everything is
possible - right? I mean you would eventually find your RSA private key
with a brute force attack too. So how hard is it is the key. Even with a
good obfuscator you have to balance protection level as if you do to much
you start breaking things. You still need to test whole app again after
obfuscation which is a big problem with the idea in general.
 
W

William Stacey [MVP]

The problem with decrypting the code yourself is that you have a readily
accessable decryption module in your software to decrypt the DLL. That
would make it a breeze for any decent cracker to break your protection.

True. But you have equal access to the either code in memory using a
debugger. So it does raise the bar, but not too high for crackers. They
use debugger anyway (after ildasm fails), so it is not much difference for
them.
We have engineering software for factories and such where very simply
put they store every connection (power/signal lines etc) and instrument
and what not in a database. It's a very expensive piece of software.

Sounds interesting. Hope yall do well with it.
Now I agree with you that for most software packages this solution is
way to expensive. The hardlock itself costs about as much as the average
game. But the same company also provides a software solution
(http://www.ealaddin.com/HASPSL/default.asp) which may be much more
interesting to more developers since it doesn't require a piece of
hardware and this distribution via the web is so much easier. How secure
that is, I can't say. But I do know the hardlock encryption is very
tough to crack.

Thanks for the link. Thanks for the talk. Cheers.
 
C

C-Services Holland b.v.

William said:
True. But you have equal access to the either code in memory using a
debugger. So it does raise the bar, but not too high for crackers. They
use debugger anyway (after ildasm fails), so it is not much difference for
them.

Not really. The decrypting part is in the hardlock, unaccessable by
debuggers :) From the tech docs I've read, they also employ
anti-debugging techniques to prevent on the fly inspection of things
going on.

But as I said. Nothing is impossible to crack, it's just how much time
and effort is one willing to spend.
 
W

William Stacey [MVP]

I read the docs. They talk about things like "Protective Shields" and
"Train Cars" a lot. But when you wade past the marketing fluff, it is an
RSA key store plain and simple. It stores private keys and can take an
encrypted string (encrypted with public key) and decrypt it. Here is the
basic process from what I read:
1) Encrypt exe, or dll with 128-bit Rijndael using random Secret and IV and
store. Done at developers station.
2) Encrypt the secret and IV with the public key. Save the cipher text and
public key with the cipher dll from Step 1.
3) One and 2 are the "package". Other transforms and/or "magic"
splitting/blocking/train-car may be done.
4) Create the wrapper/loader around the cipher "package" and distribute
that.

When app starts:
1) Loader *.exe that is called by user.
2) Loader first checks that the HardLock(HL) is present with a ping msg. If
not, return failure.
3) Loader loads "package" and extracts cipher Secret and IV and sends to HL.
4) HL decrypts the string(s) using private RSA key stored in the lock.
5) HL returns *clear secret and IV to caller. This is the potential weak
link in the procedure.
6) Loader decrypts "package" in memory using Rijndael keys.
7) Loader can call an entry point to start the app.
8) Loader may also use a timer thread to periodically check the HL is always
there with some ping msg - or exit if not.
9) Loader has some magic to tell if a debugger is running. Not sure about
validity of this statement or what is possible here.

So basically it uses Rijndael and RSA key pairs to encrypt the Rijndael keys
like you would do in normal digital envelope. But the RSA private key is
stored in the lock. Like all crypto, it comes down to protecting the keys
and to use the resulting clear text for only a very short time and remove it
from memory. Here is where it comes back to the same problem we all have -
protecting the clear text in memory. The driver api call to decrypt the rj
keys *has to return clear text to init Rijndael with - just has to be done.
If I can get the key, the HL is not much use anymore as I can run Rijndael
myself with the known key and iv. The various "mixing" they also do would
slow you down a bit more. The "crashing debugger" part is the most
interesting I think. If they can do that in a fool proof way, then they
really have something there. But they don't talk about the tech here other
then marking points. I don't know enough about it to say either way. If
they can't stop debuggers, then it would not be that much harder to crack
then a sw only solution.

Actually I have done all the same things in a sw-only license solution with
digital envelopes and ran into same issues. It all comes down to protecting
that darn key - the rest is not so important. Wonder if a USB sniffer would
show the returned clear text rj keys? Cheers.
 
G

Guest

Well, I think at last someone else told, what I intended... Do not use
something like this:

Sub Main()
If DoSomethingOnCard = True Then
' Go on with program
Else
' Drop to sharewaremode
End if
End sub


What I offer is like this:

Sub DoSomething
Dim d as deciaml as CalculateOnCardTheDecimalValue()
' use d variable in the program here...
end Sub

So, if the card is not acailable, the value of "d" is wrong... (Maybe
correct, but how can you know?)

So, if the card is unavailable you can't be sure of the value of d here...

If you can find out how d is calculated, well, you already are a candidate
for nobel...
(assuming d is calculated on the smartcard, through an application with RSA
or PKI security.

Please tell me a "cheap" way of calculating the value of d here...

Note, if you are writing Windows XP of higher, it's definite that many
people with many computing power and knowledge will attack you.

If your program is an interest program for milk producers, well, write a
good program and sell them all your customers.

William Stacey said:
True. Or you just resign it yourself if you want. A common misperseption
is that SNs are a security enabler as apposed to a way to uniquely identify
assemblies (which they are for.) A good doc by a MS guy is at:
http://www.codeproject.com/dotnet/StrongNameExplained.asp

Michael has some good text and SNReplace code here:
http://www.atrevido.net/blog/CategoryView.aspx?category=Code

Cheers.
 
W

William Stacey [MVP]

Sub DoSomething
Dim d as deciaml as CalculateOnCardTheDecimalValue()
' use d variable in the program here...
end Sub

So, if the card is not acailable, the value of "d" is wrong... (Maybe
correct, but how can you know?)

Thanks. Not sure what your showing here Salih. Somewhere latter in your
program, you need a test to figure out if d is good or bad. If d is a key,
then you know d. What am I missing? TIA
 
G

Guest

Hello, William,

Here are two questions for you:
1. you have definetely no access to th code that is encsrypted, because it
is stored in a flash memory of the smartcard, which is also immune to
physical investigation of data under Electron Scanning Microscope.
2. nobody, even the developer doesn't know the private key to encrypt and to
run the code required.
Remember, the code "doesn't" run on th CPU of the target machine, but on
another place.

So,

1. How can you attach a debugger to a process that doesn't run on the same
context?
2. Hawill you reveal a private key, that's known by just one party.

Hey, if you can answer thece questions with working snippets, please let me
know... As a result I can just flush all the money in your bank there...

By the way, the differences with CD way, that the games use:

1. With CD, you can read any data you want with a raw reader.
2. CD doesn't have a CPU in order to run some code on it...

TIA,

Salih

BTW,
I'm definite about the breaking into an RSA crypted executable located on
another CPU... If anyone can do it, he/she's a billionnaire now...


William Stacey said:
I read the docs. They talk about things like "Protective Shields" and
"Train Cars" a lot. But when you wade past the marketing fluff, it is an
RSA key store plain and simple. It stores private keys and can take an
encrypted string (encrypted with public key) and decrypt it. Here is the
basic process from what I read:
1) Encrypt exe, or dll with 128-bit Rijndael using random Secret and IV and
store. Done at developers station.
2) Encrypt the secret and IV with the public key. Save the cipher text and
public key with the cipher dll from Step 1.
3) One and 2 are the "package". Other transforms and/or "magic"
splitting/blocking/train-car may be done.
4) Create the wrapper/loader around the cipher "package" and distribute
that.

When app starts:
1) Loader *.exe that is called by user.
2) Loader first checks that the HardLock(HL) is present with a ping msg. If
not, return failure.
3) Loader loads "package" and extracts cipher Secret and IV and sends to HL.
4) HL decrypts the string(s) using private RSA key stored in the lock.
5) HL returns *clear secret and IV to caller. This is the potential weak
link in the procedure.
6) Loader decrypts "package" in memory using Rijndael keys.
7) Loader can call an entry point to start the app.
8) Loader may also use a timer thread to periodically check the HL is always
there with some ping msg - or exit if not.
9) Loader has some magic to tell if a debugger is running. Not sure about
validity of this statement or what is possible here.

So basically it uses Rijndael and RSA key pairs to encrypt the Rijndael keys
like you would do in normal digital envelope. But the RSA private key is
stored in the lock. Like all crypto, it comes down to protecting the keys
and to use the resulting clear text for only a very short time and remove it
from memory. Here is where it comes back to the same problem we all have -
protecting the clear text in memory. The driver api call to decrypt the rj
keys *has to return clear text to init Rijndael with - just has to be done.
If I can get the key, the HL is not much use anymore as I can run Rijndael
myself with the known key and iv. The various "mixing" they also do would
slow you down a bit more. The "crashing debugger" part is the most
interesting I think. If they can do that in a fool proof way, then they
really have something there. But they don't talk about the tech here other
then marking points. I don't know enough about it to say either way. If
they can't stop debuggers, then it would not be that much harder to crack
then a sw only solution.

Actually I have done all the same things in a sw-only license solution with
digital envelopes and ran into same issues. It all comes down to protecting
that darn key - the rest is not so important. Wonder if a USB sniffer would
show the returned clear text rj keys? Cheers.
 
G

Guest

d is not the key.
Assume that you're writing a program that calculates the interest values for
some data...

Assume that *only* the card *knows* how to calculate it.

It is still possible to crack this program, but you must *know* how this
interest is calculated. And assume that the algorithm that calculates this
value is the main part of your program.

So, your program running in Windows context doesn't know how to calculate
this value for any variable. If you want any calculation on any variable, you
use the smart card.

BTW, smart cards are really smart with 33 MHz dedicated MPU's that do not
deal with any UI but only raw calculations. I have heard of faster MPU's for
smartcards but I myself didn't check them live yet...

Is it clear enough?

Salih
 

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