Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Controlling Demo-Version Crack and Software Piracy Issue for Beginners - Part 1

1.60/5 (2 votes)
20 Aug 2011CPOL4 min read 27.1K   394  
This article has been written for small individual developers who really face demo crack problem before launching their application.

Introduction

In the earlier version of this article, I did not provide the source code for implementing the said strategy. I am going to update this article with the required source code lines and hope this will explain my concepts more clearly. Readers who have already been through the earlier version of this article can jump directly to the updated part under header “To accomplish our target, take the following 2 steps:

A well organized IT company has their strategy makers for controlling software piracy and crack issues, but for beginner and individual developers it is really a painful issue.

Application demo is used for the purpose of publicity and usually a registration option provided with it for upgradation to full version. The registration is accomplished after providing a license-key by customer against an auto-generated license code.

This is the weakest point where if the license-key got cracked, the demo-version can easily be converted to full-version and control of developer’s harvest slips into another’s hands.

Approaches Used to Control Piracy

  • Attaching a dongle (hardware) to software
  • Provide a license key for registration against license code

In general, license key option is used for this purpose. So the issue is to make an attempt at piracy control at demo-version level and the strategy is to completely isolate demo from the full-version of application.

There are many points which are taken under consideration while making demo-version for an application. Let's take a snapshot of them:

  1. A finite-days expiration period is provided for the demo. If customer doesn’t register within this period, the demo expires.
  2. Instead of complete application, only partial features of application are kept in action. Only after registration, the customer can avail the full features of application.
  3. For registration, a license key has to be provided by the customer against auto-generated license code.

So, the application registration is the point where maximum crack risk resides.

To overcome this situation, the following strategies may be adopted:

  1. Demo means demo, no provision to upgrade to full version to be provided.
  2. Out of full version, an isolated portion of demo to be ripped-off with only partial features with finite expiration period.
  3. An additional feature has to be added, i.e., finite number of re-installations of demo version on each system and each installation with finite days expiration. After completion of finite installations, the demo should not be re-installed unless and until system gets formatted.

For achieving the third point, a separate console application can be used to create a file that holds installation date and installations counter value.

The installation counter shall be incremented by +1 for each time demo gets re-installed and installation date should remain fixed to be used for demo expiration calculation.

Deceiving Crackers

We should attempt to use multiple strategies for keeping the above file contents out of reach of malicious minds. Some suggestions are as follows:

  1. Installation date and installation counter may be kept in separate files.
  2. Multiple special folders, SystemRoot and Registry can be used to keep these files/contents separately.

    For example special folder “ApplicationData” path can be obtained by:

    String appDataPath = Environment.GetFolderPath
    			( Environment.SpecialFolder.ApplicationData)

    And SystemRoot path can be obtained by:

    String SysRtPath = Environment.GetEnvironmentVariable("SystemRoot"); 
  3. Always store installation date in random format while storing to file which shall be recompiled to proper format whenever our code needs it. Garbage data may also be included with date for creating confusion.
  4. An encryption strategy can be adopted for data protection.

To accomplish our target, take the following two steps:

Step 1

A console application can be used to create files for holding installation date and re-installation counter information. This console application shall be attached to demo’s setup as primary output and to be executed at the time of installation on client machine to store this information of client system.

For example, if we want to execute this file on clicking Register button while installation, set said console application’s primary output in executable property of Register user dialog of User interface editor in setup.

Note that the below source code uses SystemRoot folder and Registry to store our potential data files. Though the help provided with the source code is self explanatory, yet the main functionality of the source code is as below:

  • An install counter with limited installations information in “SystemRoot” folder along with controlling number of installations limit.
  • Updating installation date for each incremental installation.
  • Information to be stored in a “Registry subkey”.
  • Some garbage information also inserted for confusing the crackers which can be edited by programmers as required.

Source Code Sample

C#
//  Demdsthlp file
  using System;
  using  System.Collections.Generic;
  using  System.Text;
  using  Microsoft.Win32;
  using System.IO;

