Developing Applications Using The SoftwareShield System > Anti-Hacker Guide > Anti-Hacker Standard Practices

Anti-Hacker Standard Practices


There are two specific areas of interest to you as a developer using the SoftwareShield System.

  1. What can you, as a developer, do to make you implementation of SoftwareShield licensing as secure as possible?
  2. What can you, as a developer, do on an ongoing basis, in order to make your software as secure as possible?

Anti-hacker standard practices are just that - standard. They should not be limited solely to your implementation of the SoftwareShield System and the code around it. So, in fact, the two concerns above are one and the same. Below are several simple "tricks" you should consider, that when used together, will force crackers trying to defeat your system to invest incrementally more time in doing so. When used in conjunction with the SoftwareShield System, their job will be unpleasant to say the least. Please be sure you understand that the purpose of playing the "game" is an impasse. (see: Anti-Hacker Guide).

Here are several standard things you should do in any software you wish to protect to slow down crackers:

  1. Never give any registration or protection testing function a self describing name. Never use a function name like "IsActivated". Crackers will quickly locate these names (in most high level languages) and simply remove or rewrite them.
  2. Use return values from the ClientProtector somehow in your processing of a standard program function. This can be particularly effective to slow down crackers. You might implement this by using a pre-set parameter value inside one of the Authorization Definitions as an XOR "key" to be used with a stored value in your binary. When you XOR them together, it produces a value that must be used by (for example) the "save" or "print" function. If the value is not computed correctly, your program will not save or print correctly. Don't put up an error message if the value isn't correct, instead, simply make the programs output incorrect. It can be difficult for a cracker to detect this, regardless of whether he can even determine if this is simply an error or a protection.
  3. Avoid unnecessary error messages. If your program gives an error message after an unsuccessful activation attempt, the crackers will be able to quickly locate the error message and know that at some point in the call stack immediately before it - a protection or activation-test function call failed.
  4. Wait using a timer in a separate thread to provide error messages. When an error message is unavoidable, you may wish to set a timer in a separate thread that will fire several seconds or minutes later to warn the user and take action. This makes tracing back to the protection call that caused the timer to start up more difficult and will slow the cracker down.
  5. Encrypt any and all protection strings. When an error message in unavoidable, be sure to dynamically generate the message string itself. The best way to do this is to store it in encrypted form in the binary and decrypt only immediately before you need it. This makes searching for the string very difficult. Better yet - encrypt all your programs strings.
  6. Use random tests for activation. Test that the program is correctly activated at random time intervals; hours, days or even weeks after it was first installed and run. Possibly test only after certain key functions (unrelated to activation) are used. This will often be missed by crackers and again will slow them down or make their crack worthless.
  7. Don't start the activation test for several seconds (or even minutes) after the activation. This applies to a few different scenarios where the ClientProtector is not solely responsible for activation. IE: Where your program interprets the value of parameters or it must inspect activation of individual Authorization Definitions. Alternatively, you may wish to store any Activation Codes input by the user temporarily in memory and after a brief pause try to activate them using the ClientProtector interface. You may even wish to require the user to restart the program before you input the value. This makes it difficult to trace and will slow the cracker down.
  8. Use CRC checksums in your application and dlls. Be sure you have read the CRC Checking section for more information. Have your EXEs check themselves, check other DLLs, or even have them check each other. Consider computing a checksum on just a small section of the file itself instead of the whole thing - this makes the crackers job more difficult.
  9. Use Anti-Debugging tricks. Be sure you have read the Anti-Debugging section for more information on how to slow down crackers by having your software resist debuggers.
  10. Use Anti-Disassembling tricks. Be sure you have read the Anti-Disassembling section for more information on how to slow down crackers by having your software resist disassembling.
  11. Use more activation checking routines than the minimum necessary. You should test in several places, and in places where the crackers might not expect it. Check at random time intervals too (see above). One routine requires a time investment from the cracker to remove, then more routines will require even more time to break.
  12. Use Honey Pots. A "Honey Pot" is a fake or decoy routine (or set of routines) you code into your program that seem to check activation, but in fact - does nothing. Have it write and read registry keys, manipulate files, jump all over in memory computing useless values and doing meaningless comparisons. Use your imagination here. Name honey pots to draw the crackers attention (like "CheckReg"). The point is to waste their time with a ruse.
  13. Wrap Activation testing routines in ridiculously long code. Consider using several long procedures which do a huge amount of unnecessary (but seemingly meaningful) processing. At some point during this useless processing, legitimately check the activation. Consider even checking it two or three times in different ways. This make the crackers job of tracing through this giant jumble of assembly looking for the "real" code a more frustrating experience. This will slow them down. Your testing routines can safely take 5 to 20 seconds to execute on a reasonably fast machine.
  14. If you use a demo version of your software with limited features, make sure you don't have "grayed out" buttons or menu options. A cracker can simply change the enabled property of these controls which will effectively make your features visible again. It is always preferable to dynamically create these controls only when they are available.
  15. If you use a demo version of your software with limited features, consider not distributing the actual binary code to execute those functions. The simplest way to do this is to include the "paid version only code" inside a DLL which is called from your program when it is legitimately purchased. Then when a customer purchases your software, give them an Activation Code to release your SoftwareShield protections as well as the required DLL containing the code for the missing features.
  16. If your program has been cracked, release a new version. This is probably the most important principle which makes all the above tricks worth while. Once you have wasted the crackers time as much as possible, slowing them down with all these tricks (and others you may think up yourself), you must immediately make all their hard work go to waste - release a new version fast. Change a few things around, re-organize the code, update the version number, test - and re-release. The cracker will have to start all over again. Reaction time is important too. Expect to move quickly if a crack is released. Try and release a new version as rapidly as possible to maximize the frustration effect.
 
Related Topics