Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

SW copy protection


  • Please log in to reply
305 replies to this topic
guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011
another idea

Have server check and lock license on program startup every time, and release license on program exit. If another client starts with same license whilst the first client has license then it is rejected. This way doesn't prevent the license being used by more than one user, but does prevent it being used concurrently by more than one user - which is good enough. It also allows a legitimate user to transfer the license on any of their computers which provides a better experience.



<!-- m -->http://stackoverflow... ... 87#2460887<!-- m -->

guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011
php manual
<!-- m -->http://php.net/manua...mysql-query.php<!-- m -->

For other type of SQL statements, INSERT, UPDATE, DELETE, DROP, etc, mysql_query() returns TRUE on success or FALSE on error.


maybe i'm reading it wrong, i don't know squat about mysql, but these may be bugs in Jamie's config.php, where you reverse the success/fail of the mysql_query call as the return value of the functions.

this affects the following method return values:

maketable()
insert()
setmfp()


fix:

<?php

    
    // put a new license into the database (with a blank mfp)
    function insert($license, $product) {
      $license = $this->cleanse($license);  
      $product = $this->cleanse($product);
      $sql = "INSERT INTO " . $this->tablename . " (license, product, mfp) VALUES ('$license', '$product', '')";
      $result=mysql_query($sql);
      [color=red]//if (!$result) {[/color]
      [color=green]if ($result) {[/color]
        return true;
      }
      return false;
    }
    
?>



this probably slipped by, becuase it doesn't look like you're actually using the return value of those methods anywhere. i tried using the return true/false as confirmations and thats how i ran into it.

Jamie
  • Members
  • 129 posts
  • Last active: Dec 02 2012 04:59 AM
  • Joined: 26 Mar 2010
One thing I often do is make "false" represent success, because it lets me more easily return more information if there is a failure. In PHP I often return the empty string (false) for success, and for failure I return a string describing the reason for the failure.

If false represents failure, then some other mechanism is usually required to get the reason for the error. Each language has its own idioms for this, whether it's ErrorLevel or errno() or mysql_error() or exceptions or what have you.

I very often use this convention in AHK as well
if (rc := somefunction()) {
  MessageBox, somefunction had an error: %rc%
  return
}

That being said, I can't say for sure if it's an error or not. I don't remember my thought process at the time, and I don't always use the false=success convention. If I meant for false to represent success, at the very least I should have returned "" for success and "failed to insert" for failure. The boolean value would be the same but it would be less confusing as to why.

dorfl68
  • Members
  • 92 posts
  • Last active: Sep 03 2013 08:03 PM
  • Joined: 11 Jun 2010
I played with this for my purposes and want to share back.

Changes
(1) INstalled function for test period (in days). Effectively, I create a registry entry with a (very simply) obfuscated timestamp and check that

(2) I didn't like the user and O/S depended Computer footprint. On the other hand, I did not want to use only processor etc as there are too few options. So I am creating two random registry entries at first run that get incorporated in the footprint. Seemed like a good compromise for low level protection (which is all I need)

(3) Library shows a splash screen if program is not registered. Text in splash depends on the status of the testmode (still testing or ran out)

(4) I wanted all keys nicely formatted in 4 strings of four

Obviously, none of this is great against a semi good Hacker, but it was fine for my application

registration_Library.ahk:

; Demo for Testperiod and registration
; Author:   [email protected]
;
;
;

/* global variables defined in here
license_k0   ; secret keys
license_k1
license_k2
license_k3
license_l0
license_l1
license_m0
license_m1

regkey1, regkey2, regkey3, regkey4 - registration keys

*/




;-------------------------------------------------------------------------------
; higher level functions
;-------------------------------------------------------------------------------
;
; Registered_copy() ; Returns TRUE if this a registered copy or a copy in testmode
; copy_is_registered() ; Shows registration screen if not registered; returns TRUE if this a registered copy
; in_testmode() ; Shows registration screen if in testmode; returns TRUE if in testmode
;
;-------------------------------------------------------------------------------


Registered_copy()
  {
    ; Returns TRUE if this a registered copy or a copy in testmode
    ; shows splash screen if not registered

    license_Initialize() ; make sure all keys are set etc

    If (copy_is_registered())
        Return True

    If (in_testmode())
        Return True
    Else
        Return False

  }



copy_is_registered()
  {
    ; test if software is already registered

    IniRead, k, %A_ScriptDir%\registration, registration, regkey,0 ; Get registration key

    If (K=0) ; registration key doesn't exist, this is not registered
        Return False

    ; now K hold a registration key.
    If (IsUserAuthenticated(k)) ; is the key correct?
        Return True ; yes, correct key
    Else
        Return, False ; wrong key
  }



in_testmode()
  {
    ; returns True if in testmode, False if expired
    ; shows splashscreen

    time_divider := 6.3737 ; to obfuscate time
    test_time := 8 ; days test period

    RegRead, installation_time, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, time1  ; read installation time

    If installation_time=
      {
        testperiod_splash("First run - you have " . test_time " days to test this software")
        code_time := A_Now/time_divider ; obfuscated installation time
        RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\dorflsoft, time1, %code_time% ; write into reg
        Return True ; we are in testmode
      }

    installation_time := Floor(Installation_time * time_divider) ; get installation time

    OutputDebug, Installed: %installation_time% ; debugging

    now :=A_Now ; today's time
    EnvSub, now, %installation_time%, Days ; get difference from installation to today in days

    If ((now<test_time) And (now>-1)) ; true if we are in test period
      {
        now := test_time - now
        testperiod_splash("You have " . now . " days left in testmode")
        Return True ; we are still in test period
      }

    ; we are outside test period
    testperiod_splash("Testperiod expired - please register!")
    Return False ; outside test period
  }


