AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SW copy protection
Goto page 1, 2, 3 ... 18, 19, 20  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sat Oct 08, 2005 5:57 pm    Post subject: SW copy protection Reply with quote

Here is a "proof of concept" script providing SW copy protection. It needs the SafeSW.ini file with the user information and an unlock code, without it the script request registration and exits. The unlock code is computed by the same process at the provider of the SW (AuthData), and it has to be emailed back to the user.

1. To protect the code the AHK script has to be compiled to an executable with ahk2exe, which is part of the AHK distribution. To prevent de-compilation a (good) password has to be provided. This way the program runs normally, but an attacker would have difficulties modifying the program or getting out secrets (keys).

2. Collect some data specific to the target machine. For simplicity we use the following environment variables:

COMPUTERNAME
HOMEPATH
USERNAME
PROCESSOR_ARCHITECTURE
PROCESSOR_IDENTIFIER
PROCESSOR_LEVEL
PROCESSOR_REVISION

AHK built in variables:

A_OSVersion
A_OSType

These should not change at OS updates or changing the network environment.

In addition one can use disk volume identifiers by running the consol command VOL > info.txt:

Volume in drive C has no label.
Volume Serial Number is 24B5-2345

The MAC (Media Access Controller) address of the network cards can be used, too, by Getmac /NH >> info.txt:

00-20-30-F0-F1-F2 Media disconnected


(To be safe only the first 17 characters should be used, the MAC of the first network card.)

Instead of saving this data in a temporary file, one can use CMDret - return output from console programs [DLL version]

3. Having the machine/user specific data, we hash them all (Message Authentication Code = MAC with key 0), so no confidential data can be retrieved from it (for privacy concerns) and everybody can verify that no user secret is hidden in there. This is called the PC fingerprint. We ask the user to register the program via email, with the PC fingerprint and with a username and valid return email address, where we would send the unlock code.

4. We generate an unlock code from the data and send the whole SafeSW.ini file back to the user. S/he saves it into the script's working directory. At startup the program verifies if the user info, the PC fingerprint and the unlock code match. If not, it asks for registering the SW, otherwise it starts working.

Fingerprint = MAC(0_key; PC_data)
Registration_data = Username, Email, Fingerprint → emailed for registration
Authentication_data = Username, Email, MAC(secret_key, Username, Email, Fingerprint) ← emailed back from registration site

5. Operation

- If no or invalid format Authentication_data: Request registration, Exit
- Retrieve PC_data, Username, Email (from stored Authentication_data)
- Compute MAC(secret_key; Username, Email, Fingerprint)
- If invalid Authentication_data in the SafeSW.ini file: Request registration, Exit
- Else: display Username, Email; Start working
- Periodically re-compute Fingerprint, at change: Exit.

6. SafeSW.ini

It contains the following information:

[Registration]
User = Laszlo Hars
Email = Laszlo@Hars.US
UnlockCode = d0e8fd5f48edbc00

7. Notes

A malicious user could change the environment variables before the program starts, but it prevents normal operation, so he has to change it back. The periodic check of the PC fingerprint should make this attack more difficult.

MAC was used with key 0 for the Fingerprint, so users could verify the information sent for registration does not contain their secrets. A general, un-keyed hash is safer, as it is harder in the wrong PC to modify just one environmental variable to get a desired Fingerprint. We used MAC for simplicity.

There is more information that can be included in the machine specific data, like the physical serial number of the primary disk, the BIOS version, checksum, etc. You can make the sample script arbitrarily complex.

Some random, secret info can be written at installation somewhere hidden on the disk (e.g. in the registry) and it could be read back. (It is easy to catch the writing action, so this does not look very secure.) This random number could modify the executable itself, but it is complicated by the need of re-encrypting the code.

It is still possible to disassemble the program, and read the secret keys, but it is hard. Stronger protection is possible, but things would soon get very complicated.
Code:
; AutoHotkey Version: 1.0.39+
; Language:  English
; Platform:  Win2000/XP
; Author:    Laszlo Hars <www.Hars.US>
; Function:  SW copy protection

