Demystifying my Nagware Scheme

In my post The Protection Racket, I referred to a “copy-protection” scheme used for years in my command-line emailer MailSend in the late 90’s.

While it really didn’t prevent making copies of the trial version, it served as a reminder to procrastinators that they should register the product.  I later used the same technique in MailWrench, MailSend’s successor.

Now that both MailSend and MailWrench are free, open source products, I thought that I should divulge the relatively simple Windows technique I used to limit the number of executions to around 15 before requiring a log-off or reboot.

The Windows API has a function called GlobalAddAtom(char *str) which creates a unique global hash-code for the supplied string.  When a program terminates, any atoms that it has added globally persist through the life of that Windows session.

A counterpart function GlobalFindAtom(char *str) returns the atom that had already been created if it had existed.  Under the non-NT 32-bit implementations of Windows ( Win95, when I wrote the original code ) GlobalFindAtom() would return a zero or negative-one ( I don’t remember which ).  However, Windows NT 4.0 seemed to return something other than what the Win95 family had returned.  Here’s the TAWK ( compiled AWK ) code that I used to implement the nagware check:

extern winapi int GlobalFindAtom(char*);
extern winapi int GlobalAddAtom(char*);
function checkitout() {
   for(i=37;i<=51;i++) {
      x="MSND_JKL__"  i;
      if( GlobalFindAtom(x) == GlobalFindAtom("MSND_NAMTAB") ) {
   if( i>=51) {
      # display nag message here

The first couple of lines declare the external WIN32 API function references for TAWK. The function checkitout() implements the persistent 15-execution counter.

The code iterates from 37 to 51 ( 15 iterations ). Creating the strings “MSND_JKL_37”, “MSND_JKL_38”, … “MSND_JKL_51”.  To check for a missing atom, I had to check to see if a GlobalFindAtom() called with one of the iterated “MSND_JKL_…” strings matched the GlobalFindAtom() for a nonsense string.  In this case, I used “MSND_NAMTAB” as the string I’d have bet would not exist. ( “MSND_” as MailSend’s prefix and “NAMTAB” was “Batman” spelled backwards … something I didn’t think any other process would use as the source string for an atom ).

The above comparison was the only way I was able to reliably determine if an atom was missing that worked in both the Win95 family and the WinNT family of OS’s.

If the atom did not exist, the code would add the atom and would then return from the function cleanly.  If the function iterated through all of the strings and found all of the atoms, that meant that 15 attempts had been made to use the software.  The code would then display a nagware message and would terminate the process with a call to exit(). I had also encrypted the nagware message so that it wouldn’t be too easy for anyone trying to bypass the scheme to find.

I had wondered whether this approach was a good idea.  Forcing the user to log off or reboot seemed extreme, but I never got any complaints.  I did receive contacts from people saying that they could not properly evaluate the product with such a restriction, so I sent them the fully-registered product on the honor system.  Most of them ended up registering.

I’d never been sure if someone had sidestepped that particular portion of the protection scheme.  Because I used a compiler that didn’t generate native C/C++ code, I think the techies may have had a reverse-engineering bag of tricks that was limited in use.  There were cracks for the software that removed three lines in the text of each email that indicated the software was a trial version.

I had thought that because I used .NET managed code that the scheme would be discovered and sidestepped in my MailWrench product, even though I obfuscated the bulk of the symbol names just before compiling the sources.  I just don’t think the market was big enough for MailWrench that it attracted the attention of the reverse-engineering crowd.


About Jim Lawless

I've been programming computers for about 36 years ... 30 of that professionally. I've been a teacher, I've worked as a consultant, and have written articles here and there for publications like Dr. Dobbs Journal, The C/C++ Users Journal, Nuts and Volts, and others.
This entry was posted in Technology. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s