testperiod_splash(message)
  {
    global regkey1, regkey2, regkey3, regkey4 ; need to be global to be used in GUI

    install_number := Get_install_number()

    Gui, 91: +ToolWindow
    Gui, 91: Font, S20 bold, Verdana
    Gui, 91: Add, Text, Section x20 y10 w660 h30 +Center, Registration example

    Gui, 91: Font, S10 norm, Verdana
    Gui, 91: Add, Text, xs  yp+30 w660 h40 +Center , This software was written in AHK (http://www.autohotkey.com)
    Gui, 91: Font, S12 norm bold, Verdana
    Gui, 91:  Add, Text, xs yp+30 w660 h30 +Center , %message%
    Gui, 91: Font, S12 norm, Verdana
    Gui, 91:  Add, Text, xs yp+30 w660 h30 +Center gcopyinstallnumber, Installation Number (Click to copy to Clipboard for email)
    Gui, 91: Font, cblue
    Gui, 91:  Add, Text, xs yp+30 w660 h30 +Center gcopyinstallnumber, %install_number%
    Gui, 91: Font, norm cblack
    Gui, 91: Add, Text, xs+100 yp+60, Registration Key:
    Gui, 91: Font, s12, courier
    Gui, 91: Add, Edit, limit4 w50 Section Uppercase yp xp+150 Center vregkey1,
    Gui, 91: Add, Text, YP w5 xp+51,-
    Gui, 91: Add, Edit, limit4 xp+6 w50 Uppercase ys Center vregkey2,
    Gui, 91: Add, Text, YP xp+51,-
    Gui, 91: Add, Edit, limit4 xp+6 w50 Uppercase ys Center vregkey3,
    Gui, 91: Add, Text, YP xp+51,-
    Gui, 91: Add, Edit, limit4 xp+6 w50 Uppercase ys Center vregkey4,
    Gui, 91: Font, S8 norm, Verdana
    Gui, 91:  Add, Button, yp xp+60 hp Default Center -Wrap gregister_me, Register
    Gui, 91: Font, S14 norm, Verdana

    Gui, 91:  Add, Button, x300 yp+50 w100 h30 Default Center -Wrap, OK

    Gui, 91: Show, w700 Center , Testmode

    ; wait until user is done with this GUI

    Gui, 91: +LastFound
    WinWaitActive
    WinWaitClose

    Return


  copyinstallnumber:
    {
      Clipboard := install_number
      MsgBox, 4160, Registration, Install Number copied to Clipboard. `n Email the Number to [tbd]@tbd.com] for registration
      Return
    }




  register_me:
  {

    Loop, 4
        GuiControlGet, regkey%A_Index%

    k := regkey1 . regkey2 . regkey3 . regkey4 ; create key

    If IsUserAuthenticated(k) ; test whether this is a valid key
      {
        Gui, 91: Destroy
        IniWrite, %k%, %A_ScriptDir%\registration, registration, regkey  ; write key in registry
        MsgBox, 4144, Registration, Registration key recognized `n Thank You!
        Return
      }
    Else
        MsgBox, 4144, Registration Error, Sorry, that seems to be an`n invalid registration key

    Return


  }


91GuiClose:
91ButtonOK:
Gui, 91: Destroy
Return

}








;-------------------------------------------------------------------------------
; core functions Functions
;-------------------------------------------------------------------------------
;
; licence_Initialize() ; initialize the secret keys
; install_number()     ; returns the installation number (fingerprint)
; IsUserAuthenticated(key) ; returns true if Key is a valid registration key
; GenerateLicenseKey(install_number) ; generates a registration key from the install number (fingerprint)
;
;-------------------------------------------------------------------------------
license_Initialize()
  {
    ; initialize the variables and create the registry entries
    global

    license_k0 := 0x89879798                ; 128-bit secret key (example)
    license_k1 := 0x98987987
    license_k2 := 0x82826363
    license_k3 := 0x82928637

    license_l0 := 0x91873619                  ; 64- bit 2nd secret key (example)
    license_l1 := 0x92929292

    license_m0 := 0x11111982                  ; 64- bit 3rd secret key (example)
    license_m1 := 0x98292929

    ; now create the random keys if they don't exist

    RegRead, license_reg1, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, r1
    RegRead, license_reg2, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, r2


    If license_reg1=
      {
        Random,license_reg1,10000000,2147483647
        RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, r1, %license_reg1%
      }

    If license_reg2=
      {
        Random,license_reg2,10000000,2147483647
        RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, r2, %license_reg2%
      }

    Return
  }






Get_install_number()
  {
    ; gets installation number (formally called fingerprint)
    ; kept all envgets if other folks want to add them back in

    EnvGet, COMPUTERNAME, COMPUTERNAME
    EnvGet, HOMEPATH, HOMEPATH
    EnvGet, USERNAME, USERNAME
    EnvGet, PROCESSOR_ARCHITECTURE, PROCESSOR_ARCHITECTURE
    EnvGet, PROCESSOR_IDENTIFIER, PROCESSOR_IDENTIFIER
    EnvGet, PROCESSOR_LEVEL, PROCESSOR_LEVEL
    EnvGet, PROCESSOR_REVISION, PROCESSOR_REVISION

    ; new: read random keys
    RegRead, license_reg1, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, r1
    RegRead, license_reg2, HKEY_LOCAL_MACHINE, SOFTWARE\Dorflsoft, r2

    ; construct the key - feel free to vary
    ; this tries to be hardware specific

    PCdata = %license_reg1%%PROCESSOR_ARCHITECTURE%%PROCESSOR_IDENTIFIER%
    PCdata = %PCdata%%PROCESSOR_LEVEL%%PROCESSOR_REVISION%%license_reg2%

    Fingerprint := XCBC(Hex(PCdata,StrLen(PCdata)), 0,0, 0,0,0,0, 4,3, 4,3)

    StringUpper, fingerprint,fingerprint ; make it look good
    fp := create_blocks(fingerprint) ; create blocks of four with dashes in between
    Return FP
  }


GenerateLicenseKey(fingerprint )
  {
    ; almost as original - create the registration key from fingerprint
    ; also now takes a fingerprint in blocks of 4 with dashes

    global license_k0,license_k1,license_k2,license_k3,license_l0,license_l1,license_m0,license_m1

    StringReplace, fingerprint,fingerprint,-,,All ; remove any dashes

    Auth := XCBC(Hex(fingerprint,StrLen(fingerprint)), 0,0, license_k0,license_k1,license_k2,license_k3, license_l0,license_l1, license_m0,license_m1)

    StringUpper, auth, auth ; make it look good

    a := create_blocks(auth) ; create blocks of four with dashes in between

    Return A
  }


IsUserAuthenticated(key )
  {

    ; check whether user is authenticated
    ; takes both keys with or without dashed

    global license_k0,license_k1,license_k2,license_k3,license_l0,license_l1,license_m0,license_m1

    StringReplace, key,key,-,,All ; remove any dashes

    AuthData := GenerateLicenseKey(Get_install_number())

    StringReplace, authdata,authdata,-,,All ; remove any dashes
    StringUpper, key,key
    Return Key=AuthData
  }


create_blocks(in)
  {
    ; takes string of 16 and returns blocks of four with dashes
    out :=""
    Loop
      {
        out .= SubStr(in,1,4)
        If StrLen(in) =4
            Break ; last one
        out .= "-"
        StringTrimLeft, in, in, 4 ; remove 4 and repeat
      }
    Return out
  }




;-------------------------------------------------------------------------------
; Internal Functions by Laszlo
;-------------------------------------------------------------------------------

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TEA cipher ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Block encryption with the TEA cipher
; [y,z] = 64-bit I/0 block
; [k0,k1,k2,k3] = 128-bit key
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TEA(ByRef y,ByRef z, k0,k1,k2,k3)
  {                                   ; need  SetFormat Integer, D
    s = 0
    d = 0x9E3779B9
    Loop 32                          ; could be reduced to 8 for speed
      {
        k := "k" . s & 3              ; indexing the key
        y := 0xFFFFFFFF & (y + ((z << 4 ^ z >> 5) + z  ^  s + %k%))
        s := 0xFFFFFFFF & (s + d)  ; simulate 32 bit operations
        k := "k" . s >> 11 & 3
        z := 0xFFFFFFFF & (z + ((y << 4 ^ y >> 5) + y  ^  s + %k%))
      }
  }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XCBC-MAC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; x  = long hex string input
; [u,v] = 64-bit initial value (0,0)
; [k0,k1,k2,k3] = 128-bit key
; [l0,l1] = 64-bit key for not padded last block
; [m0,m1] = 64-bit key for padded last block
; Return 16 hex digits (64 bits) digest
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XCBC(x, u,v, k0,k1,k2,k3, l0,l1, m0,m1)
  {
    Loop % Ceil(StrLen(x)/16)-1   ; full length intermediate message blocks
        XCBCstep(u, v, x, k0,k1,k2,k3)

    If (StrLen(x) = 16)              ; full length last message block
      {
        u := u ^ l0                   ; l-key modifies last state
        v := v ^ l1
        XCBCstep(u, v, x, k0,k1,k2,k3)
      }
    Else {                           ; padded last message block
        u := u ^ m0                   ; m-key modifies last state
    v := v ^ m1
    x = %x%100000000000000
    XCBCstep(u, v, x, k0,k1,k2,k3)
  }
Return Hex8(u) . Hex8(v)         ; 16 hex digits returned
  }

XCBCstep(ByRef u, ByRef v, ByRef x, k0,k1,k2,k3)
  {
    StringLeft  p, x, 8              ; Msg blocks
    StringMid   q, x, 9, 8
    StringTrimLeft x, x, 16
    p = 0x%p%
    q = 0x%q%
    u := u ^ p
    v := v ^ q
    TEA(u,v,k0,k1,k2,k3)
  }

Hex8(i)                             ; 32-bit integer -> 8 hex digits
  {
    format = %A_FormatInteger%       ; save original integer format
    SetFormat Integer, Hex
    i += 0x100000000                 ; convert to hex, set MS bit
    StringTrimLeft i, i, 3           ; remove leading 0x1
    SetFormat Integer, %format%      ; restore original format
    Return i
  }

Hex(ByRef b, n=0)                   ; n bytes data -> stream of 2-digit hex
  {                                   ; n = 0: all (SetCapacity can be larger than used!)
    format = %A_FormatInteger%       ; save original integer format
    SetFormat Integer, Hex           ; for converting bytes to hex

    m := VarSetCapacity(b)
    If (n < 1 or n > m)
        n := m
    Loop %n%
      {
        x := 256 + *(&b+A_Index-1)    ; get byte in hex, set 17th bit
        StringTrimLeft x, x, 3        ; remove 0x1
        h = %h%%x%
      }
    SetFormat Integer, %format%      ; restore original format
    Return h
  }

example usage



/*
Main program for Demo only
*/

#SingleInstance force
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.



If (!registered_copy())
    ExitApp

MsgBox, App is registered or in testperiod, have fun

; main program starts here


Return


#Include registration_library.ahk

Tool to calculate the reg code

/*
 Creates registration key
*/


#NoEnv
#SingleInstance force

Gui, Font, S14
Gui, Add, Text,Section,Dorfl Registration key generator
Gui, Add, Text,, Installion Number:
Gui, Add, Edit, yp xp+200 vinstallnumber gnumberchange,

Gui, Add, Text,XS, Registration key:
Gui, Add, Text , yp xp+200 w200 vregkey ReadOnly, %A_Space%
Gui, Add, Button,gcopytoclip,Copy registration key to Clipboard
Gui, Show
Return

numberchange:
  {
    License_Initialize()
    GuiControlGet, installnumber
    r := GenerateLicenseKey(installnumber)
    GuiControl,, regkey, %r%
    Return
  }

copytoclip:
  {
    GuiControlGet, regkey
    Clipboard := regkey
    MsgBox, %regkey% copied to Clipboard
    Return

  }







#Include registration_library.ahk

Paddy For Lightroom!
Use AHK for keyboard mapping, Midi support, external keyboards, and more in Adobe Lightroom

M'o
  • Members
  • 10 posts
  • Last active: Feb 14 2012 10:57 AM
  • Joined: 09 Mar 2006
Hello together,
i tried the scripts from the first pages, but they dont work with AutoHotkey_L. Because I don't understand why, I ask my question here...

My own script startet without registration file, so I got the fingerprint of my system. Then I have created the SafeSW.ini with the short script (with input boxes) from page 2 of this thread.
The file was created, now I started my script again, but the registration is'nt valid and the registration windows comes back.

I've installed AHK_L in the ANSI-Mode, to get better compatibility, but there is a problem, that I can't solve...

Back to normal AutoHotkey can't be the way for me, because I need the debug function in combination with Scite and this is not available for normal AHK version...

Sorry for my terrible english and thanks for any suggestions...

Regards, M'o

deeno
  • Guests
  • Last active:
  • Joined: --

here are the files. swp-internal i've fixed the bug and made it revision 0.12. usage at the bottom

SWProtect-Internal.ahk

; SWProtect-Internal.ahk
;-------------------------------------------------------------------------------
;
; Software Protection Library 0.12
;
; This library contains a set of functions to generate a registration key
; based on a user fingerprint.
; To be used separately or together with the GUI library - SWProtect-GUI.ahk
;
; Original Code:    Laszlo Hars <www.Hars.US>
; Library Version:  Icarus
; modifications:    guest3456          (see changelog at bottom)
;
; Original proof of concept by Laszlo, taken from AutoHotkey Forum at
; http://www.autohotkey.com/forum/viewtopic.php?t=5763&postdays=0&postorder=asc&start=0
;
;
; Functions in this version
;
;   SWP_Initialize( [ secret1, secret 2, ... , secret 8 ] )
;   Fingerprint := SWP_GetPcFingerprint()
;   UserOK      := SWP_IsUserAuthenticated( username, email, key )
;   Key         := SWP_GenerateKey( username, email, fingerprint )
;
;-------------------------------------------------------------------------------


#NoEnv





;-------------------------------------------------------------------------------
; TESTER - Comment or delete this tester when including the file
;

/*

; Initialize the required globals
;----------------------------------------
SWP_Initialize()        ; May be called with up to 8 secret keys


; Get a hardware fingerprint
;----------------------------------------
Fingerprint := SWP_GetPcFingerprint()
MsgBox 32,,Your computer ID is`n%Fingerprint%


; Generate a license key for this user
;----------------------------------------
Username    := "Icarus"
Email       := "[email protected]"
Key         := SWP_GenerateKey( Username, Email, Fingerprint )
MsgBox 32,,Your registration details are:`nUser:`t%Username%`nEmail:`t%Email%`nKey:`t%Key%


; Check if a user's registration code is ok
;----------------------------------------
;Key := "some invalid key by the user"                      ; Uncomment to test
UserOK      := SWP_IsUserAuthenticated( Username, Email, Key )
If( UserOK )
    MsgBox 32,OK,User is authenticated
Else
    MsgBox 16,INVALID,User is NOT authenticated`n%Username%`n%Email%`n%Key%
   
   
Return


*/

;
; END OF TESTER
;-------------------------------------------------------------------------------




;-------------------------------------------------------------------------------
; API Functions
;-------------------------------------------------------------------------------
; 
; SWP_Initialize( [ secret1, secret 2, ... , secret 8 ] )
; Fingerprint := SWP_GetPcFingerprint()
; UserOK      := SWP_IsUserAuthenticated( username, email, key )
; Key         := SWP_GenerateKey( username, email, fingerprint )
;
;-------------------------------------------------------------------------------
SWP_Initialize( mk0=0x11111111, mk1=0x22222222, mk2=0x33333333, mk3=0x44444444
    ,ml0=0x12345678, ml1=0x12345678, mm0=0x87654321, mm1=0x87654321 ) {
   
    Global

    k0 := mk0                  ; 128-bit secret key (example)
    k1 := mk1
    k2 := mk2
    k3 := mk3
   
    l0 := ml0                  ; 64- bit 2nd secret key (example)
    l1 := ml1
   
    m0 := mm0                  ; 64- bit 3rd secret key (example)
    m1 := mm1

}


SWP_GetPcFingerprint() {
    EnvGet, COMPUTERNAME, COMPUTERNAME
    EnvGet, HOMEPATH, HOMEPATH
    EnvGet, USERNAME, USERNAME
    EnvGet, PROCESSOR_ARCHITECTURE, PROCESSOR_ARCHITECTURE
    EnvGet, PROCESSOR_IDENTIFIER, PROCESSOR_IDENTIFIER
    EnvGet, PROCESSOR_LEVEL, PROCESSOR_LEVEL
    EnvGet, PROCESSOR_REVISION, PROCESSOR_REVISION

    PCdata = %COMPUTERNAME%%HOMEPATH%%USERNAME%%PROCESSOR_ARCHITECTURE%%PROCESSOR_IDENTIFIER%
    PCdata = %PCdata%%PROCESSOR_LEVEL%%PROCESSOR_REVISION%%A_OSType%%A_OSVersion%%Language%

    Fingerprint := XCBC(Hex(PCdata,StrLen(PCdata)), 0,0, 0,0,0,0, 1,1, 2,2)
    Return Fingerprint
}

SWP_GenerateKey( username, email, fingerprint ) {
    Global k0,k1,k2,k3,l0,l1,m0,m1
   
    If( not k0 ) {
        MsgBox 16,Error,Error in SWP_GenerateKey - values are not initialized.`nPlease call SWP_Initialize() first.
        Return false
    }
       
    Together = %username%%email%%fingerprint%
    Auth := XCBC(Hex(Together,StrLen(Together)), 0,0, k0,k1,k2,k3, l0,l1, m0,m1)
    Return Auth
}


