protecting an app for illigal copying

User avatar
plantenkennis
Posts: 151
Joined: Wed Nov 25, 2015 7:13 pm
Location: the Netherlands
Contact:

protecting an app for illigal copying

Post by plantenkennis »

Hello Antonio,

I want to protect my app from illigal copying/distibuting. In Windows I use the serial number of the harddisk where the app is installed on. This serial number is a 8 numbers HEX string like 'AE23 12BF'. In my app I calcutates with this string so users can only install the app on one disk, depending on a key I give them.

I have looked in Apple developers for such functionallity, but the harddisk number seems not to be a save way. However, every Mac has a unique MAC-adres which I can use to protect my app. Here is a explanation:
https://developer.apple.com/library/con ... index.html

Is it possible for you to make a function that retrieves the MAC adres of a computer? Someting like 'cMacAdres:= GetMacAdres()'. With this string I can protect my app with a registration key that I store in a .plist
On the next page is a sample code, hope this can be build in.
https://developer.apple.com/library/con ... Intro.html

René
Kind regards,

René Koot
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

We have other possibilities here:

http://stackoverflow.com/questions/6775 ... -an-iphone

reviewing them
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

This one is also interesting:

http://forums.macrumors.com/threads/how ... de.689645/

Code: Select all

NSPipe *outPipe = [NSPipe pipe];
NSTask* theTask = [[NSTask alloc] init];
NSString *string;
NSString *s;
//Built-in ethernet
[theTask setStandardOutput:outPipe];
[theTask setStandardError:outPipe];
[theTask setLaunchPath:@"/sbin/ifconfig"];
[theTask setCurrentDirectoryPath:@"~/"];
[theTask setArguments:[NSArray arrayWithObjects:@"en0", nil]];
[theTask launch];
[theTask waitUntilExit];