namespace  Demdthlp
  {
  class Program
  {
  RegistryKey  rk, rgsk;
  int d,  m, y;
  string  revdt, Dtfor_SysRt;
  string  syrtdtflpth;

  Program()
  {
  syrtdtflpth = Environment.GetEnvironmentVariable("SystemRoot");
  d = 0; m = 0; y = 0; revdt = "MPAD";
  }

  // Date formatting and making a string to store in Registry key  
  // and SystemRoot folder
  private  void md_instdt()
  {
  string  dd_num = "0";
  string  mm_num = "0";
  DateTime  dt = DateTime.Now;
  d = dt.Day;
  m = dt.Month;
  y = dt.Year;

  if  (d < 10)
  dd_num += d.ToString().Trim();
  else
  dd_num = d.ToString().Trim();

  if  (m < 10)
  mm_num += m.ToString().Trim();
  else
  mm_num = m.ToString().Trim();

  string strdt  = dd_num + mm_num + Convert.ToString(y).Trim();

  Dtfor_SysRt = strdt;

  for  (int i = 0; i < 8; i++)
  revdt += strdt.Substring(7 - i,  1);
  revdt += "NORKREV1602"; // Garbage info as strategy required
  }

  // Making a Fake Registry for above said purpose
  private void ed_rgy()
  {
  rk = Registry.CurrentUser;
  rk.DeleteSubKey("Software\\abcDem", false);
  rgsk = rk.OpenSubKey("Software", true);

  try
  {
  RegistryKey  newrk = rgsk.CreateSubKey("abcDem");
  newrk.SetValue("adem",  revdt.ToString().Trim(), RegistryValueKind.String);
  }
  catch  (Exception s)
  {
  Console.WriteLine(s.Message);
  }
  }

  // Creating  file in SystemRoot Folder
  private  void ed_sysrt()
  {
  syrtdtflpth += "\\demdt.dtd";
  if  (File.Exists(syrtdtflpth))
  {
  //  Check install counter in file
  string  insCounter = RetuInstalCounter(syrtdtflpth);
  int  ncount = int.Parse(insCounter);

  //  Counter ==5 , don't update installation date so that demo can't be renewed
  if  (ncount >= 5)
  {
  Console.WriteLine("Sorry, Your Demo Trials Limit is Over.");
  Console.ReadLine();
  return;
  }
  else
  {
  //  otherwise increase install counter by +1
  ncount++; string strcount = "";
  strcount = ncount.ToString().Trim();
  Dtfor_SysRt += strcount;
  try  { File.Delete(syrtdtflpth); }   // than delete  installation date file
  catch  { }

  //  and recreate new file with fresh date
  StreamWriter  fsInstDtFile =
  new  StreamWriter(new  FileStream(syrtdtflpth,
  FileMode.Create,
  FileAccess.Write));
  fsInstDtFile.Write(Dtfor_SysRt);
  fsInstDtFile.Close();
  }
  }
  else
  {
  // If  file doesn't exist, set install counter to 1 at 9th letter position, 
  // and add to  file
  Dtfor_SysRt += "1";
  //  Now write to file
  StreamWriter  fsInstDtFile =
  new  StreamWriter(
  new FileStream
  (syrtdtflpth,
  FileMode.Create,
  FileAccess.Write));
  fsInstDtFile.Write(Dtfor_SysRt);
  fsInstDtFile.Close();
  }
  }

  private  string RetuInstalCounter(string syrtdtflpth)
  {
  StreamReader  fsInstDtFile =
  new  StreamReader(new  FileStream(syrtdtflpth,
  FileMode.Open,
  FileAccess.Read));
  string  instdtAndCounter = fsInstDtFile.ReadToEnd();
  fsInstDtFile.Close();

  // now  ripoff install counter
  string  inscount = instdtAndCounter.Substring(8, 1);
  return  inscount;
  }

  static void Main(string[]  args)
  {
  Program  p = new Program();
  p.md_instdt();
  p.ed_rgy();
  p.ed_sysrt();
  }
  }
  }

Step 2

A special verification code that has to be executed very first should be attached to our main executable file of application. After demo-version installation, every time application runs, this code verifies the expiration date.