SWP_IsUserAuthenticated( username, email, key ) {
    Global k0,k1,k2,k3,l0,l1,m0,m1
   
    If( not k0 ) {
        MsgBox 16,Error,Error in SWP_IsUserAuthenticated - values are not initialized.`nPlease call SWP_Initialize() first.
        Return false
    }

    Fingerprint := SWP_GetPcFingerprint()
    Together = %username%%email%%Fingerprint%

    AuthData := XCBC(Hex(Together,StrLen(Together)), 0,0, k0,k1,k2,k3, l0,l1, m0,m1)
   
    Return Key=AuthData
}




;-------------------------------------------------------------------------------
; Internal Functions by Laszlo
;-------------------------------------------------------------------------------

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TEA cipher ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Block encryption with the TEA cipher
; [y,z] = 64-bit I/0 block
; [k0,k1,k2,k3] = 128-bit key
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TEA(ByRef y,ByRef z, k0,k1,k2,k3)
{                                   ; need  SetFormat Integer, D
   s = 0
   d = 0x9E3779B9
   Loop 32                          ; could be reduced to 8 for speed
   {
      k := "k" . s & 3              ; indexing the key
      y := 0xFFFFFFFF & (y + ((z << 4 ^ z >> 5) + z  ^  s + %k%))
      s := 0xFFFFFFFF & (s + d)  ; simulate 32 bit operations
      k := "k" . s >> 11 & 3
      z := 0xFFFFFFFF & (z + ((y << 4 ^ y >> 5) + y  ^  s + %k%))
   }
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XCBC-MAC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; x  = long hex string input
; [u,v] = 64-bit initial value (0,0)
; [k0,k1,k2,k3] = 128-bit key
; [l0,l1] = 64-bit key for not padded last block
; [m0,m1] = 64-bit key for padded last block
; Return 16 hex digits (64 bits) digest
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XCBC(x, u,v, k0,k1,k2,k3, l0,l1, m0,m1)
{
   Loop % Ceil(StrLen(x)/16)-1   ; full length intermediate message blocks
      XCBCstep(u, v, x, k0,k1,k2,k3)

   If (StrLen(x) = 16)              ; full length last message block
   {
      u := u ^ l0                   ; l-key modifies last state
      v := v ^ l1
      XCBCstep(u, v, x, k0,k1,k2,k3)
   }
   Else {                           ; padded last message block
      u := u ^ m0                   ; m-key modifies last state
      v := v ^ m1
      x = %x%100000000000000
      XCBCstep(u, v, x, k0,k1,k2,k3)
   }
   Return Hex8(u) . Hex8(v)         ; 16 hex digits returned
}

XCBCstep(ByRef u, ByRef v, ByRef x, k0,k1,k2,k3)
{
   StringLeft  p, x, 8              ; Msg blocks
   StringMid   q, x, 9, 8
   StringTrimLeft x, x, 16
   p = 0x%p%
   q = 0x%q%
   u := u ^ p
   v := v ^ q
   TEA(u,v,k0,k1,k2,k3)
}

Hex8(i)                             ; 32-bit integer -> 8 hex digits
{
   format = %A_FormatInteger%       ; save original integer format
   SetFormat Integer, Hex
   i += 0x100000000                 ; convert to hex, set MS bit
   StringTrimLeft i, i, 3           ; remove leading 0x1
   SetFormat Integer, %format%      ; restore original format
   Return i
}

Hex(ByRef b, n=0)                   ; n bytes data -> stream of 2-digit hex
{                                   ; n = 0: all (SetCapacity can be larger than used!)
   format = %A_FormatInteger%       ; save original integer format
   SetFormat Integer, Hex           ; for converting bytes to hex

   m := VarSetCapacity(b)
   If (n < 1 or n > m)
       n := m
   Loop %n%
   {
      x := 256 + *(&b+A_Index-1)    ; get byte in hex, set 17th bit
      StringTrimLeft x, x, 3        ; remove 0x1
      h = %h%%x%
   }
   SetFormat Integer, %format%      ; restore original format
   Return h
}


;-------------------------------------------------------------------------------
; Revision History
;-------------------------------------------------------------------------------
/*

    0.12  2010-04-29
        - guest3456: changed script to use #NoEnv and GetFingerprint to use EnvGet
          to solve this bug: http://www.autohotkey.com/forum/post-347395.html#347395


    0.11  2007 09 04
        - Fixed  : IsUserAuthenticated returned -1 in case of an uninitialized
                   globals, now returning false.
       
    0.10  2007 09 03
        - First version



*/ 




SWProtect-GUI.ahk

; SWProtect-GUI.ahk
;-------------------------------------------------------------------------------
;
; Software Protection Library - GUI Implementation 0.11
;
; This library contains a simple set of GUI functions to allow easy
; implementation of a software protection, using a registration code and a
; computer fingerprint.
;
; Requires: SWProtect-Internal.ahk
;
; Original Code:        Laszlo Hars <www.Hars.US>
; Library/GUI Version:  Icarus
;
; AutoHotkey Forum Thread:
; http://www.autohotkey.com/forum/viewtopic.php?t=5763&postdays=0&postorder=asc&start=0
;
; USAGE 1:
;   1. Include this file in your script
;   2. In your loading sequence, call SWP_Initialize() then
;      SWP_CheckRegistration( "AppName", "DeveloperEmail" )
;      to check/ask for a valid registration.
;
; USAGE 2:
;   1. Include this file in a new script
;   2. Call SWP_Initialize() then SWP_ShowKeyGen() to activate a KeyGen dialog
;
; TODO:
;   - See if there is a way to use less global variables
;   - See if there is a way to avoid using a fixed GUI ID (currently, 20) and
;     instead pass it as an optional parameter. The reason why this is not
;     implemented like this is because we need to have 20GuiEscape: labels
;
;-------------------------------------------------------------------------------
#Include SWProtect-Internal.ahk

;-------------------------------------------------------------------------------
; TESTER - Comment or delete this tester when including the file
;

/*

#SingleInstance Force
SetWorkingDir %A_ScriptDir%

; USAGE 1: Add this in a separate file, to have your own keygen
;-------------------------
SWP_Initialize( 0x81645732, 0x19573549 )   ; Up to 8 secret keys,
SWP_ShowKeyGen()
Return
;-------------------------


; USAGE 2: Add this in your loading sequence to check/ask for a valid registration
;-------------------------
;SWP_Initialize( 0x81645732, 0x19573549 )    ; Up to 8 secret keys,
;SWP_CheckRegistration( "My Application", "[email protected]" )     
;-------------------------



Msgbox The program continues here`n`n`n`n`n`n`n`n
Return

*/

;
; END OF TESTER
;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------
; Main GUI Function
;-------------------------------------------------------------------------------

SWP_CheckRegistration( appName, developerEmail, iniFilename="Reg.ini" ) {
;
; Checks for the existence of a valid registration file.
; If registration is valid, it will return the control to the caller, otherwise
; it will show a registration GUI (with an option to the user to ask for a
; registration key) and will only resume normal operation if a valid
; registration code is entered.
;
; When a valid key is entered, the registration details will be saved in an INI
; file (default: Reg.ini) so that next time this function is called, it will be
; able to find the registration code on its own.
;
;-------------------------------------------------------------------------------
    Global SWP_AppName, SWP_IniFilename, SWP_DeveloperEmail, SWP_LicenseOK
   
    SWP_AppName        := appName
    SWP_IniFilename    := iniFilename
    SWP_DeveloperEmail := developerEmail
    SWP_LicenseOK      := false
   
    If( Not FileExist( iniFilename ) ) {
        SWP_ShowRegisterDialog( appName )
        Loop
            If( SWP_LicenseOK )     ; Loop will be broken by a valid license
                Break

    }
    Else {                          ; File exists, read registration data and validate
        SWP_ReadRegFile( iniFilename )
        Sleep 1000      ; This is here since the Reload in SWP_ReadRegFile
                        ; seem to still give the application to continue running
                        ; before it actually reloads.
                        ; Deleteing this launches the "The program continues"
                        ; msgbox
                        ; *** TODO: Can be fixed?

    }

}

SWP_ShowKeyGen() {
;
; This function shows a simple generator for registration numbers.
; Once the user has sent you his Computer ID, use this function to generate
; a valid registration key for this user+computer.
;
; The proper use of this function, is to create a separate ahk code, including
; this library, then calling this function.
;
; Note that you need to call SWP_Initialize with the same seed keys as in your
; SWP_CheckRegistration function BEFORE you call this function.
;
;-------------------------------------------------------------------------------
    Global SwpGuiVal_Name, SwpGuiVal_Email, SwpGuiVal_Key, SwpGuiVal_Fingerprint
        ,SWP_GuiID
   
    SWP_GuiID := 20
    GuiID := SWP_GuiID
   
    Gui %GuiID%:Margin, 10, 10

    ; Top introduction text
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Text, x10 y10 w352 h22 center, Please enter user details:
    Gui %GuiID%:Font, s10 norm

    ; Text labels
    Gui %GuiID%:Add, Text, xp y+15 w135 h22 right section, % "Name/Company: "
    Gui %GuiID%:Add, Text, xp y+2  wp   hp  right        , % "Email Address: "
    Gui %GuiID%:Add, Text, xp Y+2  wp   hp  right        , % "Computer ID: "
    Gui %GuiID%:Add, Text, xp Y+2  wp   hp  right        , % "Key: "
   
    ; Edit fields
    Gui %GuiID%:Add, Edit, xs+137 ys  wp+64 hp vSwpGuiVal_Name
    Gui %GuiID%:Add, Edit, xp     y+2 wp    hp vSwpGuiVal_Email
    Gui %GuiID%:Add, Edit, xp     y+2 wp    hp vSwpGuiVal_Fingerprint
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Edit, xp     y+2 wp    hp readonly center vSwpGuiVal_Key
    Gui %GuiID%:Font, s10 norm
    Gui %GuiID%:Add, Groupbox, xs ys-20 w352 h126
   
    ; Buttons
    Gui %GuiID%:Add, Button, xs  y+10 w109   h24 gSWP_RegisterDialogCancel  , E&xit
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Button, x+2    yp   wp+20 hp  default gSWP_KeygenGenerate  , &Generate
    Gui %GuiID%:Font, s10 norm
    Gui %GuiID%:Add, Button, x+2    yp   wp-20 h24 gSWP_KeygenOk, &Copy && Exit 
   
    Gui %GuiID%:Show, w372, Registration Key Generator
}

;-------------------------------------------------------------------------------
; Other GUI Functions (you should generally avoid calling these functions)
;-------------------------------------------------------------------------------

SWP_ShowRegisterDialog( appName ) {
    Global SWP_GuiID        ; *** TODO: See if there is a way to have a dynamically
                            ; created 20GuiEscape labels, so we can pass GuiID as
                            ; an optional parameter to the function

    Global SWP_AppName, SwpGuiVal_Name, SwpGuiVal_Email, SwpGuiVal_Key
   
    SWP_GuiID := 20
    GuiID := SWP_GuiID
   
    Gui %GuiID%:Margin, 10, 10

    ; Top introduction text
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Text, x10 y10 w352 h22 center, %appName% is not registered.
    Gui %GuiID%:Font, s10 norm
    Gui %GuiID%:Add, Text, xp y+0 wp hp center, Please enter your registration details:

    ; Text labels
    Gui %GuiID%:Add, Text, xp y+15 w135 h22 right section, % "Name/Company: "
    Gui %GuiID%:Add, Text, xp y+2  wp   hp  right        , % "Email Address: "
    Gui %GuiID%:Add, Text, xp Y+2  wp   hp  right        , % "Registration Code: "
   
    ; Edit fields
    Gui %GuiID%:Add, Edit, xs+137 ys  wp+64 hp vSwpGuiVal_Name
    Gui %GuiID%:Add, Edit, xp     y+2 wp    hp vSwpGuiVal_Email
    Gui %GuiID%:Add, Edit, xp     y+2 wp    hp vSwpGuiVal_Key
    Gui %GuiID%:Add, Groupbox, xs ys-20 w352 h102
   
    ; Buttons
    Gui %GuiID%:Add, Button, xs  y+10 w168 h24 gSWP_RegisterDialogGetKey    , &Get a Registration Key
    Gui %GuiID%:Add, Button, x+2 yp   w90  h24 gSWP_RegisterDialogCancel    , E&xit
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Button, x+2 yp   w90  h24 default gSWP_RegisterDialogOk, Register
   
    Gui %GuiID%:Show, w372, %appName% Registration
}

20GuiEscape:
20GuiClose:
SWP_RegisterDialogCancel:
    ExitApp
Return

SWP_RegisterDialogOk:
    Gui %SWP_GuiID%:Submit, NoHide
    If( SwpGuiVal_Name = "" or SwpGuiVal_Email = "" or SwpGuiVal_Key = "" )
        MsgBox 16,Invalid Registration, Invalid Registration.`nPlease check your input.`t
    Else If( Not SWP_IsUserAuthenticated( SwpGuiVal_Name, SwpGuiVal_Email, SwpGuiVal_Key ) ) {
        MsgBox 16,Invalid Registration, Invalid Registration.`nPlease check your input.`t
    }
    Else {
        ; Registration ok, write to ini file and exit happily
        IniWrite %SwpGuiVal_Name%, %SWP_IniFilename%, Registration, Name
        IniWrite %SwpGuiVal_Email%, %SWP_IniFilename%, Registration, Email
        IniWrite %SwpGuiVal_Key%, %SWP_IniFilename%, Registration, Key
        MsgBox 64,Registration Accepted, Your registration was accepted and saved.`t`nThank you for using %SWP_AppName%.
        SWP_LicenseOK := true
        Gui %SWP_GuiID%:Destroy
    }   
Return

SWP_RegisterDialogGetKey:
    SWP_ShowGetKeyDialog()
Return

SWP_ShowGetKeyDialog() {
    Global SWP_GuiID, SWP_AppName, SwpGuiVal_Fingerprint, SwpGuiButton_Ok
        ,SWP_DeveloperEmail

    ; Destroy
    Gui %SWP_GuiID%:Destroy
   
    ; Then rebuild
    SwpGuiVal_Fingerprint := SWP_GetPcFingerprint()
   
    GuiID := SWP_GuiID
    Gui %GuiID%:Margin, 10, 10

    ; Middle box
    Gui %GuiID%:Font, s10 norm
    Gui %GuiID%:Add, Text, x20   y20  w332  h44 center section, Please send us this Computer ID together with your name and email address.
    Gui %GuiID%:Font, s12 bold
    Gui %GuiID%:Add, Edit, xp+10 y+2  wp-20 h24 r1 ReadOnly center vSwpGuiVal_Fingerprint, %SwpGuiVal_Fingerprint%
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Text, xp    y+2  wp    h24 center, Send to %SWP_DeveloperEmail%
    Gui %GuiID%:Font, s10 norm
    Gui %GuiID%:Add, Groupbox, xs-10 ys-15 w352 h128
   
    ; Buttons
    Gui %GuiID%:Add, Button, xs-10  y+10 w90 h24 gSWP_RegisterDialogCancel  , E&xit
    Gui %GuiID%:Font, s10 bold
    Gui %GuiID%:Add, Button, x+2 yp w259  h24 default vSwpGuiButton_Ok gSWP_GetDialogOk, Copy to Clipboard && Exit 
   
    GuiControl %GuiID%:Focus, SwpGuiButton_Ok       ; To avoide the selection of the fingerprint
   
    Gui %GuiID%:Show, w372, %SWP_AppName% Registration
}

SWP_GetDialogOk:
    Gui %SWP_GuiID%:Submit
    Clipboard := "Computer ID: " SwpGuiVal_Fingerprint
    MsgBox 64,Copied to Clipboard, Your Computer ID was copied to the clipboard.`nPlease send it along with your name and email address to`t`n%SWP_DeveloperEmail%.
    ExitApp
Return


SWP_ReadRegFile( iniFilename ) {
    Global SWP_LicenseOK
    IniRead Name, %iniFilename%, Registration, Name
    IniRead Email, %iniFilename%, Registration, Email
    IniRead Key, %iniFilename%, Registration, Key
    SWP_LicenseOK := false
    If( Not SWP_IsUserAuthenticated( Name, Email, Key ) ) {
        MsgBox 16,Invalid Registration, Your registration details seem to be invalid.`t`n
        FileDelete %iniFilename%
        Reload
    }
    SWP_LicenseOK := true
}

SWP_KeygenGenerate:
    Gui %SWP_GuiID%:Submit, NoHide
    SwpGuiVal_Key := SWP_GenerateKey( SwpGuiVal_Name, SwpGuiVal_Email, SwpGuiVal_Fingerprint )
    GuiControl ,%SWP_GuiID%:,SwpGuiVal_Key,%SwpGuiVal_Key%
Return

SWP_KeygenOK:
    Gui %SWP_GuiID%:Submit, NoHide
    Clipboard =
        ( LTRIM
            -----------------------------------
            Username: %SwpGuiVal_Name%
            Email:    %SwpGuiVal_Email%
            Key:      %SwpGuiVal_Key%
            -----------------------------------
        )
    Gui %SWP_GuiID%:Destroy

Return


;-------------------------------------------------------------------------------
; Revision History
;-------------------------------------------------------------------------------
/*

    0.11  2007 09 04
        - Added  : Keygen
        - Changed: Initialize function (secret seeds) now needs to be called
          separately prior to calling any of the other main GUI functions.
          This is done to allow different key generation for every software
          you develop.
          If this is not a requirement, the Initialize function can be put
          back into the two main GUI functions (only make sure you are using
          the same seeds)
       
    0.10  2007 09 03
        - First version



*/ 



yourname.php

<?php


SWP_Initialize(0x81645732,0x19573549);

$str = "UsernameEmailFingerprint";



$key=XCBC($str);
echo "key: ".$key."";


function XCBC($str)
   {
   global $str,$u,$v,$l0,$l1,$m0,$m1;
   $u=0;
   $v=0;
   $str = bin2hex($str);


   // full length intermediate message blocks
   $flimbs = ceil(strlen($str)/16)-1;

   for($i=0; $i<$flimbs; $i+=1)
      {
      XCBCstep();
      }
     

   if (strlen($str)==16)
      {
      $u = $u ^ $l0;               
      $v = $v ^ $l1;

      XCBCstep();
      }else{
      $u = $u ^ $m0;               
      $v = $v ^ $m1;

      $str = $str."100000000000000";

      XCBCstep();
      }


$u = dechex($u);
$v = dechex($v);
while (strlen($u) < 8) { $u='0'.$u; }
while (strlen($v) < 8) { $v='0'.$v; }

return $u.$v;




}

function XTEA()
   {
   global $u,$v,$key;
   $s = 0;
   $d = 0x9e3779b9;
   for($i=0; $i<32;$i++)
      {
      $u = _add($u ,_add($v << 4 ^ _rshift($v,5), $v) ^ _add($s,$key[$s & 3] ) );
      $s =  ($s + $d) ;
      $s= 0xffffffff & $s ;
      $v = _add($v ,_add($u << 4 ^ _rshift($u,5), $u) ^ _add($s,$key[_rshift($s, 11) & 3]));
      }
   return;
   }



function XCBCstep()
   {
   global $u,$v,$str;
   $p = substr($str,0,8);
   $q = substr($str,8,8);
   $str = substr($str,16);
   $p=hexdec($p);
   $q=hexdec($q);
   $u = $u ^ $p;
   $v = $v ^ $q;
   XTEA();
   return;
   }



function _add($i1, $i2) {
        $result = 0.0;
        foreach (func_get_args() as $value)
      {
           if (0.0 > $value) {
                $value -= 1.0 + 0xffffffff;
               }
               $result += $value;
           }


           // convert to 32 bits
           if (0xffffffff < $result || -0xffffffff > $result) {
                  $result = fmod($result, 0xffffffff + 1);
              }

           // convert to signed integer
           if (0x7fffffff < $result) {
               $result -= 0xffffffff + 1.0;
           } elseif (-0x80000000 > $result) {
                  $result += 0xffffffff + 1.0;
           }

           return $result;
          }


function hex2bin($h)
   {
     if (!is_string($h)) return null;
     $r='';
     for ($a=0; $a<strlen($h); $a+=2) { $r.=chr(hexdec($h{$a}.$h{($a+1)})); }
     return $r;
     }


function _rshift($integer, $n) {
        // convert to 32 bits
        if (0xffffffff < $integer || -0xffffffff > $integer) {
            $integer = fmod($integer, 0xffffffff + 1);
        }

        // convert to unsigned integer
        if (0x7fffffff < $integer) {
            $integer -= 0xffffffff + 1.0;
        } elseif (-0x80000000 > $integer) {
            $integer += 0xffffffff + 1.0;
        }

        // do right shift
        if (0 > $integer) {
            $integer &= 0x7fffffff;                     // remove sign bit before shift
            $integer >>= $n;                            // right shift
            $integer |= 1 << (31 - $n);                 // set shifted sign bit
        } else {
            $integer >>= $n;                            // use normal right shift
        }

        return $integer;
    }

function SWP_Initialize($mk0=0x11111111, $mk1=0x22222222, $mk2=0x33333333, $mk3=0x44444444 ,$ml0=0x12345678,$ml1=0x12345678,$mm0=0x87654321, $mm1=0x87654321)
{
   
    global $l0,$l1,$m0,$m1 ,$key;

    $key[0] = $mk0;                 
    $key[1] = $mk1;
    $key[2] = $mk2;
    $key[3] = $mk3;

   
    $l0 = $ml0;                 
    $l1 = $ml1;
   
    $m0 = $mm0;                 
    $m1 = $mm1;


return;

}

?> 


to test that the AHK and PHP generate the same key, heres what you do:

as you can see on the top of the PHP file, there is an Initialize with two keys and a str="UsernameEmailFingerprint". upload the PHP to your webserver and navigate to the page. it will show you the key generated.

use SWProtect-GUI.ahk and uncomment the TESTER section and use USAGE1 which will show you the keygen window. simply put in "Username", "Email", and "Fingerprint" in the respective fields, and click generate. it should show the same key as the PHP in your browser.


Is this stil working? i have try this a lot of time but the key is diferent on php than on ahk is generate it.
i have also check the name, mail and SWP_Initialize strings.
have anyone a working php running on a server so i can check if the key is diferent than what my ahk or php generate it?
i can helps me with find the problem in ahk or php, or maybe some have complete it running demo?

thanks alot

guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011
i dont see why it shouldnt work

make sure the keys parameters are the same in the two Initialize functions

and make sure the user/email/fingerprint are the same. realize that the $str in the php concatenates these three side by side with no spaces

rani
  • Members
  • 217 posts
  • Last active: Jul 21 2016 12:53 PM
  • Joined: 18 Mar 2008
Hi laszlo,

I wonder, can the machine finger print , distinguish differences,
when copying by VMware on some other machine ?

as you know, many machines today are working under virtual machine,
so the question is,
can the SW protection 'understand' that somebody made VMware copy on some other virtual machine ?
because the VMware copy is completeley image copy(if I understand) of a machine

do I need more proection tools for that ?

rgrds
rani

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I don't know, never used one... A virtual machine, in theory, presents the user all the peripherals via its own device drivers, therefore, the HW components can look different. The BIOS is also filtered. Each virtual machine is unique, and this kind of SW copy protection might need new registrations. You have to experiment.

If you can still access some of the HW ID's, the copy protection would work. One candidate is the MAC of your LAN adapter. (Every Ethernet network controller has a unique 48-bit serial number called a MAC address, which is stored in read-only memory.) Similarly, hard disks have ID's, but the VM might not let you access these ID's.

rani
  • Members
  • 217 posts
  • Last active: Jul 21 2016 12:53 PM
  • Joined: 18 Mar 2008
VMware image copy

you mean the BIOS machine is filtered by CPUinfo() in SW protect ?

rani

  • Guests
  • Last active:
  • Joined: --
A lot of variables are nothing, why are they being used?!
PROCESSOR_ARCHITECTURE PROCESSOR_IDENTIFIER PROCESSOR_LEVEL PROCESSOR_REVISION


rani
  • Members
  • 217 posts
  • Last active: Jul 21 2016 12:53 PM
  • Joined: 18 Mar 2008
cpuinfo() function in SW copy protect

yes you right,
and also some text of them is very standard,
but the main 'signature' info I think is unique.

does this CPUinfo gives the BIOS info, as lazslo mentioned,
or there are additional param's for that ?

rani
  • Members
  • 217 posts
  • Last active: Jul 21 2016 12:53 PM
  • Joined: 18 Mar 2008

hi Laszlo,

cpuinfo() function in SW protection

 

I tried on few machines the function cpuinfo()

but on all machines I got same zero no.:

0x0 0x0 0x0 ....

and so on

 

is there a way to get unique CPU fingerprint or SN as most as possible ?



capbat
  • Members
  • 191 posts
  • Last active: Feb 08 2017 06:57 PM
  • Joined: 29 Nov 2007

Script #2 has only one function, to create SafeSW.ini, with the registration/copy protection information. The original script #1 (in the first post) is what you extend with the desired functionality, compile with a password and offer the .exe for download (or distribute the way you like).

Locate the two lines in the script #1:

MsgBox OK   ; add your code here 
Sleep 10000 ; add your code here
They are Line 28 and 29. Remove these lines and add the code you write and want to protect in their place. The MsgBox/Sleep lines represent an example.

 

 

 

Thanks That is also the info that I was missing.

 

Bat



capbat
  • Members
  • 191 posts
  • Last active: Feb 08 2017 06:57 PM
  • Joined: 29 Nov 2007

Hi All

I believe that Laszlo does not come here anymore but here my question anyway.

I have tried this Software works ok and then I said to myself I'll try it on different computer.

So I moved the My App and the SafeSW.ini file to my laptop and it worked perfectly

I tought that all this scheme was Hardware specific.

I used the ini file from the desktop whithout anymore registration and it Worked.

I thought it would be blocked and ask for another registration!

 

Any Ideas?

 

Bat