k0 = 0x11111111                  ; 128-bit secret key (example)
k1 = 0x22222222
k2 = 0x33333333
k3 = 0x44444444

l0 = 0x12345678                  ; 64- bit 2nd secret key (example)
l1 = 0x12345678

m0 = 0x87654321                  ; 64- bit 3rd secret key (example)
m1 = 0x87654321

IniFile = SafeSW.ini

GoSub    CheckAuth
SetTimer CheckAuth,1000
MsgBox,,,This SW is registered to`n%User% at %Email%,4

MsgBox OK   ; add your code here
Sleep 10000 ; add your code here

ExitApp

;---- End autoexecute secsion ----;

CheckAuth:
   IniRead User, %IniFile%, Registration, User
   IniRead Email,%IniFile%, Registration, Email
   IniRead Code, %IniFile%, Registration, UnlockCode
   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)
   Together = %User%%Email%%Fingerprint%
   AuthData := XCBC(Hex(Together,StrLen(Together)), 0,0, k0,k1,k2,k3, l0,l1, m0,m1)
   If (User="Error" || Email="Error" || Code <> AuthData)
   {
      S =
      (  LTrim
         To: Registration@MyOwn.com
         Username = <enter your full name here>
         Your email address = <where you want the unlock code sent>
         PC Fingerprint = %Fingerprint%
      )
      ClipBoard = %S%
      MsgBox Please Register! Email the following information`n`n%S%`n`n(it has been copied to the ClipBoard)
      ExitApp
   }
Return

;---- Crypto functions ----;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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
}


Last edited by Laszlo on Sun Oct 09, 2005 5:33 am; edited 1 time in total
Back to top
View user's profile Send private message
Atomhrt



Joined: 02 Sep 2004
Posts: 124
Location: Sunnyvale

PostPosted: Sun Oct 09, 2005 1:18 am    Post subject: Reply with quote

Weird. I did kind of a similar thing just two days ago. I really wanted to prevent a users ini file that contained some info about their account (not passwords or anything like that) from being used by someone else. One of the things that I did was save some info about the users environment to the ini file (computer name was one of them), but in encrypted format. This prevents anyone from knowing what it is in plain text. Then when the program starts up, it verifies that its running on the machine that it was first authenticated on.

What you've done looks pretty cool. I know that I will be using it soon.
_________________
I am he of whom he speaks!
Back to top
View user's profile Send private message
JohnL



Joined: 04 Oct 2005
Posts: 35

PostPosted: Sun Oct 09, 2005 3:39 am    Post subject: Reply with quote

I hate to ask, simply because this code is so far advanced from anything I could ever make, but could you please write a short script for creating the unlock code?

also, in this line there is a spelling error:

If (User="Error" || Eamil="Error" || Code <> AuthData)


I think I speak for everyone when I say... wow.. what a great contribution for the community. Thanks!
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sun Oct 09, 2005 5:31 am    Post subject: Reply with quote

I fixed in the original post a couple of bugs. Thanks, JohnL!

To generate the SafeSW.ini file replace the code between the line IniFile = ... and ExitApp with the following:
Code:
InputBox User, User,  Enter the User's name,,   220,140
InputBox Email,Email, Enter the User's Email,,  220,140
InputBox FGprt,FGprt, Enter the PC Fingerprint,,220,140
Together = %User%%Email%%FGprt%
Auth := XCBC(Hex(Together,StrLen(Together)), 0,0, k0,k1,k2,k3, l0,l1, m0,m1)
IniWrite %User%, %IniFile%, Registration, User
IniWrite %Email%,%IniFile%, Registration, Email
IniWrite %Auth%, %IniFile%, Registration, UnlockCode
You can remove the CheckAuth subroutine, too, but it does not matter.
Back to top
View user's profile Send private message
Bonzo
Guest





PostPosted: Mon Oct 17, 2005 4:31 am    Post subject: I would skip the HardDrive test... Reply with quote

Hi,

All very cool, but I would skip the Hard Drive test... of all the computers I've owned, every single one of them, had a new hard drive installed at one point.

I would be very annoyed (as an end customer), if my Software didn't work, after a clean install.

Just my 2 cents.
Back to top
Thalon



Joined: 12 Jul 2005
Posts: 633

PostPosted: Mon Oct 17, 2005 7:00 am    Post subject: Reply with quote

I think that's the post I was looking for!
I didn't read the code, only description but it looks like that what I need!

Big thanks to Laszlo (and to Bonzo who put the topic on top Very Happy )!

@Bonzo
I think this way of protecting is very personal, so it wouldn't be hard to tell the user that he has to re-register the programm after changing hardware!

THX!
Thalon
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Oct 17, 2005 3:26 pm    Post subject: Reply with quote

The more information on the user's system we include in the PC fingerprint, the more often s/he needs to re-register the SW. Network cards get also replaced or new adapters added, the original disk could become secondary, when a larger one is installed, BIOS can be updated, etc. Using fewer pieces of configuration data makes the copy protection easier to break. I think the information used in the original post represent a good security/convenience tradeoff, and also high speed, simple code.

Another variation of the theme is when the user first receives (downloads) the compiled script, without the code doing the useful work. In response of the registration we send back the fully functional program with the information User, Email and UnlockCode hard coded. The original setup program then can be deleted. This way there is no need for the .ini file, but our email response has to contain a large attachment.
Back to top
View user's profile Send private message
hotControler



Joined: 07 Nov 2005
Posts: 10
Location: Germany

PostPosted: Wed Nov 09, 2005 5:50 pm    Post subject: Reply with quote

Laszlo, thanks for this great solution - you are a genious!
I am developing a somewhat bigger program and want to share it.
But I definitely cannot give away the source by now, only the exe file (too much nights without getting sleep and too much justified complaints
by my family members). I would like to know, how many people still use it after a period of 90 days.

So I want to ask your permission to integrate this solution in my script.
Of course I could give credits to you, in whatever form you want
(in the registration-Gui, in the email with the code, in the documentaion, ...)
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Wed Nov 09, 2005 6:42 pm    Post subject: Reply with quote

Whatever I post in the AHK forum is FREE, you can use it without any restriction, but I cannot guarantee anything about the scripts, either. I would be glad if you give me credit for the copy protection scheme in the documentation (my website is in my AHK profile).
Back to top
View user's profile Send private message
hotControler



Joined: 07 Nov 2005
Posts: 10
Location: Germany

PostPosted: Wed Nov 09, 2005 8:34 pm    Post subject: Reply with quote

Thank you!
I expected an answer like that, but anyway, I felt bad to use it without your
explicit permission.

The credits will be given, and I hope, my program will be of some use for you too, so I can give something back.
Back to top
View user's profile Send private message
Guest






PostPosted: Mon Jul 17, 2006 12:25 pm    Post subject: Reply with quote

so when i get the persons info sent to my email

do i edit the .ini file or something please explian how i edit it
Back to top
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Jul 17, 2006 7:13 pm    Post subject: Reply with quote

As described above, you need a second version of the script, with the replacement code. You run it, enter (copy & paste) the user information you received via email, and it creates the ini file for you. Its path\name is assigned to "IniFile".
Back to top
View user's profile Send private message
i3egohan



Joined: 18 Jul 2006
Posts: 403

PostPosted: Tue Jul 18, 2006 11:20 am    Post subject: Reply with quote

got it thanks nice work
Back to top
View user's profile Send private message
HCProfessionals



Joined: 18 Jun 2007
Posts: 166

PostPosted: Mon Jun 25, 2007 7:04 pm    Post subject: Reply with quote

I'm just not understanding the 2nd part of this, how do i create the ini file and the location of it, lol?
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Mon Jun 25, 2007 8:31 pm    Post subject: Reply with quote

This post explains how you generate the personalized ini file.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3 ... 18, 19, 20  Next
Page 1 of 20

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group