SG Lock USB Dongle in AHK nutzen

Veröffentliche deine funktionierenden Skripte und Funktionen

Moderator: jNizM

User avatar
Gucky_87
Posts: 375
Joined: 03 Jul 2014, 05:09

SG Lock USB Dongle in AHK nutzen

01 Aug 2014, 08:10

Hallo zusammen,

auch, wenn man im Zusammenhang AHK und aktiver Softwareschutz diskutieren kann,
möchte ich Euch das Folgende nicht vorenthalten. Mein Dank geht dabei vor allem
an just me und Gerry, die mich bei diesem Vorhaben sehr tatkräftig unterstützt haben.
Ohne deren Hilfe, wäre dieses Projekt gescheitert (nicht als Schleimen verstehen!).

Aufgabe war es, ein Programm, das ich in AHK geschrieben habe und dass nun
verkauft werden soll, mit einem Dongle vor den phöhsen Softwarepiraten zu schützen.
Bei meinen Recherchen hierzu habe ich etliche Hersteller kontaktiert, die natürlich
alle nichts von AHK gehört hatten. Ich stieß schließlich auf die Firma
SG-Lock und war überrascht, als einer der Programmierer mir erzählte AHK zwar zu
kennen, sich aber natürlich nicht sehr intensiv damit beschäftigt zu haben.

Nun kam das Problem der DLL Calls auf mich zu und ich suchte... und suchte...
Da ich einige Jahre nichts mit AHK gemacht hatte, war ich verwundert, das alte
Forum verlassen vorzufinden. Aber ich fand den Weg hierher und wurde gleich mit
offenen Armen empfangen. Danke.

Just me war es dann, der mein Ansinnen in die Tat umsetzte und blind eine
Routine von C++ in AHK übersetzte (s. dieser Thread).
Da er nun kein Dongle hatte, konnte er es nicht richtig austesten. Dennoch
klappte es bereits beim 1. Anlauf zu 95% und beim 2. dann vollständig.

Das Schöne an diesen Dongles ist, dass man nur eine einzige DLL benötigt.
Crackern wird es insofern schwer gemacht, als dass man sich zunächst bei dieser
DLL authentifizieren mus, ehe die überhaupt mal nachschaut, ob überhaupt ein
Dongle angesteckt ist. Genau diese Authentifizierung war der schwierigste Brocken,
den just me dann aber, wie folgt, gelöst hat:

SglAuth.AHK ; 2014/07 by just me

Code: Select all

; ======================================================================================================================

