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)
}
; ======================================================================================================================
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.