Solved

Protecting programs from piracy

Posted on 1997-05-05
5
143 Views
Last Modified: 2010-04-06
How can I get the hard disk's serial number in order to protect my program from running elsewhere that in that particular hard disk ?
0
Comment
Question by:sime
  • 3
5 Comments
 
LVL 1

Accepted Solution

by:
jackb022197 earned 50 total points
ID: 1335929
See the unit below...

unit SerNum;

Interface

uses WinProcs, WinTypes;

function GetSerialNumber (drive: Byte): LongInt;
function SetSerialNumber (drive: Byte; serNum: LongInt): Bool;

Implementation

type
    PMIDINFO = ^MIDINFO;
    MIDINFO = record
                  InfoLevel:  Word;
                  SerialNum:  Longint;
                  VolLabel:   array[0..10] of Char;
                  FileSystem: array [0..7] of Char;
              end;

var
    R: record     { Real mode call structure }
           di, si, bp, Reserved, bx, dx, cx, ax : Longint;
           Flags, es, ds, fs, gs, ip, sp, ss: Word;
       end;

{----------------------------------------------------------------------------}
{    Name:    GetSetMid                                                      }
{    Purpose: Low level code to get or set a MIDINFO data structure for the  }
{             specified drive.  RealModeAX = $6900 for a get and $6901 for a }
{             set operation.                                                 }
{----------------------------------------------------------------------------}

function GetSetMid (Drive: Byte; MID: PMIDINFO; RealModeAX: Word): Bool;
var
    Error: Byte;
begin
    { Assume everything ok }

    Error := 0;
    GetSetMid := True;

    R.ax := RealModeAX;
    R.bx := Drive;
    R.ds := HiWord (Longint (MID));              { Subtle !!! }
    R.dx := LoWord (Longint (MID));

    asm
        mov bx, 0021h     { set flags to $00, Real mode interrupt $21 }
        xor cx, cx        { copy 0 words from protected mode stack }
        mov ax, seg R
        mov es, ax        { selector of real mode call structure }
        mov di, offset R  { offset of real mode call structure }
        mov ax, 0300h     { DPMI simulate real mode interrupt }
        int 31h           { do the business }
        jnc @@1           { branch if no error }
        inc Error
    @@1:
    end;

    if Error = 1 then GetSetMid := False;
end;

{----------------------------------------------------------------------------}
{    Name:    GetMid                                                         }
{    Purpose: Get the MIDINFO record for a specified drive.                  }
{             Uses GetSetMid.  Returns TRUE if successful.                   }
{----------------------------------------------------------------------------}

function GetMid (drive: Byte; var mid: MIDINFO): Bool;
var
    p: LongInt;
begin
    { Assume failure }
    GetMid := False;

    { Allocate a MIDINFO data structure in DOS address-space }
    p := GlobalDOSAlloc (sizeof (MIDINFO));

    if GetSetMid (drive, Ptr (HiWord (p), 0), $6900) then
    begin
        mid := PMIDINFO (Ptr (LoWord (p), 0))^;
        GetMid := True;
    end;

    GlobalDOSFree (LoWord (p));
end;

{----------------------------------------------------------------------------}
{    Name:    SetMid                                                         }
{    Purpose: Set the MIDINFO record for a specified drive.                  }
{             Uses GetSetMid.  Returns TRUE if successful.                   }
{----------------------------------------------------------------------------}

function SetMid (drive: Byte; var mid: MIDINFO): Bool;
var
    p: LongInt;
begin
    { Assume failure }
    SetMid := False;

    { Allocate a MIDINFO data structure in DOS address-space }
    p := GlobalDOSAlloc (sizeof (MIDINFO));
    PMIDINFO (Ptr (LoWord (p), 0))^ := mid;
    if GetSetMid (drive, Ptr (HiWord (p), 0), $6901) then SetMid := True;
    GlobalDOSFree (LoWord (p));
end;

{----------------------------------------------------------------------------}
{    Name:    GetSerialNumber                                                }
{    Purpose: Get the serial number for a specified drive.                   }
{             If an error occurs, then 0 is returned as the serial number.   }
{----------------------------------------------------------------------------}

function GetSerialNumber (drive: Byte): LongInt;
var
    mid: MIDINFO;
begin
    if GetMid (drive, mid) then GetSerialNumber := mid.SerialNum
    else GetSerialNumber := 0;
end;

{----------------------------------------------------------------------------}
{    Name:    SetSerialNumber                                                }
{    Purpose: Set the serial number for a specified drive.                   }
{             If no error, TRUE is returned as the function result.          }
{----------------------------------------------------------------------------}

function SetSerialNumber (drive: Byte; serNum: LongInt): Bool;
var
    mid: MIDINFO;
begin
    SetSerialNumber := False;
    if GetMid (drive, mid) then
    begin
        mid.SerialNum := serNum;
        SetSerialNumber := SetMid (drive, mid);
    end;
end;

end.
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335930
If you can set the serial number...what would prevent some
other program from doing the same thing, thus rendering
your program inoperable...thus pissing off your customer??

Reading drive serial numbers is just a bad idea.  Think about
it?  If it was a good idea, every major piece of software
would be doing it.

Also, what's to stop someone from just pirating your setup
disk??  Your setup doesn't know, ahead of time, the serial
number of the drive it is going to be installed to.
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335931
What kind of software are you writing that you think it will
be so rampantly pirated?

If you are writing shareware or something, a better bet might
be to just supply demos that are time-stamped and will not
allows installs after an initial one has expired.

If you want some tips on how to do this effectively, I can
supply as an answer if you don't like the answer already given.
0
 
LVL 2

Expert Comment

by:javiertb
ID: 1335932
And what if you change the system date? You could still be using the program.
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335933
I've already taken into account changing the system date...
system date changes are a really simple problem to solve.

The simplest, though not the only solution, is to hard code
a date into your program that it cannot run before.  If
you created your program July 1996...you certainly would
not allow it to run with a system date of June 1996 or earlier.

There are a lot of other little things that you can do to
make it extremely difficult for anyone to try and circumvent
time-stamping.  It will always be possible to circumvent,
but if you make it a pain in the ass to do so, most folks will
stop bothering to try.

And you always have human error to rely on...the moment someone
forgets to set back the clock and run your program, it'll
make it very difficult for them to re-run it once it has
expired.
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Reconfigure Delphi Install? 2 51
Performance of SQL statement 37 111
Firemonkey webbrowser scrollbars ? 1 40
Slow Restore if incremental backups using RDiff.exe 4 20
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question