string = [[NSString alloc] initWithData:[[outPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding];

if (![string isEqualToString:@"ifconfig: interface en0 does not exist"]) {
    s = string;
    NSRange f;
    f = [s rangeOfString:@"ether "];
    if (f.location != NSNotFound) {
        s = [s substringFromIndex:f.location + f.length];
        
        string = [s substringWithRange:NSMakeRange(0, 17)];
    }
    [ethernet setStringValue:string];
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

one more:

http://www.cocoabuilder.com/archive/coc ... dress.html

Code: Select all

void getEthernetAddress()
{
    InetInterfaceInfo    myInetInterfaceInfo;
    int i, adaptorInterface;

    NSLog(@"Ethernet addresses: ");

    adaptorInterface=0;
    do {
        OTInetGetInterfaceInfo(&myInetInterfaceInfo, adaptorInterface);
        if (myInetInterfaceInfo.fHWAddrLen > 0) {
            for(i=0; i<myInetInterfaceInfo.fHWAddrLen; i++) {
                printf("%02x ",myInetInterfaceInfo.fHWAddr[i]);
            }
            printf("\n");
        }
        adaptorInterface++;
    }
    while (myInetInterfaceInfo.fHWAddrLen > 0);
}
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

This one is working nicely :-)

I send you the new FiveMac libs by email

Code: Select all

HB_FUNC( GETMACADDRESS )
{
   NSPipe *outPipe = [NSPipe pipe];
   NSTask* theTask = [[NSTask alloc] init];
   NSString *string;
   NSString *s;
   //Built-in ethernet
   [theTask setStandardOutput:outPipe];
   [theTask setStandardError:outPipe];
   [theTask setLaunchPath:@"/sbin/ifconfig"];
   [theTask setCurrentDirectoryPath:@"~/"];
   [theTask setArguments:[NSArray arrayWithObjects:@"en0", nil]];
   [theTask launch];
   [theTask waitUntilExit];

   string = [[NSString alloc] initWithData:[[outPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding];

   if (![string isEqualToString:@"ifconfig: interface en0 does not exist"]) 
   {
      s = string;
      NSRange f;
      f = [s rangeOfString:@"ether "];
      if( f.location != NSNotFound) 
      {
        s = [s substringFromIndex:f.location + f.length];
        
        string = [s substringWithRange:NSMakeRange(0, 17)];
      }
   }

   hb_retc( [ string cStringUsingEncoding : NSWindowsCP1252StringEncoding ] ); 
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

Already sent :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: protecting an app for illigal copying

Post by mastintin »

Antonio Añadida Funcion que devuelve el numero de serie de la maquina . Cada mac tiene un numero de serie único ... se debe añadir al compilar el ejemplo el framework iokit
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

Tested and working fine

many thanks Manuel :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
plantenkennis
Posts: 151
Joined: Wed Nov 25, 2015 7:13 pm
Location: the Netherlands
Contact:

Re: protecting an app for illigal copying

Post by plantenkennis »

Hello Antonio,

Thanks for this function. Just what I needed.

Tomorrow I will make a sample prg on how to use this for protection

Greetings,

Rene
Kind regards,

René Koot
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

Rene,

very good

surely others users may appreciate to review your example PRG when it gets ready :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
plantenkennis
Posts: 151
Joined: Wed Nov 25, 2015 7:13 pm
Location: the Netherlands
Contact:

Re: protecting an app for illigal copying

Post by plantenkennis »

Hello Antonio,

Here is a sample program on how I use the MacAdress to protect my program. The only thing I can't get to work is to calculate the days since the program is first opened. Normally I could calculate this by puting the first date in the registration key and when the program is opened again, get DATE()-Firstdate. The number that comes out of this calculation is not what I expect, it is a long number instead of the number of days.

Code: Select all

#include "FiveMac.ch"
#define CR_LF Chr(13) + Chr(10)

/*
With this example we can build a protected program. The user must enter a registration key the first time he uses the program
This key is based on the MacAdres of the computer, every computer has at least one unique MacAdres
When the user gives his program to someone else, the key given is not working anymore
*/

FUNCTION Main()

    PUBLIC cVarFile
    PUBLIC oWnd                 && the main window
    PUBLIC cPath        := ResPath()
    PUBLIC cRegKey      := ''
    PUBLIC nVersion     := 0
    PUBLIC lContinue    := .F.
    PUBLIC nDays        := 0
    
    cVarFile        := cPath + '/registration.plist'

    RK_LoadVariables()
    
    MsgInfo(cRegKey)
    lContinue := RK_CheckKey()

DEFINE WINDOW oWnd TITLE 'testing registration' ;
    FROM 0, 0 TO 600, 600

IF lContinue
@ 400, 20 BUTTON 'Success, version: ' + ALLTRIM(STR(nVersion)) OF oWnd 
ELSE
@ 500, 20 BUTTON 'Register, days to go: '  + ALLTRIM(STR(nDays)) OF oWnd  ; 
    ACTION RK_Register() SIZE 200, 25 
ENDIF

ACTIVATE WINDOW oWnd ;


RETURN NIL

*************************************************

FUNCTION RK_LoadVariables()
*all variables are saved in a .plist file
*date: 13-11-2016

   LOCAL oPList := TPList():New( cVarFile )
   cRegKey := oPList:GetItemByName( 'RegistrationKey' )

RETURN

*************************************************

FUNCTION RK_SaveVariables()
*all variables are saved in a .plist file
*date: 13-11-2016

   LOCAL oPList := TPList():New( cVarFile )

    oPList:SetItemByName( 'RegistrationKey', cRegKey, .T. )
    
RETURN

*************************************************

FUNCTION RK_CheckKey()

*to check the registration key
*date: 15-11-2016

LOCAL cMacAdres
LOCAL cCode1 := '', cCode2 := '', dDate
LOCAL nVersion := 0

IF LEN(cRegKey) == 0        && if there is not a registration yet
    cRegKey := '#'+DtoC(Date()) + '1'
    RETURN .F.
ELSEIF SUBSTR(cRegKey,1,1) == '#'       && if first opening is more than 30 days ago, this is not working correct....
    dDate := CToD(SUBSTR(cRegKey, 2, 8))
    nDays := nDays-(DATE()-dDate)
    RETURN .F.
ELSE                        && check if the key is correct
    cMacAdres := GetMacAddress()
    cCode1      := SUBSTR(cMacAdres, 1, 2) + SUBSTR(cMacAdres, 4, 2)
    cCode2      := SUBSTR(cMacAdres, 7, 2) + SUBSTR(cMacAdres,10, 2)
    cRegKode1   := SUBSTR(cRegKey, 1,1) + SUBSTR(cRegKey, 3,1) + SUBSTR(cRegKey, 5,1) + SUBSTR(cRegKey, 7,1)
    cRegKode2   := SUBSTR(cRegKey, 9,1) + SUBSTR(cRegKey, 11,1) + SUBSTR(cRegKey, 13,1) + SUBSTR(cRegKey, 15,1)
    nVersion    := VAL(SUBSTR(cRegKey,16,1))
    cRegKode7 := CHR(ASC(SUBSTR(cRegKey, 2, 1))- nVersion) + ;
                 CHR(ASC(SUBSTR(cRegKey, 4, 1))+ nVersion) + ;
                 CHR(ASC(SUBSTR(cRegKey, 6, 1))- nVersion-nVersion) + ;
                 CHR(ASC(SUBSTR(cRegKey, 8, 1))+ nVersion+nVersion)
    cRegKode8 := CHR(ASC(SUBSTR(cRegKey, 10, 1))- nVersion) + ;
                 CHR(ASC(SUBSTR(cRegKey, 12, 1))+ nVersion) + ;
                 CHR(ASC(SUBSTR(cRegKey, 14, 1))- nVersion-nVersion)

    IF hb_HexToNum(cCode1)+hb_HexToNum(cRegKode1) == 65535 .AND. hb_HexToNum(cCode2)+hb_HexToNum(cRegKode2) == 65535  .AND. cRegKode7 + cRegKode8 == 'PLANTEN'
        
        RETURN .T.
    ELSE
        MsgInfo('The registration code you have entered is not correct,'+CR_LF+'Please inform us'+CR_LF+ 'You can do this via info@plantenkennis.com.', 'error')
        RETURN .F.
    ENDIF
ENDIF

RETURN .F.

*************************************************

FUNCTION RK_Register()

    LOCAL oDlg, oGet1, oGet2, cGet3:='', cGet4:='', cGet5:='', cGet6:= ''

    LOCAL cMacAdres     := GetMacAddress()
    LOCAL cCode1        := SUBSTR(cMacAdres, 1, 2) + SUBSTR(cMacAdres, 4, 2)
    LOCAL cCode2        := SUBSTR(cMacAdres, 7, 2) + SUBSTR(cMacAdres,10, 2)

    DEFINE DIALOG oDlg TITLE "registration code" PANELED FROM 0, 0 TO 300, 400
   
    @ 200, 100 GET oGet1 VAR cCode1 of oDlg SIZE 75, 25
    @ 200, 200 GET oGet2 VAR cCode2 of oDlg SIZE 75, 25


    @ 100, 10 GET oGet3 VAR cGet3 of oDlg SIZE 75, 25
    @ 100, 90 GET oGet4 VAR cGet4 of oDlg SIZE 75, 25
    @ 100, 170 GET oGet5 VAR cGet5 of oDlg SIZE 75, 25
    @ 100, 250 GET oGet6 VAR cGet6 of oDlg SIZE 75, 25
    
    @ 23,  20 BUTTON "OK" OF oDlg ACTION (cRegKey := cGet3+cGet4+cGet5+cGet6, IF(RK_CheckKey(), MsgInfo('The entered key is correct, close program to continue'), MsgInfo('Wrong key')))


   ACTIVATE DIALOG oDlg CENTERED;
      VALID RK_SaveVariables()

return nil

*************************************************
 
To use this protection the buyer of the program must ask a registration key by me. I have a small program to calculate the registration key. Here is the code for that.

Code: Select all

#include "FiveMac.ch"

/*
This function is to make a registration code that users can put in there app, so it functions well.
use this sample together with the registration_test.prg.
The radiobuttons I use for different versions of the program, PRO has more options than Standard.....

Created by René Koot, 15-11-2016
*/

function Main()

    local oWnd, oRad, nRad := 2
    local cGet1 := '', cGet2 := '', cGet3 := ''


    DEFINE WINDOW oWnd TITLE "creating registration code" PANELED FROM 0, 0 TO 400, 400
   
    @ 300, 100 GET cGet1 of oWnd SIZE 75, 25
    @ 300, 200 GET cGet2 of oWnd SIZE 75, 25

    @ 250, 130 RADIO oRad VAR nRad ITEMS { "Standard", "PRO", "PRO[+]" } OF oWnd

    @ 100, 10 GET oGet3 VAR cGet3 of oWnd SIZE 300, 25
    
    @ 23,  20 BUTTON "Create" OF oWnd ACTION RK_MakeRegistrationCode( cGet1, cGet2, nRad )

    @ 23, 120 BUTTON "Cancel" OF oWnd ACTION oWnd:End()

   ACTIVATE WINDOW oWnd CENTERED

return nil

*************************************************

FUNCTION RK_MakeRegistrationCode(cCode1, cCode2, nRad)

*for creating the registration code
*date: 15-11-2016

LOCAL aLet := {'P', 'L', 'A', 'N', 'T', 'E', 'N'}       &&you can change this array, but use the same array in your program
LOCAL cRegKode1 := hb_NumToHex(65535 - hb_HexToNum(cCode1))
LOCAL cRegKode2 := hb_NumToHex(65535 - hb_HexToNum(cCode2))
LOCAL cRegKode3 := ''
LOCAL cRegKode4 := ''
LOCAL cRegKode5 := ''
LOCAL cRegKode6 := ''

IF LEN(cRegkode1) == 3
    cRegkode1 := '0' + cRegkode1
ENDIF

IF LEN(cRegkode2) == 3
    cRegkode2 := '0' + cRegkode2
ENDIF

cRegKode3 := SUBSTR(cRegKode1, 1, 1) + CHR(ASC(aLet[1])+ nRad) + SUBSTR(cRegKode1, 2, 1) + CHR(ASC(aLet[2])- nRad)
cRegKode4 := SUBSTR(cRegKode1, 3, 1) + CHR(ASC(aLet[3])+ nRad+nRad) + SUBSTR(cRegKode1, 4, 1) + CHR(ASC(aLet[4])- nRad-nRad)
cRegKode5 := SUBSTR(cRegKode2, 1, 1) + CHR(ASC(aLet[5])+ nRad) + SUBSTR(cRegKode2, 2, 1) + CHR(ASC(aLet[6])- nRad)
cRegKode6 := SUBSTR(cRegKode2, 3, 1) + CHR(ASC(aLet[7])+ nRad+nRad) + SUBSTR(cRegKode2, 4, 1) + ALLTRIM(STR(nRad))

oGet3:SetText(cRegKode3 + ' ' + cRegKode4 + ' ' + cRegKode5 + ' ' + cRegKode6)

RETURN NIL
 
I hope this code is useful

Rene
Kind regards,

René Koot
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

René,

Many thanks for this great contribution :-)

Do you mean here in your code ?

nDays := nDays-(DATE()-dDate)

what number do you get ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
bpd2000
Posts: 153
Joined: Tue Aug 05, 2014 9:48 am
Location: India

Re: protecting an app for illigal copying

Post by bpd2000 »

I like protecting method of Easyreport, Refer original source code of EasyReport
Regards, Greetings

Try FWH. You will enjoy it's simplicity and power.!
User avatar
plantenkennis
Posts: 151
Joined: Wed Nov 25, 2015 7:13 pm
Location: the Netherlands
Contact:

Re: protecting an app for illigal copying

Post by plantenkennis »

Hello Antonio,

Yes, there is the problem. I was expecting the number of days different between those dates, but i get a number like 36498. That is also not seconds of days....

Rene
Kind regards,

René Koot
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: protecting an app for illigal copying

Post by Antonio Linares »

René,

Please check those values:

MsgInfo( nDays, ValType( nDays ) )
MsgInfo( dDate, ValType( dDate ) )

nDays := nDays-(DATE()-dDate)
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply