Es ist schon beeindruckend, wie geschmeidig die Portierung von C-Code mit AHK_H möglich ist. Wenn Du das ausprobieren kannst/willst, solltest Du es unbedingt mal versuchen.
Ich bleibe lieber bei AHK 1.1 und habe mich deshalb an einer Portierung der Portierung versucht. Die Funktion SGL_Authent() habe ich etwas umgestaltet, weil mir das, was der Programmierer der Fa. SG in der Header-Datei abgelegt hat, etwas zu umständlich erscheint. Auch in SGL_TeaEncipher() waren für AHK (das gilt sowohl für 1.1 als auch für H) noch Anpassungen nötig, weil AHK nur 64-bittige numerische Werte kennt und deshalb bei der Shifterei zusätzliche Bits ins Spiel gebracht wurden.
Bei mir scheint die Authentisierung gegen die DLL so zu klappen, der Anfang scheint gemacht. Mehr kann ich jetzt mangels Dongle auch nicht testen. Es gibt übrigens unter Support -> Download auch eine 64-Bit DLL.
SGL.ahk
Code: Select all
; ======================================================================================================================
; Funktionen für per USB Dongle der Firma SG Intec geschützte Anwendungen (http://www.sg-lock.com/de/index.php).
; Wegen der super-globalen Veriablendeklarationen muss das Skript muss am Anfang des Programms innerhalb der
; Auto-Execute-Section eingebunden werden.
; ======================================================================================================================
Global SGL_SUCCESS := 0x0000
, 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"
; ======================================================================================================================
; Funktion: SGL DLL laden.
; Rückgabewerte:
; Bei Erfolg: Handle der geladenen DLL.
; Bei Fehler: Fehlermeldung und Beenden der Anwendung.
; Anmerkungen:
; Die Funktion muss einmal erfolgreich aufgerufen werden, bevor andere SGL Funktionen aufgerufen werden,
; die auf die DLL zugreifen.
; ======================================================================================================================
SGL_Init() {
Static HMOD := 0
If (HMOD = 0) && !(HMOD := DllCall("Kernel32.dll\LoadLibrary", "Str", SGLDLL, "UPtr")) {
MsgBox, 16, Fehler!, Die %SGLDLL% konnte nicht geladen werden!`nDie Anwendung wird beendet!
ExitApp
}
Return HMOD
}
; ======================================================================================================================
; Funktion: Authentisierung des Benutzer gegen die SGL DLL.
; Parameter:
; AuthentCode Array mit zwölf 32-bittigen Integerwerten entsprechend dem 'authentication code' des Benutzers.
; Rückgabewerte:
; Bei Erfolg: 0x0000 (SGL_SUCCESS)
; Bei Fehler: 0x0006 (SGL_AUTHENTICATION_FAILED)
; Anmerkungen:
; Die Funktion muss einmal erfolgreich aufgerufen werden, bevor andere DLL-Funktionen genutzt werden können.
; ======================================================================================================================
SGL_Authent(AuthentCode) {
; MSVCRT Zufallszahlengenerator initialisieren
DllCall("msvcrt.dll\srand", "UInt", SGL_Rand())
; Zwei Zufallszahlen erzeugen
RandNumLo := SGL_Rand()
RandNumHi := SGL_Rand()
; Variable Randnum erzeugen und füllen
VarSetCapacity(RandNum, 8, 0)
NumPut(RandNumLo, RandNum, 0, "UInt")
NumPut(RandNumHi, RandNum, 4, "UInt")
; Variable AppRandNum erzeugen und füllen
VarSetCapacity(AppRandNum, 8, 0)
NumPut(RandNumLo, AppRandNum, 0, "UInt")
NumPut(RandNumHi, AppRandNum, 4, "UInt")
; Variable LibRandNum erzeugen und mit Nullwerten initialiseren
VarSetCapacity(LibRandNum, 8, 0)
; Variable AuthentLocal erzeugen und mit den ersten 8 Werten aus AuthentCode füllen
VarSetCapacity(AuthentLocal, 32, 0)
Addr := &AuthentLocal
Loop, 8
Addr := NumPut(AuthentCode[A_Index], Addr + 0, "UInt")
; Variable TeaKey erzeugen und mit den letzten 4 Werten aus AuthentCode füllen
TeaKey := [AuthentCode[9], AuthentCode[10], AuthentCode[11], AuthentCode[12]]
; Dll-Funktion SglAuthentA aufrufen
RetCode := DllCall(SGLDLL . "\SglAuthentA", "Ptr", &AuthentLocal, "Ptr", &AppRandNum, "Ptr", &LibRandNum, "UInt")
; Ergebnis prüfen und bei Fehler aussteigen
If (RetCode <> SGL_SUCCESS)
Return SGL_AUTHENTICATION_FAILED . " - SglAuthentA"
; Variable RandNum mit TeaKey verschlüsseln
SGL_TeaEncipher(RandNum, RandNum, TeaKey)
; Prüfen, ob das Ergebnis mit der Variablen AppRandNum übereinstimmt, wenn nicht, aussteigen
If (NumGet(RandNum, 0, "UInt") <> NumGet(AppRandNum, 0, "UInt"))
|| (NumGet(RandNum, 4, "UInt") <> NumGet(AppRandNum, 4, "UInt"))
Return SGL_AUTHENTICATION_FAILED . " - SGL_SGL_TeaEncipher 1"
; Variable LibRandNum mit TeaKey verschlüsseln
SGL_TeaEncipher(LibRandNum, LibRandNum, TeaKey)
; DLL-Funktion SglAuthentB aufrufen
RetCode := DllCall(SGLDLL . "\SglAuthentB", "Ptr", &LibRandNum, "UInt")
; Ergebnis prüfen und bei Fehler aussteigen
If (RetCode <> SGL_SUCCESS)
Return SGL_AUTHENTICATION_FAILED . " - " . RetCode . " - " . ErrorLevel . " - SglAuthentB"
; Alles ist gut!
Return SGL_SUCCESS
}
; ======================================================================================================================
; Interne Hilfsfunktionen
; ======================================================================================================================
SGL_TeaEncipher(ByRef InData, ByRef OutData, ByRef Key) {
Static Delta := 0x9E3779B9
; Lokale Variablen initialisieren
Y := NumGet(InData, 0, "UInt")
Z := NumGet(InData, 4, "UInt")
A := Key[1]
B := Key[2]
C := Key[3]
D := Key[4]
Sum := 0
N := 32
; Verschlüsseln
Loop, % N {
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)))
}
; Ergebnis in die Variable OutData schreiben
NumPut(Y, OutData, 0, "UInt")
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)
}
; ======================================================================================================================
Mein Test Skript
Code: Select all
#NoEnv
#Include SGL.ahk
; 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()
MsgBox, 0, Test SGL_Authent(), % SGL_Authent(AuthentCode)
ExitApp