anti-cracking library 1.0

ACLib implementation tutorial
In this article, I will show you the basic ACLib implementation principles. You will need intermediate knowledge of Delphi and Windows programming to understand it.

1. Designing a software protection

If you are making a protection for your software, you have to think like a cracker. This means, how would YOU bypass the protection. It's not possible to make an uncrackable application - you have to make an application, which is really hard to crack. Make lots of checks if serial is correct, use lots of debugger detection algorithms and make them independent from each other. Call them from everywhere - crackers hate it.

2. The tutorial

Let's make a simple protected application. I will use a demo shipped with Delphi 7: "SWAT" (you will probably know it from good old Borland Pascal 7). At first, we will create a file called "defines.inc" and type there:
{$DEFINE ANTICRACK}
{$DEFINE RELEASE}
This file will be included ({$I defines.inc}) by every PAS file containing the protection. By using these switches, you will be able to enable and disable the protection, because it would be annoying to see a "Debugger detected" message, when YOU are debugging it.
Let's now look at project's source (from Delphi menu: Project -> View Source). At first, add an include of Defines.inc and use of ACLib.pas. Next step will be easy: type somewhere before Application.Run this:
  {$IFDEF RELEASE}
  if SICE_Detect_CreateFile or Debugger_Detect_API then
  begin
    MessageBox(GetDesktopWindow,'No debuggers, please!',
      'Debugger detected',MB_ICONINFORMATION);
    exit;
  end;

  if DeDe_Detect_EnumWindows then
     Crash_App_AccessViolation;
  {$ENDIF}
If you try to run SWAT now, it will show you: "No debuggers, please!" and exit. Undefine RELEASE in defines.inc and we can continue. You can now close Swat.dpr, we will move to Main.pas (so add ACLib to Uses list and include defines.inc). Create an initialization section and write there this:
  {$IFDEF ANTICRACK}
  Detect_FrogsICE_Kill;
  if SICE_Detect_Int1 or SICE_Detect_Int68h then
     Crash_App_VMMCall;
  {$ENDIF}
This should be enough of this kind of protection. It is easy to remove it, because it makes direct action i.e. looks for SoftICE and if found, crashes the application. Better is to merge protection to your program - to make the whole program dependant on ACLib and his routines. This is a little bit harder, but if you want to make a well-protected application, you can spend a few hours designing your protection scheme.
Now is the time to make a serial verification algorithm. I will make just a silly one, because I will teach you how to do them in next part of tutorial. Don't even try to use this kind of serial verification in your projects - it's definitely not safe! Here it goes:
function GenerateSerial(Name: string):string;
var i: integer;
    serial, x: integer;
begin
  Serial:=0;
  for i:=1 to Length(Name) do
  begin
    Serial:=(Serial shl 4) + Ord(Name[i]);
    x:=Serial and $F0000000;
    if x<>0 then
       Serial:=Serial xor (x shr 24);
    Serial:=Serial and (not x);
  end;
  Result:=Format('%x',[Serial]);
end;
The correct serial for this algorithm is for example:
Name: migeel
Serial: 73FDBBC

Now is the time to check, if the game is registered. We will store the registration information in registry, in key HKCU\Software\migeel\SWAT. Because we read from registry, it is a good idea to check if any monitor (like RegMon) is installed. We will use main form's OnCreate.
  if not(Monitors_Detect_FindWindow or Monitors_Detect_FindDriver) then
  begin
    with TRegistry.Create do
    begin
      OpenKey('Software\migeel\SWAT',false);
      if ValueExists('UserName') then
         UserName:=ReadString('UserName');
      if ValueExists('UserKey') then
         UserKey:=ReadString('UserKey');
    end;
  end;
 
Next we move to Options.pas. Limitation of the demo version will be the game time - limited to 10 seconds. So let's move to OKBtnClick procedure:
  if aclGetText(GameTimeSet.Handle)<>'100' then
  begin
    if Main.GenerateSerial(Main.UserName)=Main.UserKey then
       SwatForm.GameTime := StrToInt(GameTimeSet.Text)
    else
        MessageBox(Handle,'You can''t change game time in demo version.',
          'Shareware',MB_ICONINFORMATION);
  end;
Now some anticracking protection again. We have to check, if the file isn't modified. Let's use PeChecksum functions from ACLib (TOptionsDlg.FormShow):
  Head:=GetImageNTHeaders;
  {$IFDEF RELEASE}
  if PECheckSum_ACLib(ParamStr(0))<>Head.FileHeader.TimeDateStamp then
     close;
  {$ENDIF}
This will compare checksum of running exe with checksum stored in file (in FileHeader.TimeDateStamp). If they aren't equal, dialog will be closed.
The last thing we need to do is a registration dialog. It is a good idea to hide it and tell users where to find it only when they register. We will hide it in Options dialog. Let's create a new PageControl, put the Options controls in it and make a new tab for the registration. The registration part will appear only when you press Shift and click the Cancel button. So let's make CancelBtnClick procedure:
  if ((GetAsyncKeyState(VK_SHIFT) and $8000)=$8000) then
     PageControl1.ActivePage:=TabSheet2
  else
      close;
Now implement registration routines and you are finished. Now enable RELEASE define, compile the project and update PEChecksums with Checksum.exe (in Utils directory).
You have learnt the basic concepts of using ACLib. Still, you have to study ACLib reference to learn how to use all benefits of ACLib. If you don't understand something, start your web browser, type "www.google.com" and use it. The world of cracking is very big. Every day, there are new tricks, but if you take some time, you can make a pretty tough protection.