Developing Applications Using The SoftwareShield System > Anti-Hacker Guide > CRC Checking

CRC Checking


A CRC (cyclic redundancy check) is a numeric value computed from some source (file, string, digest, etc). Unlike encryption, a CRC value is always the same size regardless of the source size. A CRC is also commonly referred to as a hash or a checksum.

There are numerous sources on the internet for information on what a CRC is, so the algorithms wont be discussed in depth here.  Regardless - it may be preferable from a security standpoint for you to develop your own CRC algorithm variation based on a well-known cryptographically secure one.  (A sample program is provided to help you get started - see below).

A CRC can be used to help slow down hackers by computing a CRC checksum of some file (your EXE or a DLL) and comparing the computed value with a stored value from a known and trusted source. If any of the instructions have been changed, the CRC checksum will not match.

This can be used by your software team in a couple ways to slow down the crackers:

Trojan Server Attack

A cracker may try to replace the SSCProt.dll with a Trojan COM server with the exact same interface but whose functions always returns true values.
 
Note that if you are using IronWrapping, this attack is inviable as the SSCProt.dll is embedded and virtualized right inside the encrypted host executable.  Thus, even if there was a registered copy of the SSCProt.dll on the machine elsewhere and it was replaced with a Trojan, this attack would fail because the IronWrapped application will only ever use the embedded COM server.
 
If you are not using IronWrapping, you can use a CRC value to attempt to defeat this attack:

The basic premise is:

  1. Read from the registry the location of the DLL based on the known GUID of the COM server you want to check.
  2. If that file exists, calculate a CRC checksum on it. (Any CRC or hashing algorithm can be used - it doesn't matter).
  3. Compare the checksum calculated against your known checksum which you have previously computed on a trusted copy of the COM server. Take action depending on the match.

Perform a CRC check on the SSCProt.dll every time your program starts but before you actually use the system. Check the return value of the CRC check on the dll against a value you store inside your program. If they are not the same - the dll has been swapped, damaged or altered. To make this even more secure have the value inside the program you check against be stored in three different places, and assemble it just before you use it. A C++ example follows where, at development time, you have already run your CRC function on a trusted copy of the SSCProt.dll file and you know it should return a value of 3070908778 :

char buffer1[25] = {'\0'};
char buffer2[25] = {'\0'};
const char * val1 = "778"; // declared in a different module somewhere
const int val2 = 3070; // declared in a different module somewhere
static int val3 = 908; // maybe read from the registry where your installer wrote it.

if (CRCCheck("SSCProt.dll") != atol(strcat(strcat( itoa(val2, buffer1, 10), itoa(val3, buffer2, 10)), val1)))
{
// DefeatAttempt! - shut down.
}

CRCChecks can be quite simple to implement. We suggest that you use your own CRC to ensure that it is original, but if you would like we have included some sample code in the "Samples" directory that illustrates how you might implement this protection (VB Code Only).

Binary Instruction Replacement Attack

Note that the best way - by far - to protect your software is to use IronWrapping.  If you own the IronWrap edition, and will be using IronWrapping in your software, you should not be concerned with Binary Instruction Replacement Attacks (patches).  This is because, the protections that IronWrapping provides, when applied at maximum strength, are at least 1000 times more powerful than any technique you could implement yourself from descriptions in this section.

When you are not using IronWrapping, a cracker may simply replace the protection calls in your program to do nothing - ignoring the COM server altogether.  In fact - this is a very common attack used by most crackers.  You can use a CRC value to attempt to defeat this attack.

All 32-bit executables have a CRC checksum field in their programs PE header. You can force your compiler to generate this checksum. Then, using the Win32 API MapFileAndCheckSumA() you can get both the computed checksum and the stored one. Then simply compare them. This of course only works if the cracker doesn't change the stored one, but can sometimes be effective. There are many more sophisticated approaches to using CRCs in your program to detect the integrity of both itself and external modules (dlls) but they are beyond the scope of this help file.

You may even wish to consider computing the checksum on just a small section of the file itself instead of the whole thing - this makes the crackers job more difficult. Don't just have EXEs and DLLs check themselves, have them check each other.

We have provided a sample program that illustrates how to use the CRC technique to check the SSCProt.dll for integrity.  You can find this program (written in VB6 for ease of understanding) in the SofwareShield\samples\CRCCheckVB\ directory.  If you do not have Visual Basic, simply open the "CRCTest.frm" file in any text editor and you should be able to understand the relatively simply code and port it to your language.  The code contains aditional in-line comments which help describe the process - step-by-step.

Related Topics