The source code below first reads information stored from file stored in SystemRoot folder and completes the following steps:

  • Verifies system date and calculates lapsed days
  • Evaluates the expiration

Source Code Sample

C#
  //  MainForm.cs
  //  This form shall be used in Main Project’s program.cs file
  using System;
  using  System.Collections.Generic;
  using  System.ComponentModel;
  using  System.Data;
  using  System.Drawing;
  using  System.Text;
  using  System.Windows.Forms;
  using System.IO;
  using  Microsoft.Win32;
  using  System.Globalization;

namespace Terminator
  {
  public partial class MainForm : Form
  {
  string  SysRtDtFilePath;

  public  MainForm()
  {
  InitializeComponent();
  SysRtDtFilePath = Environment.GetEnvironmentVariable("SystemRoot");
  }

  private  void MainForm_Load(object  sender, EventArgs e)
  {
  SysRtDtFilePath += "\\demdt.dtd";
  if  (File.Exists(SysRtDtFilePath))
  {
  try
  {
  StreamReader  fsInstDtFile =
  new StreamReader(new FileStream(SysRtDtFilePath,
  FileMode.Open,
  FileAccess.Read));
  string  instdt = fsInstDtFile.ReadToEnd();

  if  (String.IsNullOrEmpty(instdt) == false)
  doEvaluation(instdt);
  fsInstDtFile.Close();
  }
  catch
  {
  MessageBox.Show("File Read or system date format error", "Information",
  MessageBoxButtons.OK, MessageBoxIcon.Error);
  }
  }
  else
  {
  MessageBox.Show("Either evaluation period expired or file manually  corrupted.",
  "Information",  MessageBoxButtons.OK, MessageBoxIcon.Information);
  }
  }

  private  void doEvaluation(string  insdt)
  {
  string  rightdt = insdt.Trim();
  string  dy = rightdt.Substring(0, 2);
  string  mon = rightdt.Substring(2, 2);
  string  yr = rightdt.Substring(4, 4);

  // First  make installation date string:
  string  mdt = dy + "/" + mon + "/" + yr; //  +" " + "12:00:00";
  DateTime  curdt = DateTime.Today;

  IFormatProvider  culture = new CultureInfo("fr-FR", true);
  DateTime  Finstdt =
  DateTime.Parse(mdt,  culture, DateTimeStyles.NoCurrentDateDefault);

  if  (curdt < Finstdt)
  {
  label4.Text = "Invalid System date";
  MessageBox.Show("Invalid System date", "Information",
  MessageBoxButtons.OK,  MessageBoxIcon.Information);
  Application.Exit();
  }

  DateTime  maxdt = Finstdt.AddDays(2);

  TimeSpan  diffs = maxdt - curdt; // get days lapsed
  int  d = diffs.Days;

  if  (d < 0)
  {
  label4.Text = "nil";
  MessageBox.Show("Your evaluation period has been expired
  or not  Activated." + "\n" +
  "This  trial version is only for Demo purposes.
  To freely use Data Theft controller  (Demo) software" + "\n"  +
  "created  by ABC Technologies, 
  you need to purchase this Software from ABC Technologies.");
  Application.Exit();
  }
  else
  {
  label4.Text =  d.ToString().Trim() + " days left";
  btnStart.Visible = true;
  }
  }

  private  void btnStart_Click(object  sender, EventArgs e)
  {
  Form  fm = new Form1();  // First page of our application
  this.Hide();  // hide main form
  fm.ShowDialog(this);
  }

  private  void btnCancel_Click(object  sender, EventArgs e)
  {
  this.Close();
  }
  }
  }

Now add the following lines of code to Program.cs file of our main application:

C#
namespace Terminator
  {
  static class Program
  {
  // my global  variables
  public static string  strPwdFilePath =
  Environment.GetEnvironmentVariable("SystemRoot");
  public static bool  isPwdEnabled = false;

  [STAThread]
  static void Main()
  {
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new MainForm());
  }
  } 

Summary

Once again, I want to repeat that this article provides just basic knowledge to beginners for protecting their application. Strategies can be more complicated and competitive at their level.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)