; Functions to use the SG-Lock (http://www.sg-lock.com/de/index.php) with AutoHotkey (http://www.autohotkey.com).
; This script must be included in the beginning inside the auto-execute-section of the programscript.
; It automatically detects to use the 32 or 64 bit SG-Lock Dll.
; The following routines are written by just me (2014/07) 
;======================================================================================================================

Global SGL_SUCCESS                  := 0x0000                               ; Error messages
     , SGL_DGL_NOT_FOUND            := 0x0001
     , SGL_LPT_BUSY                 := 0x0002
     , SGL_LPT_OPEN_ERROR           := 0x0003
     , SGL_NO_LPT_PORT_FOUND        := 0x0004
     , SGL_AUTHENTICATION_REQUIRED  := 0x0005
     , SGL_AUTHENTICATION_FAILED    := 0x0006
     , SGL_FUNCTION_NOT_SUPPORTED   := 0x0007
     , SGL_PARAMETER_INVALID        := 0x0008
     , SGL_SIGNATURE_INVALID        := 0x0009
     , SGL_USB_BUSY                 := 0x000A
     , SGLDLL := A_PtrSize = 8 ? "SGLW64.DLL" : "SGLW32.DLL"                ; Don´t change this!



; ======================================================================================================================
; Function:           Load dll
; Return values:
;     On success:     Handle of loaded dll file
;     On bad success: Errormessage and exit the program
; ======================================================================================================================

SGL_Init()
    {
    Static HMOD := 0
    If (HMOD = 0) && !(HMOD := DllCall("Kernel32.dll\LoadLibrary", "Str", SGLDLL, "UPtr"))
        {
        MsgBox, 16, ERROR!, `n'%SGLDLL%' not loaded!`nProgram will be terminated.
        ExitApp
        }
    Return HMOD
    }



; ======================================================================================================================
; Function:           Authentification between the script and the SglDLL.
; Parameters:
;     AuthentCode     Array with twelve 32 bit integers
; Return values:
;     On success:     0x0000 (SGL_SUCCESS)
;     On bad success: 0x0006 (SGL_AUTHENTICATION_FAILED)
; ======================================================================================================================

SGL_Authent(AuthentCode)
    {
    DllCall("msvcrt.dll\srand", "UInt", SGL_Rand())                         ; Init MSVCRT Random generator
    RandNumLo := SGL_Rand()                                                 ; Generate two random numbers
    RandNumHi := SGL_Rand()
    VarSetCapacity(RandNum, 8, 0)                                           ; Generate and fill Randnum
    NumPut(RandNumLo, RandNum, 0, "UInt")
    NumPut(RandNumHi, RandNum, 4, "UInt")
    VarSetCapacity(AppRandNum, 8, 0)                                        ; Generate AppRandNum and fill with 0
    NumPut(RandNumLo, AppRandNum, 0, "UInt")
    NumPut(RandNumHi, AppRandNum, 4, "UInt")
    VarSetCapacity(LibRandNum, 8, 0)                                        ; Generate LibRandNum and initialize it with 0
    VarSetCapacity(AuthentLocal, 32, 0)                                     ; Generate AuthentLocal and fill it with the first 8 values of the AuthentCode
    Addr := &AuthentLocal
    Loop, 8                                                                 ;Generate TeaKey and fill it with the last 4 values of the AuthentCode
        Addr := NumPut(AuthentCode[A_Index], Addr + 0, "UInt")
    TeaKey := [AuthentCode[9], AuthentCode[10], AuthentCode[11], AuthentCode[12]]
    RetCode := DllCall(SGLDLL . "\SglAuthentA", "Ptr", &AuthentLocal, "Ptr", &AppRandNum, "Ptr", &LibRandNum, "UInt") ; Call 'SglAuthentAÄ from Dll file
    If (RetCode <> SGL_SUCCESS)                                             ; Check result and exit on error.
        Return SGL_AUTHENTICATION_FAILED . ": SglAuthentA"
    SGL_TeaEncipher(RandNum, RandNum, TeaKey)                               ; Encrypt RandNum with TeaKey
    If (NumGet(RandNum, 0, "UInt") <> NumGet(AppRandNum, 0, "UInt"))        ; Check if the result conciders eith AppRandNum.
    || (NumGet(RandNum, 4, "UInt") <> NumGet(AppRandNum, 4, "UInt"))        ; If not, exit.
        Return SGL_AUTHENTICATION_FAILED . ": Sgl_TeaEncipher 1"
    SGL_TeaEncipher(LibRandNum, LibRandNum, TeaKey)                         ; Encrypt LibRandNum with TeaKey
    RetCode := DllCall(SGLDLL . "\SglAuthentB", "Ptr", &LibRandNum, "UInt") ; Call DLL function 'SglAuthentB'
    If (RetCode <> SGL_SUCCESS)                                             ; Check relult and exit on error
        Return SGL_AUTHENTICATION_FAILED . " - " . RetCode . " - " . ErrorLevel . " - SglAuthentB"
    Return SGL_SUCCESS                                                      ; Anything is all right
    }


; ======================================================================================================================
; Internal functions
; ======================================================================================================================

SGL_TeaEncipher(ByRef InData, ByRef OutData, ByRef Key)
    {
    Static Delta := 0x9E3779B9
    Y := NumGet(InData, 0, "UInt")                                          ; Initialize local vaiables
    Z := NumGet(InData, 4, "UInt")
    A := Key[1]
    B := Key[2]
    C := Key[3]
    D := Key[4]
    Sum := 0
    N := 32
    Loop, % N
        {                                                                   ; Encrypt
        Sum := SGL_UINT(Sum + Delta)
        Y := SGL_UINT(Y + (((Z << 4) + A) ^ (Z + Sum) ^ ((Z >> 5) + B)))
        Z := SGL_UINT(Z + (((Y << 4) + C) ^ (Y + Sum) ^ ((Y >> 5) + D)))
        }
    NumPut(Y, OutData, 0, "UInt")                                           ; Write result to OutData
    NumPut(Z, OutData, 4, "UInt")
    }



; ----------------------------------------------------------------------------------------------------------------------
SGL_Rand()
    {
    Return ((DllCall("msvcrt.dll\rand", "Int") << 16) | DllCall("msvcrt.dll\rand", "Int")) & 0xFFFFFFFF
    }



; ----------------------------------------------------------------------------------------------------------------------
SGL_UINT(Value)
    {
    Return (Value & 0xFFFFFFFF)
    }
; ======================================================================================================================
In dem zu schützenden Programm muss dann möglichst als erstes folgender Aufruf kommen:

Code: Select all

# include SglAuth.AHK

Sgl_Authent() ; 2014/07 by just me
Diese Routine Fragt noch NICHT ab, ob ein für den angegebenen Authent Code gültiges
Dongle angesteckt ist! Es wird nur überprüft, ob der Authent Code, der für jeden Benutzer
individuell vom Donglehersteller vergeben wird, gültig ist.
Wenn ja, lässt die DLL Zugriffe auf ein angestecktes Dongle danach erst zu.
Der Authent Code wird NICHT zum Dongle gesendet, da er dann abfangbar wäre!

Code: Select all

; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

 This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
 AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
                ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
                ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Authentification with SGL.DLL (Returns 0x0000 when successful)
MsgBox, 0, SGL_Authent(), % SGL_Authent(AuthentCode)

Sgl_GetProductID() ; 2014/07 by Gucky
Hier wird nun erstmals direkt auf ein eingestecktes Dongle zugegriffen.
Es wird die individuell vom Programmierer vergebbare Product ID ausgelesen.
Mit dieser ist es möglich, verschiedene Programme verschiedenen Dongles, die den
den selben Authent Code benutzen, zuzuordnen,

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
 AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
                ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
                ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Search for a SG-Lock matching to the AuthentCode.
; If present, read it´s product id.
If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_GetProductId()
    If Result > -1
        MsgBox, 0, SGL_GetProductID, % "Product ID: " . SGL_GetProductId()
    else
        MsgBox, 0, SGL_GetSerialNumber(), % "ERROR!`nNo matching SG-Lock found.`n`nErrorcode: " . Result
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."

ExitApp    
    


SGL_GetProductId()
    {
    Result := DllCall(SGLDLL . "\SglReadProductId", "UIntP", SGL_ProductID)
    If Result = 0
        Return SGL_ProductID
    else
        Return -%Result%
    }


Sgl_WriteProductID() ; 2014/07 by Gucky
Die folgende Routine schreibt eine neue Product ID in ein Dongle.
Hierzu muss zunächst die bisherige Product ID ausgelesen werden, da diese
der Routine übergeben werden muss.

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Writes a new product id to the SG-Lock matching the old product id.
; Note: The product id must be between 0 and 65535
OldProductID := 1234
NewProductID := 5678
If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_WriteProductId(OldProductID, NewProductId)    
    If Result = 0
        MsgBox, 0, SGL_WriteProductID(), New product ID: %NewProductID%
    else
        MsgBox, 0, SGL_WriteProductID(), % "ERROR!`nProduct ID was not changed.`n`nErrorcode: " . Result
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."

ExitApp    
    


SGL_WriteProductID(SGL_ProductID, SGL_ProductID_New)
    {
    Result := Return DllCall(SGLDLL . "\SglWriteProductId", "UInt", SGL_ProductID, "Uint", SGL_ProductID_New)
    If Result = 0
        Return 0
    else
        Return -%Result%
    }

Sgl_GetSerialNumber() ; 2014/07 by Gucky
Um die vom Hersteller in jedem Dongle verankerte, individuelle Seriennummer
auszulesen, kann die folgende Routine benutzt weerden. Zum Auslesen der
Seriennummer muss zuvor die Product ID bekannt sein, damit auf das richtige
Dongle zugegriffen wird (falls gleichzeitig mehrere angesteckt sein sollten).

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
 AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
                ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
                ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Reads the serial number from an SG-Lock with specified product id.
ProductId := 1001
If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_GetSerialNumber(ProductId)
    If Result > -1
        MsgBox, 0, SGL_GetSerialNumber(), % "Serial numer: " . Result
    else
        MsgBox, 0, SGL_GetSerialNumber(), % "ERROR!`nNo matching SG-Lock found.`n`nErrorcode: " . Result

    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
ExitApp    
    


SGL_GetSerialNumber(SGL_ProductID)
    {
    Result := DllCall(SGLDLL . "\SglReadSerialNumber", "UInt", SGL_ProductID, "UIntP", RetVal)
    If Result = 0
        Return RetVal
    else
        Return -%Result%
    }

Sgl_SearchLock() ; 2014/07 by Gucky
Diese Funktion sucht nach einem Dongle, das die angegebene Product ID enthält.
Diese Routine dient also der Klärung der Frage: Ist "mein" Dongle da oder nicht?

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Search for a SG-Lock with a specified product id
ProductID := 1001
If SGL_Authent(AuthentCode) = 0
    {
    If SGL_SearchLock(ProductID) = 0
        MsgBox, 0, SGL_SearchLock(), Found SG-Lock with the`nproduct id: %ProductID%
    else
        MsgBox, 0, SGL_SearchLock(), Unable to find SG-Lock`nwithproduct id: %ProductID%
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
 
ExitApp    
    


SGL_SearchLock(SGL_ProductID)
    {
    Result := Return DllCall(SGLDLL . "\SglSearchLock", "UInt", SGL_ProductID)
    If Result = 0
        Return 0
    else
        Return -%Result%
    }

Sgl_ReadMemory() ; 2014/07 by Gucky
Alle Dongles der Serien "U3" und "U4" besitzen einen internen, frei verfügbaren
Speicher für Daten, sowie Zählregister. Sie unterscheiden sich nur in der Menge.
Mit der folgenden Funktion kann der Wert einer Speicherzelle ausgelesen werden:

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Read data from the memory of the SG-Lock with the specified product id.
ProductID := 1001
Address   := 0
If SGL_Authent(AuthentCode) = 0
    {
    Value := SGL_ReadMemory(ProductID, Address)
    If Value > -1
        MsgBox, 0, SGL_ReadMemory(), % "Value of memory address " . Address . " [Hex: " . Dec2Hex(Address, "0x") . "] is:`n" . Value . " [Hex: " . Dec2Hex(Value, "0x") . "]"
    else
        MsgBox, 0, SGL_ReadMemory(), % "ERROR!`nUnable to read memory address " . Address . " [Hex: " + Dec2Hex(Address, "0x") . "].`n`nErrorcode: " . Value 
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
 
ExitApp    
    


SGL_ReadMemory(SGL_ProductID, Address)
    {
    Result := DllCall(SGLDLL . "\SglReadData", "UInt", SGL_ProductID, "UInt", Address, "UInt", 1, "UIntP", ReadValue)
    If Result = 0
        Return %ReadValue%
    else
        Return -%Result%
    }
    
    
    
Dec2Hex(h, Praefix)
    {
    format = %A_FormatInteger%
    SetFormat, Integer, hex
    H += 0
    SetFormat, Integer, d
    StringLeft, C, H, 2
    If C = 0x
        {
        L := StrLen(h) -2
        StringRight, h, h, L
        }

    If StrLen(h) < 2
        H = 0%h%
    StringUpper, h, h
    SetFormat Integer, %format%
    Return, Praefix . h
    }

Sgl_WriteMemory() ; 2014/07 by Gucky
Das Gegenstück zu Sgl_ReadMemory() ist die folgende Routine. Sie schreibt einen
16 Bit Wert an die angegebene Speicheradresse:

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Write data to a specified address of the SG-Lock with the specified product id.
ProductID := 1001
Address   := 0
Value     := 123456789
If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_WriteMemory(ProductID, Address, Value)
    If Result = 0
        MsgBox, 0, SGL_WriteMemory(), % "Memory address " . Address . " [Hex: " . Dec2Hex(Address, "0x") . "] set to `n" . Value . " [Hex: " . Dec2Hex(Value, "0x") . "]"
    else
        MsgBox, 0, SGL_WriteMemory(), % "ERROR!`nUnable to write to address " . Counter . " [Hex: " + Dec2Hex(Counter, "0x") . "].`n`nErrorcode: " . Result
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
  
ExitApp    
    


SGL_WriteMemory(SGL_ProductID, Address, WriteValue)
    {
    Result := Return DllCall(SGLDLL . "\SglWriteData", "UInt", SGL_ProductID, "UInt", Address, "UInt", 1, "UIntP", WriteValue)
    If Result = 0
        Return 0
    else
        Return -%Result%
    }



Dec2Hex(h, Praefix)
    {
    format = %A_FormatInteger%
    SetFormat, Integer, hex
    H += 0
    SetFormat, Integer, d
    StringLeft, C, H, 2
    If C = 0x
        {
        L := StrLen(h) -2
        StringRight, h, h, L
        }

    If StrLen(h) < 2
        H = 0%h%
    StringUpper, h, h
    SetFormat Integer, %format%
    Return, Praefix . h
    }

Sgl_ReadCounter() ; 2014/07 by Gucky
Um aus Dongles der Serien "U3" oder "U4" die Zählregister, die sich auch als
normale Speicher verwenden lassen, auslesen zu können, kann die folgende
Funktion benutzt werden:

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Read data from a specified counter of the SG-Lock with the specified product id.
ProductID := 1001
Counter   := 0
If SGL_Authent(AuthentCode) = 0
    {
    Value := SGL_ReadCounter(ProductID, Counter)
    If Value > -1
        MsgBox, 0, SGL_ReadCounter(), % "Value of counter number " . Counter . " [Hex: " . Dec2Hex(Counter, "0x") . "] is:`n" . Value . " [Hex: " . Dec2Hex(Value, "0x") . "]"
    else
        MsgBox, 0, SGL_ReadCounter(), % "ERROR!`nUnable to read counter " . Counter . " [Hex: " + Dec2Hex(Counter, "0x") . "].`n`nErrorcode: " . Value 
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
Return    
ExitApp    
    


SGL_ReadCounter(SGL_ProductID, CountNum)
    {
    Result := DllCall(SGLDLL . "\SglReadCounter", "UInt", SGL_ProductID, "UInt", CountNum, "UIntP", CountRead)
    If Result = 0
        Return CountRead
    else
        Return -%Result%
    }
    
    
    
Dec2Hex(h, Praefix)
    {
    format = %A_FormatInteger%
    SetFormat, Integer, hex
    H += 0
    SetFormat, Integer, d
    StringLeft, C, H, 2
    If C = 0x
        {
        L := StrLen(h) -2
        StringRight, h, h, L
        }

    If StrLen(h) < 2
        H = 0%h%
    StringUpper, h, h
    SetFormat Integer, %format%
    Return, Praefix . h
    }

Sgl_WriteCounter() ; 2014/07 by Gucky
Die Funktion Sgl_WriteCounter() ist wiederum das Gegentstück zur letzten Funktion.
Sie schreibt einen 16 Bit Wert an die angegebene Zähleradresse des Dongles.

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Write data to a specified counter of the SG-Lock with the specified product id.
ProductID := 1001
Counter   := 0
Value     := 543210
If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_WriteCounter(ProductID, Counter, Value)
    If Result = 0
        MsgBox, 0, SGL_WriteCounter(), % "Counter number " . Counter . " [Hex: " . Dec2Hex(Counter, "0x") . "] set to `n" . Value . " [Hex: " . Dec2Hex(Value, "0x") . "]"
    else
        MsgBox, 0, SGL_WriteCounter(), % "ERROR!`nUnable to set counter number " . Counter . " [Hex: " + Dec2Hex(Counter, "0x") . "].`n`nErrorcode: " . Result
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
  
ExitApp    
    


SGL_WriteCounter(SGL_ProductID, CountNum, CountValue)
    {
    Result := DllCall(SGLDLL . "\SglWriteCounter", "UInt", SGL_ProductID, "UInt", CountNum, "UInt", CountValue)
    If Result = 0
        Return 0
    Else
        Return -%Result%
    
    
    }



Dec2Hex(h, Praefix)
    {
    format = %A_FormatInteger%
    SetFormat, Integer, hex
    H += 0
    SetFormat, Integer, d
    StringLeft, C, H, 2
    If C = 0x
        {
        L := StrLen(h) -2
        StringRight, h, h, L
        }

    If StrLen(h) < 2
        H = 0%h%
    StringUpper, h, h
    SetFormat Integer, %format%
    Return, Praefix . h
    }

Sgl_ReadConfig() ; 2014/07 by Gucky
Um sicherzustellen, um welchen Typ es sich bei einem erkannten Dongle handelt,
können mit der folgenden Routine die Konfigurationsdaten ausgelesen werden.
Es lassen sich die Hard- und Softwareversion, die Anzahl Speicher- und Zählerzellen,
sowie die Seriennummer und die Anzahl persönlicher Schlüssel abfragen.

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
               ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
               ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Read configuration data of a SG-Lock with the specified product id.
; It´s possible to get each configuration value seperately by specifying the category
ProductID := 1001
Category  := "softver"  ; Type | Interface | SoftVer | HardVer | SerialNumber | MemSize | CountNum | KeyNum
If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_ReadConfig(ProductID, Category)
    If Result > -1
        MsgBox, 0, SGL_ReadConfig(),  %Result%
    else
        MsgBox, 0, SGL_ReadConfig(),  ERROR!`nUnable to read configuration data.`n`nErrorcode: %Result%
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."

ExitApp  


SGL_ReadConfig(SGL_ProductID, Category)
    {
    StringLower, Category, Category
    VarSetCapacity(ConfigData, 32, 0)
    Result := DllCall(SGLDLL . "\SglReadConfig", "UInt", SGL_ProductID, "UInt", 0, "Ptr", &ConfigData)
    If Result = 0
        {
        If Category = type
            {
            Return % NumGet(ConfigData,  0, "UInt")
            msgbox TYPE
            }
        else If Category = interface
            Return % NumGet(ConfigData,  4, "UInt")
        else If Category = softver
            Return % NumGet(ConfigData,  8, "UInt") >> 16 . "." . NumGet(ConfigData,  8, "UInt") & 0xFFFF
        else If Category = hardver
        
; SG_Lock_HardVer    := ((Ver := NumGet(ConfigData, 12, "UInt") >> 16) . "." . Substr("0" . (Ver & 0xFFFF), -1)
            Return % NumGet(ConfigData, 12, "UInt") >> 16 . "." . NumGet(ConfigData, 12, "UInt") & 0xFFFF
        else If Category = serialnumber
            Return % NumGet(ConfigData, 16, "UInt") 
        else If Category = memsize
            Return % NumGet(ConfigData, 20, "UInt")
        else If Category = countnum
            Return % NumGet(ConfigData, 24, "UInt")   
        else If Category = keynum
            Return % NumGet(ConfigData, 28, "UInt") 
        else
            Return -11
        }
    else
        Return -%Result%  
    }


Sgl_WriteKey() ; 2014/07 by Gucky
Alle Dongles der Typen "U3" und "U4" besitzten separate Speicher, in die eigene
64 Bit Schlüssel geschrieben werden können. Mit diesen ist es dann möglich, Daten
mit Hilfe des Dongles zu ver- oder entschlüseln. Es handelt sich dabei um
symmetrische Schlüssel, d.h. dass stets der selbe Schlüssel zum Verschlüsseln und
auch zum Entschlüsseln verwendet wird.
Um die Sicherheit zu erhöhen, können Schlüssel nur in das Dongle geschrieben,
nicht jedoch ausgelesen werden.

Code: Select all

; 2014/07 by Gucky
; This program shows how to use the SG-Lock together with AutoHotKey

; IMPORTANT NOTE:
; With the Demo Authent Key it´s impossible to read/write data from/to
; the memory or counter and/or to encrypt/decrypt data, because the
; demo locks (U2 type) don´t have any memory to store data.

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

; This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
 AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
                ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
                ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

SGL_Init()

; Writes a new 128 bit key into the SG-Lock with the specified product id.
ProductID := 1001
KeyNum    := 0
Key       := [0x11111111, 0x22222222, 0x33333333, 0x44444444]

If SGL_Authent(AuthentCode) = 0
    {
    Result := SGL_WriteKey(ProductID, KeyNum, Key)
    If Result = 0
        MsgBox, 0, SGL_WriteKey(), % "New key stored to key #" . KeyNum . ":`n" . Dec2Hex(Key[1], "0x") . "  " . Dec2Hex(Key[2], "0x") . "  " . Dec2Hex(Key[3], "0x") . "  " . Dec2Hex(Key[4], "0x")
    else
        MsgBox, 0, SGL_WriteKey(), % "ERROR!`nUnable to write key # " . KeyNum . ".`n`nErrorcode: " . Result
    }
Else
    MsgBox, 0, SGL_Authent(), % "ERROR!`nDLL Authentification failed."
ExitApp
    



SGL_WriteKey(SGL_ProductId, KeyNum, Key)
    {
    VarSetCapacity(NewKey, 16, 0)
    Addr      := &NewKey
    Loop, 4
        {
        Addr := NumPut(Key[A_Index], Addr + 0, "UInt")
    }
    Result := DllCall(SGLDLL . "\SglWriteKey", "UInt", SGL_ProductID, "UInt", KeyNum, "Ptr", &NewKey)
    If Result = 0
        Return 0
    else
        Return -Result
    }



Dec2Hex(h, Praefix)
    {
    format = %A_FormatInteger%
    SetFormat, Integer, hex
    H += 0
    SetFormat, Integer, d
    StringLeft, C, H, 2
    If C = 0x
        {
        L := StrLen(h) -2
        StringRight, h, h, L
        }

    If StrLen(h) < 2
        H = 0%h%
    StringUpper, h, h
    SetFormat Integer, %format%
    Return, Praefix . h
    }

Es fehlen noch ein paar Funktionen, wie z.B. das Signieren von Datenblöcken.
Das Prinzip sollte jedoch anhand der aufgeführten Funktionen klar sein.
Falls Ihr Fragen zu den Dongles habt, könnt Ihr mich fragen. Sollten jedoch
Fragen bezgl. der Authentifizierung auftauchen, wendet Euch bitte an just me,
der dieses Rad erfunden hat, wofür ich ihm nochmals herzlich danke.


Gucky.
strobo
Posts: 125
Joined: 30 Sep 2013, 15:24

Re: SG Lock USB Dongle in AHK nutzen

01 Aug 2014, 09:19

tl;dr
wie würde ich denn dieses Programm

Code: Select all

msgbox Hello World!
vor den phöhsen Churcken schützen?
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: SG Lock USB Dongle in AHK nutzen

02 Aug 2014, 03:10

Hallo Gucky,

gut, dass Du soweit alles Nötige erfolgreich zum Laufen gebracht, Glückwunsch! Es ist ein gutes Beispiel dafür, dass AHK durchaus für professionelle Anwendungen taugt. Die Frage, ob eine AHK Anwendung überhaupt sicher geschützt werden kann, ist meiner Meinung nach bereits oft genug diskutiert worden, so dass man das hier nicht erneut aufgreifen muss.

Eine Anregung hätte ich noch, auch wenn die Nachfrage nach dem Skript möglicherweise nicht besonders groß sein wird. Fasse doch bitte alle Funktionen noch einmal in einem Skript SGL.AHK für den Download zusammen. Für die Funktionsbeschreibungen sollte ein Verweis auf Deinen Beitrag hier ausreichen.

Viel Erfolg weiterhin!

just me

@strobo: Ich würde zunächst einmal kären, welche Sprache die phösen Churcken sprechen, und dann den Text einfach in einer ihnen unbekannten Sprache ausgeben. Wofür sonst gibt es AHK Unicode? ;)
strobo
Posts: 125
Joined: 30 Sep 2013, 15:24

Re: SG Lock USB Dongle in AHK nutzen

02 Aug 2014, 09:13

@just me: So mach ich das sonst immer, wollte nur mal die SGL.AHK Alternative _am Stück_ bestaunen;)
User avatar
Gucky_87
Posts: 375
Joined: 03 Jul 2014, 05:09

Re: SG Lock USB Dongle in AHK nutzen

11 Nov 2014, 10:06

@ just me:
Das kann ich gerne machen. Wie sollte das ganze dann genau aussehen?
Quasi alle Einzelfunktionen in einem Script untereinander?
Meine Idee, alle Funktionen einzeln zu posten, war, dass man sich für "sein" Script das raussuchen kann, was man benötigt und nicht den Code unnötig mit Routinen aufbläht, die man NIE braucht (in diesem Script).

@ strobo:
Sicherlich ist die Relation, EINE einzelne Zeile per Dongle zu schützen, etwas groß :D
Aber dennoch geht auch das natürlich (ich setze voraus, dass die einzelnen Routinen als Files vorhanden sind):

Code: Select all

#NoEnv
#Include SglAuth.AHK
SetBatchlines -1

 This is the DEMO authentication code, every  regular SG-Lock user gets its own unique authentication code.
 AuthentCode := [0xF574D17B, 0xA94628EE, 0xF2857A8F, 0x69346B4A
                ,0x4136E8F2, 0x89ADC688, 0x80C2C1D4, 0xA8C6327C
                ,0x1A72699A, 0x574B7CA0, 0x1E8D3E98, 0xD7DEFDC5]

If SGL_Init() == 0
    {
    msgbox Hello World!
    ExitApp
    }
else
    {
    msgbox No hardlock found!
    ExitApp
    }
if 


Ich bin mir natürlich darüber im Klaren, dass ein AHK Script Re Compiliert werden kann u.s.w. Klar. Das geht beinahe mit jedem Code (oder irre ich da?), genügend "kriminelle" Energie vorausgesetzt.

Was mein Script angeht, würde es dort, wo ich es einsetze, vermutlich völlig ausreichen, irgendwo versteckt einen Registry Wert zu setzen und diesen abzufragen.
Ich möchte damit niemanden "als dumm" bezeichnen, aber die Benutzer interressiert es recht wenig, ob sie das Ding knacken könnten. Sie benutzen es und legen an sich mehr Wert darauf, dass es fehlerfrei läuft. Auch ist die Gefahr, dass "ein Kumpel" eine Kopie macht, die er dann auch noch auf Fremdrechnern ans Laufen bekommt, recht gering.

Dieses Script ist inzwischen so komplex, dass man es nicht "mal eben so" installieren kann. Es müssen auf jedem Rechner bestimmte Anpassungen vorgenommen werden, die man kaum "aus dem Ärmel" schütteln kann.

Dennoch habe ich den Dongle Schutz eingebaut, um eine leichtete Lizensierung zu ermöglichen. Im Speicher des Dongles kann ich (auch aus der Ferne) Werte setzen, ändern, löschen, die auch dann erhalten bleiben, wenn der PC sich ändert.
Es geht also nicht nur um den reinen (s. Beispiel) Schutz "ist das Dongle da?".


Gruß,

Gucky
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: SG Lock USB Dongle in AHK nutzen

11 Nov 2014, 10:49

Hallo Gucky,

ja, so dachte ich mir das. Der mögliche Anwender kann dann alles in einem Rutsch runterladen und - so er will - selbst entscheiden, ob er einzelne Funktionen wieder rauswirft.


Grüße,

just me
User avatar
Gucky_87
Posts: 375
Joined: 03 Jul 2014, 05:09

Re: SG Lock USB Dongle in AHK nutzen

13 Dec 2014, 05:27

Moinsen zusammen,

nur mal eine ganz "blöde" Fage am Rande (Wenns nicht ohne "Axt" und "kettensäge" geht, btte gleich sagen, dann vergesse ich diese Idee.

Kann man diese Dpngleabfrage auch netzwerkfähig machen?
Sprich, das Dongle steckt an einem PC der im selben netzwerk ist, wie der PC,
auf dem das Haupt Programm installiert ist.

Also:
Progtamm liegt auf PC mit (z.B.) IP 192.168.0.1
Dongle steckt an PC mit (z.B.( IP 192.169.178.123

Meine erste Idee dazu war folgende:
Das Dongle + die sgl.dll + ein kleines AHL Script liegen auf dem Netzwerkrechner.
Mein programm, das auf einem anderen PC läuft, fragt per TCP/IP irgendwas an das AHK Script auf dem Dongle Rechner, der dann antwortet.

Mir ist natürlich klar, dass damit an sich der Schutz dahin ist, da die ganze Sache genau DORT angreifbar wird. Vielleicht fehlt mir aber auch Erfahrung/Wissen und es gibt einen weg, der mich z.B. aus der Ferne direkt auf die DLL zugreifen lässt?

Gucky.
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: SG Lock USB Dongle in AHK nutzen

17 Dec 2014, 05:38

Hallo,

ich bin nicht sicher, was genau Du vorhast, aber für die Netzwerkkommunikation guck mal da: autohotkey . com/board/topic/94376-socket-class-überarbeitet/?p=603390
User avatar
Gucky_87
Posts: 375
Joined: 03 Jul 2014, 05:09

Re: SG Lock USB Dongle in AHK nutzen

22 Dec 2014, 08:54

Hallo,

na ich habe das DOngle an einem PC, der aber z.B. keine USB Anschlüsse hat,
bzw. sind diese nicht verfügbar. Daher möchte ich das Dongle an einen anderen
PC anklemmen können und dann per Netzwerk abfragen, obs da ist.
So könnte man z.B. auch Mehrplatzanwendungen mit 1 Dongle schützen.

Ich schaue mir Deinen Link nach den Feiertagen sicherlich an, just me, danke erstmal.

Wie gesagt, es ist nicht "brennend" wichtig. Es war eher eine "Schnapsidee".

In diesem Sinne,

schöne Feiertage und rutscht gut alle zusammen,

Gucky.

Return to “Skripte und Funktionen”

Who is online

Users browsing this forum: No registered users and 50 guests