Solved

Protecting programs from piracy

Posted on 1997-05-05
5
147 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

730 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