Hallo erstmel... Und meine erste Frage

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

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

Hallo erstmel... Und meine erste Frage

03 Jul 2014, 08:16

Halli hallo zusammen.

Ich bin in einigen AHK Foren unterwegs (gewesen), in denen es aber
nach und nach recht still wurde.

Nun habe ich aber ein konkretes Problem, für das ich selber keine Lösung finde
und hoffe, dass mir hier weiter geholfen werden kann.

Ich habe ein Programm, das komplett in AHK (v1.1.13.1) geschrieben wurde und
das mit einem Dongle der Firma SGLock (http://www.sg-lock.com/de/index.php)
geschützt werden soll.
Mir ist bekannt UND bewusst, dass der AHK Compiler nicht verschlüsselt und
man natürlich mit dem entsprechenden Willen dahinter den Sourcecode wieder
sichtbar machen könnte. Daher geht es nicht um die Frae nach dem 'Cracken'.

Die Einbindung dieses Dongles geschieht einfach per DLL und es liegen Beispiele
zur Implementierung in diversen SPrachen vor (siehe Handbuch:
http://www.sg-lock.com/download/SG-Lock_Manual_Deu.pdf)

Ich habe meine ersten Versuche mit den C++ Beispielen (Seite 43, Kapitel 6.1.1)
gemacht, komme aber nicht weiter.
Es sieht so aus, dass die Funktion SGLAuthent in das zu schützende Programm
eingebaut werden muss. Von dort aus mus zunächst einmal ei 48 Byte langer
Schlüssel (12 x 8 Bytes in einem Array) an die DLL gesendet werden.
Vorher beantwortet diese JEDEN Zugriff mit einer Fehlermeldung.
Sie tut quasi so, als wäre gar kein Dongle vorhanden und stellt sich 'doof'.
Erst nach der Authentifikation ist die DLL dann 'ansprechar' und damit auch das Dongle.

Ich habe testweise (und ohne an eine Chance auf Erfolg zu glauben) die Zeile

Code: Select all

#Include SglW32.h
in mein Script gebaut und war erstaunt, dass ich keine Fehlermedlung bekomme
(schmunzel). Dass die Datei 'included' wird sehe ich daran, dass wenn ich einen Fehler einbaue, AHK diesen bemeckert.

Spaß beiseite :D
Ich wäre Euch dankbar, wenn mir jemand dabei helfen könnte, dieses Ding zu (haha) knacken.

Irgendwo in einem der vielen Forenbeiträge habe ich etwas von GitHub
(https://github.com/AutoHotkey/AutoHotkey) gelesen.
Ist dies in dieser Sache dienlich? Wenn ja, inwiefern ist es einzubinden?

Ich sage schon mal ein SEHR DICKES DANKESCHÖN an alle, die diesen langen Text gelesen haben.

Gucky.
toralf
Posts: 792
Joined: 27 Apr 2014, 21:08
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

03 Jul 2014, 08:46

Du wirst sich mit DllCall() beschaeftigen muessen.
Damit kannst Du die Daten uebergeben und Daten zurueckbekommen.
In dem API Handbuch siehst Du welche Werte die DLL Funktionen erwarten und welche Typen es sind. Diese Typen musst Du in AHK Typen uebersetzen.
Die Werte der Rueckgabewerte solltest Du in irgend einer Datei die in den Beispielen enthalten sien sollte finden.
Ich empfehle einen Wrapper fuer die DLL zu schreiben. Dann koennen auch andere Nutzer dieses spaeter verwenden.
ciao
toralf
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 03:00

Hmmm, harter Stoff.

Wenn Du den Dongle ansprechen willst, brauchst Du zunächst einmal eine zur AHK-Version passende DLL (x86/x64); es gibt wohl nur eine 32-Bit DLL:

Die würde ich mit LoadLibrary genau einmal laden DllHandle := DllCall("Kernel32.dll\LoadLibrary", "Str", DllPfad, "UPtr"), falls sie sich während des Ladens initialisiert.

Dann kannst Du die API-Funktionen (hoffentlich) per DllCall aufrufen. Für SglAuthent könnte das dann so aussehen:

Code: Select all

#NoEnv
SetBatchLines, -1

SGL_SUCCESS := 0 ; http://www.sg-lock.com/download/SG-Lock_Manual_Deu.pdf -> 4.6

DllPfad := "SglW32.dll" ; wenn die DLL in System32 liegt, sonst Ordner ergänzen
DllHandle := DllCall("Kernel32.dll\LoadLibrary", "Str", DllPfad, "UPtr")

; AuthentCodeArray definieren und füllen -> 12 Integerwerte a 4 Byte
AuthentCodeArray := [1234, 2345, 3456, 4567, 5678, 6789, 7790, 0123, 1234, 2345, 3456, 4567]

; AuthentCode Variable in einer Länge von 48 Bytes erzeugen ...
VarSetCapacity(AuthentCode, 48, 0)
; ... und aus dem Array füllen
Addr := &AuthentCode ;  >>>>> &AuthentCodeArray war falsch!!!
For Each, Value In AuthentCodeArray
   Addr := NumPut(Value, Addr + 0, "UInt")
   
; Jetzt kann der DllCall folgen: ULONG SglAuthent (ULONG *AuthentCode ) ;
ReturnValue := DllCall("SglW32.dll\SglAuthent", "Ptr", AuthentCode, "UInt")
If (ReturnValue <> SGL_SUCCESS)
   MsgBox, 0, Error, Fehler bei SglAuthent = %ReturnValue%
; ...
*ungetestet*
Last edited by just me on 04 Jul 2014, 04:13, edited 1 time in total.
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 03:29

Der erste Versuch war leider unvollständig!
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 04:15

Noch mal hallo!

Ich habe oben im Beispielcode eine Zeile berichtigt: Addr := &AuthentCode ; >>>>> &AuthentCodeArray war falsch!!!
Tut mir leid!
User avatar
Gucky_87
Posts: 345
Joined: 03 Jul 2014, 05:09

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 04:46

@ just me:
Du mnusst Dich hier wohl nicht für einen Fehler rechtfertigen!
Wir alle machen Fehler und sei Dir gewiss:
Du kannst Dir nciht vorstellen, wie froh ich bin, dass sich jemand
dieses (meines) Problemes überhaupt annimmt.
Danke! Danke! Danke!


Ich habe auch einen Fehler gemacht, nämlcih ich war zu dämlich
AHK zu installieren :D
Auch wenn ich hier einen 64 Bit Rechner gerade habe mit Win7, so
muss ich doch die 32 Bit AHK Version benutzen, da die Rechner, auf
denen das Programm nachher laufen soll, zum größten Teil (hat
technische Gründe) noch immer mit XP 32 Bit rennen :P

Daher jus ich natürlich die Scripte als 32 Bit EXEs compilieren.
Kopfklatsch - Hehe

So, nun will ich Deinen Code mal testen und Dir dann sagen, ob
es klappert oder nicht. Nochmal ein Danke und zwar ein FETTES!


EDIT:
Noch eine Frage:
Wenn ich also 32 Bit Programme erzeugen möchte, muss, darf oder
brauche ich dann dennoch die folgende Zeile?

Code: Select all

DllHandle := DllCall("Kernel32.dll\LoadLibrary", "Str", DllPfad, "UPtr")
So wie ich es verstehe, sorgt die doch dafür, dass auf einem 64 Bit System
eine 32 Bit DLL/EXE geladen wird, oder irre ich?
BTW 1: Ich habe AHK nun in der Version 1.1.15.1 (Unicode, 32 Bit) installiert.
BTW 2: Ich bastel gerade mit Deinem Code herum. Bisher gibt es noch keine
Fehlermeldung, allerdings ist der Returnwert aber auch noch leer (also nicht 0,
1, oder sonstwas). Aber bitte nicht falsch verstehen!
Das liegt wohl daran, dass bei der Abfrage

Code: Select all

If (ReturnValue <> SGL_SUCCESS)
   MsgBox, 0, Error, Fehler bei SglAuthent = %ReturnValue%
Ein leerer String übergeben wird. Du hattest oben ja SGL_SUCCESS := 0 definiert, es MÜSSTE an sich also 0 rauskommen, woraus folgt, dass "" übergeben wird.

Das soll ekin Drängeln sein, sondern nur ein Feedback.


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

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 05:52

Hallo,

Du kannst AHK 32-Bit nicht mit einer 64-Bit DLL verwenden, oder auch umgekehrt. Die API-Funktion LoadLibrary sorgt dafür, dass eine DLL in den Adressraum einer Anwendung geladen wird. Das erledigt die AHK-Funktion DllCall() notfalls auch, wenn es noch nicht passiert ist, entlädt sie aber in diesem Fall nach dem Aufruf auch gleich wieder.

Nun gibt es DLLs, die sich beim Laden initializieren, d.h. bestimmte interne Werte auf Grundstellungen setzen. Wenn Du ohne LoadLibrary arbeitest, geschieht das bei jedem DllCall() Aufruf, und wenn die DLL dann auf Ergebnisse vorheriger Funktionsaufrufe zurückgreifen will, sind die möglicherweise schon wieder initialisiert. Das löst dann oft eine interessante Fehlersuche aus. Im Zweifel sollte man deshalb immer LoadLibrary verwenden.

Wenn Du prüfen willst, ob die DLL überhaupts geladen werden konnte, füge nach LoadLibrary für einen Test einfach folgende Anweisung ein:

MsgBox, 0, LoadLibrary, %DllHandle% - %ErrorLevel% - %A_LastError%

Als DllHandle sollte ein numerischer Wert größer 0 und als ErrorLevel 0 ausgegeben werden, und wenn das so ist, ist die Welt in Ordnung.


Ähnliches kannst Du nach dem DllCall() für SglAuthent machen:

MsgBox, 0, SglAuthent , %ReturnValue% - %ErrorLevel% - %A_LastError%

Hier sollte als ReturnValue 0 (= SGL_SUCCESS) und als ErrorLevel ebenfalls 0 ausgegeben werden, wenn der Aufruf erfolgreich war.
User avatar
Gucky_87
Posts: 345
Joined: 03 Jul 2014, 05:09

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 06:50

just me wrote:Hallo,

Du kannst AHK 32-Bit nicht mit einer 64-Bit DLL verwenden, oder auch umgekehrt. Die API-Funktion LoadLibrary sorgt dafür, dass eine DLL in den Adressraum einer Anwendung geladen wird. Das erledigt die AHK-Funktion DllCall() notfalls auch, wenn es noch nicht passiert ist, entlädt sie aber in diesem Fall nach dem Aufruf auch gleich wieder.
Ahh :D Wieder was gelernt. Wobei mir schon klar ist, dass man 32- und 64 Bit nicht mischen kann (darf, sollte). Daher war ja mein Fehler auch, dass ich AHK als 64 Bit installiert hatte, was ich dann eben bemerkt und korriguert habe.
... Im Zweifel sollte man deshalb immer LoadLibrary verwenden.

Wenn Du prüfen willst, ob die DLL überhaupts geladen werden konnte, füge nach LoadLibrary für einen Test einfach folgende Anweisung ein:
MsgBox, 0, LoadLibrary, %DllHandle% - %ErrorLevel% - %A_LastError%

Als DllHandle sollte ein numerischer Wert größer 0 und als ErrorLevel 0 ausgegeben werden, und wenn das so ist, ist die Welt in Ordnung.
Dies ist der Fall bei dem Script. Also ein erster Erfolg.
Ähnliches kannst Du nach dem DllCall() für SglAuthent machen:
MsgBox, 0, SglAuthent , %ReturnValue% - %ErrorLevel% - %A_LastError%

Hier sollte als ReturnValue 0 (= SGL_SUCCESS) und als ErrorLevel ebenfalls 0 ausgegeben werden, wenn der Aufruf erfolgreich war.
Ok, wird gemacht...

EDIT:

Erledigt mit folgendem Ergebnis:
Wenn ich den AuthentCode, der 12 x 4 Byte lang ist (nach dem Muster 0x11111111, 0x22222222, 0x33333333,...) in das Array einfüge (zunächst ohne die führenden "0x", dann kommt als Rückgabewert ein leerer String (also nix), für ErrorLevel -4 und für LastError eine 0.
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 07:20

Das führende "0x" muss schon sein, weil sonst ein Array aus Zeichenketten und nicht aus numerischen Werten aufgebaut wird.

ErrorLevel -4 heißt: Die Funktion wurde in der angegebenen DLL nicht gefunden.

Ich muss noch darüber nachdenken.
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 07:23

Bevor ich es wieder vergesse: Wir haben :arrow: hier dank Ragnar eine wunderbare deutsche Onlinehilfe.
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 07:35

Fehler #2:
ReturnValue := DllCall("SglW32.dll\SglAuthent", "Ptr", &AuthentCode, "UInt")
(hier muss die Adresse (pointer) der Variablen übergeben werden).

Das löst aber nicht das Problem.

Kannst/Darfst Du die Header-Datei SglW32.h hier zeigen?
User avatar
Gucky_87
Posts: 345
Joined: 03 Jul 2014, 05:09

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 08:46

Klar darf ich, die ist kein Geheimnis, da der Authentcode und noch etewas anderes relevant sind.

Biddeschööööön :D

Code: Select all

/****************************************************************************
 SGLW32.H / 11.2005 / MS-WINDOWS W32 (95/98/ME/NT/2000/XP)

 2005 (C) SG Intec Ltd & Co KG

*******************************************************************************/

#define SGL_SUCCESS                         0x0000
#define SGL_DGL_NOT_FOUND                   0x0001
#define SGL_LPT_BUSY                        0x0002
#define SGL_LPT_OPEN_ERROR                  0x0003
#define SGL_NO_LPT_PORT_FOUND               0x0004
#define SGL_AUTHENTICATION_REQUIRED         0x0005
#define SGL_AUTHENTICATION_FAILED           0x0006
#define SGL_FUNCTION_NOT_SUPPORTED          0x0007
#define SGL_PARAMETER_INVALID				0x0008
#define SGL_SIGNATURE_INVALID				0x0009
#define SGL_USB_BUSY				        0x000A



#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif


/*******************************************************************/
/*                                                                 */
/*  SG-Lock API basic functions (supported by all SG-Lock moduls)  */
/*                                                                 */
/*******************************************************************/
	
unsigned  int
SglAuthent(
  unsigned  int *AuthentCode );
	
unsigned  int __stdcall
SglSearchLock(
   unsigned  int ProductId);             // The ProductId value programmed
                                             // of all moduls is "1". Change it
					     // to your needs!
unsigned  int __stdcall
SglReadSerialNumber(
   unsigned  int ProductId,
   unsigned  int *SerialNumber);         // pointer to 1 DWORD, read only!

// administration functions
unsigned  int __stdcall
SglReadProductId(
   unsigned  int *ProductIdPtr);         // pointer to 1 DWORD
    
unsigned  int __stdcall
SglWriteProductId(
   unsigned  int OldProductId,
   unsigned  int NewProductId);

/*******************************************************************/
/*                                                                 */
/*  SG-Lock API extended functions (supported only by L3,L4,U3,U4) */
/*                                                                 */
/*******************************************************************/

// Memory functions
unsigned  int __stdcall
SglReadData(
   unsigned  int ProductId,
   unsigned  int Address,         // L3,U3: 0-63; L4,U4: 0-255
   unsigned  int Count,           // L3,U3: 1-63; L4,U4: 1-255
   unsigned  int *Data);          // data array with minimum size 
                                      // of requested data  

unsigned  int __stdcall
SglWriteData(
   unsigned  int ProductId,
   unsigned  int Address,         // L3,U3: 0-63; L4,U4: 0-255
   unsigned  int Count,           // L3,U3: 1-63; L4,U4: 1-255
   unsigned  int *Data);          // data array with minimum size
                                      // of requested data  

// Counter functions
unsigned  int __stdcall
SglReadCounter(
   unsigned  int ProductId,
   unsigned  int CntNum,          // number of counter: L3,U3: 0-15
   unsigned  int *Data);          // L4,U4: 0-63, *Data is a pointer to 1 DWORD

unsigned  int __stdcall
SglWriteCounter(
   unsigned  int ProductId,
   unsigned  int CntNum,          // number of counter: L3,U3: 0-15
   unsigned  int Data);           // L4,U4: 0-63, Data is the counter value

// Cryptographic and signing functions
unsigned  int __stdcall
SglCryptLock(
   unsigned  int ProductId,
   unsigned  int KeyNum,          // number of key: L2, U2: 0 ; L3,U3: 0-1 ; L4,U4: 0-15
   unsigned  int CryptMode,       // 0=encrypt, 1=decrypt
   unsigned  int BlockCnt,        // number of 8-Bytes blocks to proccess
   unsigned  int *Data);          // data to process, size must be BlockCnt * 8 Bytes

// Values valid for parameter MODE of Sign functions
#define SGL_SIGNATURE_GENERATE 			0
#define SGL_SIGNATURE_VERIFY 			1

unsigned  int
SglSignData( 
	unsigned  int ProductId,
	unsigned  int *AppSignKey,
	unsigned  int LockSignKeyNum,
	unsigned  int Mode,
	unsigned  int LockSignInterval,
	unsigned  int DataLen,
	unsigned  int *Data,
	unsigned  int *Signature);


unsigned  int
SglSignDataApp( 
	unsigned  int *AppSignKey,
	unsigned  int Mode,
	unsigned  int DataLen,
	unsigned  int *Data,
	unsigned  int *Signature);

unsigned  int
SglSignDataLock( 
	unsigned  int  ProductId,
	unsigned  int  LockSignKeyNum,
	unsigned  int  Mode,
	unsigned  int  DataLen,
	unsigned  int  *Data,
	unsigned  int  *Signature);

unsigned  int
SglSignDataComb( 
	unsigned  int ProductId,
	unsigned  int *AppSignKey,
	unsigned  int LockSignKeyNum,
	unsigned  int Mode,
	unsigned  int LockSignInterval,
	unsigned  int DataLen,
	unsigned  int *Data,
	unsigned  int *Signature);



// Administrativ functions
unsigned  int __stdcall
SglWriteKey(
   unsigned  int ProductId,       // L2,U2: Key fixed - that means not writeable
   unsigned  int KeyNum,          // number of key: L3,U3: 0-1 ; L4,U4: 0-15 
   unsigned  int *Key);           // 128-Bit (16 Bytes) Key, write only!!! 

unsigned  int __stdcall
SglReadConfig(
   unsigned  int ProductId,
   unsigned  int Category,		// see below
   unsigned  int *Data);		// has to be an array of 8 DWord/32bit values 


// possible parameters for 'Category'
#define SGL_READ_CONFIG_LOCK_INFO			0x0000    // version of dongle hardware

// possible returns    
// Data[0] = ModelId ( see below )
#define SGL_CONFIG_LOCK_SERIES_2			0x0001
#define SGL_CONFIG_LOCK_SERIES_3			0x0002
#define SGL_CONFIG_LOCK_SERIES_4			0x0003
   
// Data[1] = Interface ( see below )  
#define SGL_CONFIG_INTERFACE_USB			0x0000
#define SGL_CONFIG_INTERFACE_LPT			0x0001

// Data[2] = Software Version of SG-Lock ( high word = major version, low word = minor version )
// Data[3] = Hardware Version of SG-Lock ( high word = major version, low word = minor version ) 
// Data[4] = Serial Number
// Data[5] = Memory Size ( size of memory in DWords !!)
// Data[6] = Counter Count
// Data[7] = 128 bit Key Count

/*******************************************************************/
/*                                                                 */
/*           End of SG-Lock API functions                          */
/*                                                                 */
/*******************************************************************/

/*******************************************************************/
/* helping functions that have to be included, but should not be   */
/* called directly from SG-Lock using application                  */
/*******************************************************************/

unsigned  int __stdcall
SglAuthentA(
  unsigned int *AuthentCode,
  unsigned int *AppRandNum,
  unsigned int *LibRandNum );

unsigned  int __stdcall
SglAuthentB(
  unsigned  int   *LibRandNum );


void SglTeaEncipher(
    const unsigned int *const   InData,
    unsigned int *const         OutData,
    const unsigned int * const  Key);



void SglTeaDecipher(
    const unsigned int *const   InData,
    unsigned int *const         OutData,
    const unsigned int * const  Key);









unsigned  int
SglAuthent(
  unsigned int *AuthentCode ) {

  
  unsigned int RandNum[2];
  unsigned int AppRandNum[2];
  unsigned int LibRandNum[2];
  unsigned int AuthentCodeLocal[8];
  unsigned int RetCode;
  unsigned int i;

  
  for( i=0; i<8; i++ ) {
    AuthentCodeLocal[i] = AuthentCode[i];
    AuthentCode[i]= (rand()<<16) | rand();
  }
  
  srand(AuthentCode[0]);
  RandNum[0] = (rand()<<16) | rand();
  RandNum[1] = (rand()<<16) | rand();

  AppRandNum[0] = RandNum[0];
  AppRandNum[1] = RandNum[1];
  
  RetCode = SglAuthentA(
	      AuthentCodeLocal,
	      AppRandNum,
	      LibRandNum);

  for( i=0; i<8; i++ ) {
    AuthentCode[i] = AuthentCodeLocal[i];
  }

  if( RetCode != SGL_SUCCESS ) {
      return SGL_AUTHENTICATION_FAILED;
  }  
  
  SglTeaEncipher( RandNum, RandNum, &AuthentCode[8] );

  if( (RandNum[0] != AppRandNum[0] ) || 
      (RandNum[1] != AppRandNum[1] ) ) {

      return SGL_AUTHENTICATION_FAILED;
      
  }

  SglTeaEncipher( LibRandNum, LibRandNum, &AuthentCode[8] );
  
  RetCode = SglAuthentB(
		  LibRandNum);

  if( RetCode != SGL_SUCCESS ) {
      return SGL_AUTHENTICATION_FAILED;
  }  
  
  return SGL_SUCCESS;

}


// Signing functions
unsigned  int
SglSignData( 
	unsigned int ProductId,
	unsigned int *AppSignKey,
	unsigned int LockSignKeyNum,
	unsigned int Mode,
	unsigned int LockSignInterval,
	unsigned int DataLen,
	unsigned int *Data,
	unsigned int *Signature ) {

	return SglSignDataComb(
					ProductId,
					AppSignKey,
					LockSignKeyNum,
					Mode,
					LockSignInterval,
					DataLen,
					Data,
					Signature );

}

#define SGL_SIGN_DATA_INITVECTOR_1   0xC4F8424E
#define SGL_SIGN_DATA_INITVECTOR_2   0xAB99A60C
#define SGL_SIGN_DATA_FILLUPDATA     0xF6A67A11

unsigned  int
SglSignDataApp( 
	unsigned int *SignKey,
	unsigned int Mode,
	unsigned int DataLen,
	unsigned int *Data,
	unsigned int *Signature ) {


	unsigned int FeedBackRegister[2];
	unsigned int DataIndexMax;
	unsigned int i;
	unsigned  int   RetCode;

	if( DataLen == 0 ) {
		return SGL_PARAMETER_INVALID;
	}
	
	FeedBackRegister[0]= SGL_SIGN_DATA_INITVECTOR_1;
	FeedBackRegister[1]= SGL_SIGN_DATA_INITVECTOR_2;
	
	DataIndexMax= DataLen - 1;
	
	for( i=0; i<DataIndexMax; i=i+2 ) {
		FeedBackRegister[0]= Data[i]   ^ FeedBackRegister[0];
		FeedBackRegister[1]= Data[i+1] ^ FeedBackRegister[1];
		SglTeaEncipher( FeedBackRegister, FeedBackRegister, SignKey );
	}

	if( (DataLen % 2)==1 ) {
		FeedBackRegister[0]= Data[i]    ^ FeedBackRegister[0];
		FeedBackRegister[1]= SGL_SIGN_DATA_FILLUPDATA ^ FeedBackRegister[1];
		SglTeaEncipher( FeedBackRegister, FeedBackRegister, SignKey );
	}

	switch( Mode ) {
		
		case SGL_SIGNATURE_GENERATE:
			Signature[0]= FeedBackRegister[0];
			Signature[1]= FeedBackRegister[1];
			RetCode= SGL_SUCCESS;
			break;

		case SGL_SIGNATURE_VERIFY:
			if(( Signature[0] == FeedBackRegister[0] ) &&
			   ( Signature[1] == FeedBackRegister[1] )) {
				RetCode= SGL_SUCCESS;
			} else {
				RetCode= SGL_SIGNATURE_INVALID;
			}

			break;

		default:
				RetCode= SGL_PARAMETER_INVALID;

	}

	return RetCode;

}


unsigned  int
SglSignDataLock( 
	unsigned  int ProductId,
	unsigned  int SignKeyNum,
	unsigned  int Mode,
	unsigned  int DataLen,
	unsigned  int *Data,
	unsigned  int *Signature ) {


	unsigned  int   FeedBackRegister[2];
	unsigned  int 	DataIndexMax;
	unsigned  int   i;
	unsigned  int   RetCode;

	
	if( DataLen == 0 ) {
		return SGL_PARAMETER_INVALID;
	}

	
	FeedBackRegister[0]= SGL_SIGN_DATA_INITVECTOR_1;
	FeedBackRegister[1]= SGL_SIGN_DATA_INITVECTOR_2;
	
	DataIndexMax= DataLen - 1;
	
	for( i=0; i<DataIndexMax; i=i+2 ) {
		FeedBackRegister[0]= Data[i]   ^ FeedBackRegister[0];
		FeedBackRegister[1]= Data[i+1] ^ FeedBackRegister[1];

		RetCode= SglCryptLock(
					ProductId,
					SignKeyNum,
					0,
					1,
					FeedBackRegister);

		if( RetCode != SGL_SUCCESS ) {
			return RetCode;
		}
		
	}

	if( (DataLen % 2)==1 ) {
		FeedBackRegister[0]= Data[i]    ^ FeedBackRegister[0];
		FeedBackRegister[1]= SGL_SIGN_DATA_FILLUPDATA ^ FeedBackRegister[1];

		RetCode= SglCryptLock(
					ProductId,
					SignKeyNum,
					0,
					1,
					FeedBackRegister);

		if( RetCode != SGL_SUCCESS ) {
			return RetCode;
		}

	}

	switch( Mode ) {
		
		case SGL_SIGNATURE_GENERATE:
			Signature[0]= FeedBackRegister[0];
			Signature[1]= FeedBackRegister[1];
			RetCode= SGL_SUCCESS;
			break;

		case SGL_SIGNATURE_VERIFY:
			if(( Signature[0] == FeedBackRegister[0] ) &&
			   ( Signature[1] == FeedBackRegister[1] )) {
				RetCode= SGL_SUCCESS;
			} else {
				RetCode= SGL_SIGNATURE_INVALID;
			}
			break;

		default:
				RetCode= SGL_PARAMETER_INVALID;

	}

	return RetCode;

}


unsigned  int
SglSignDataComb( 
	unsigned  int ProductId,
	unsigned  int *AppSignKey,
	unsigned  int LockSignKeyNum,
	unsigned  int Mode,
	unsigned  int LockSignInterval,
	unsigned  int DataLen,
	unsigned  int *Data,
	unsigned  int *Signature ) {


	unsigned  int   FeedBackRegister[2];
	unsigned  int 	DataIndexMax;
	unsigned  int   i;
	unsigned  int   Interval;
	unsigned  int   RetCode;

	
	if( DataLen == 0 ) {
		return SGL_PARAMETER_INVALID;
	}
	
	if( LockSignInterval == 0 ) {
		return SGL_PARAMETER_INVALID;
	}
	
	DataIndexMax= DataLen - 1;
	Interval= 0x01L << LockSignInterval;
	

	FeedBackRegister[0]= SGL_SIGN_DATA_INITVECTOR_1;
	FeedBackRegister[1]= SGL_SIGN_DATA_INITVECTOR_2;
	
	
	for( i=0; i<DataIndexMax; i=i+2 ) {
		FeedBackRegister[0]= Data[i]   ^ FeedBackRegister[0];
		FeedBackRegister[1]= Data[i+1] ^ FeedBackRegister[1];

		if( (i % Interval) == 0 ) {
			
			RetCode= SglCryptLock(
						ProductId,
						LockSignKeyNum,
						0,
						1,
						FeedBackRegister);

			if( RetCode != SGL_SUCCESS ) {
				return RetCode;
			}
			
		} else {
			SglTeaEncipher( FeedBackRegister, FeedBackRegister, AppSignKey );
		}
		
	}

	if( (DataLen % 2)==1 ) {
		FeedBackRegister[0]= Data[i]    ^ FeedBackRegister[0];
		FeedBackRegister[1]= SGL_SIGN_DATA_FILLUPDATA ^ FeedBackRegister[1];

		if( (i % Interval) == 0 ) {

			RetCode= SglCryptLock(
						ProductId,
						LockSignKeyNum,
						0,
						1,
						FeedBackRegister);

			if( RetCode != SGL_SUCCESS ) {
				return RetCode;
			}

		} else {
			SglTeaEncipher( FeedBackRegister, FeedBackRegister, AppSignKey );
		}

	}

	switch( Mode ) {
		
		case SGL_SIGNATURE_GENERATE:
			Signature[0]= FeedBackRegister[0];
			Signature[1]= FeedBackRegister[1];
			RetCode= SGL_SUCCESS;
			break;

		case SGL_SIGNATURE_VERIFY:
			if(( Signature[0] == FeedBackRegister[0] ) &&
			   ( Signature[1] == FeedBackRegister[1] )) {
				RetCode= SGL_SUCCESS;
			} else {
				RetCode= SGL_SIGNATURE_INVALID;
			}
			break;

		default:
				RetCode= SGL_PARAMETER_INVALID;

	}

	return RetCode;

}


/****************************************************************************/

void SglTeaEncipher(
    const unsigned int *const   InData,
    unsigned int  *const         OutData,
    const unsigned int * const  Key) {
    
    register unsigned int y=InData[0];
    register unsigned int z=InData[1];
    register unsigned int sum=0;
    register unsigned int delta=0x9E3779B9;
    register unsigned int a=Key[0];
    register unsigned int b=Key[1];
    register unsigned int c=Key[2];
    register unsigned int d=Key[3];
    register unsigned int n=32;

    
    while( n-->0 ) {
        sum += delta;
        y += (z << 4)+a ^ z+sum ^ (z >> 5)+b;
        z += (y << 4)+c ^ y+sum ^ (y >> 5)+d;
    }

    OutData[0]=y;
    OutData[1]=z;
    
}



void SglTeaDecipher(
    const unsigned  int *const   InData,
    unsigned  int *const         OutData,
    const unsigned  int * const  Key) {
    
    register unsigned int y=InData[0];
    register unsigned int z=InData[1];
    register unsigned int sum=0xC6EF3720;
    register unsigned int delta=0x9E3779B9;
    register unsigned int a=Key[0];
    register unsigned int b=Key[1];
    register unsigned int c=Key[2];
    register unsigned int d=Key[3];
    register unsigned int n=32;

    /* sum = delta<<5, in general sum = delta * n */

    while( n-->0 ) {
        z -= (y << 4)+c ^ y+sum ^ (y >> 5)+d;
        y -= (z << 4)+a ^ z+sum ^ (z >> 5)+b;
        sum -= delta;
    }
   
    OutData[0]=y;
    OutData[1]=z;
    
}
#ifdef __cplusplus
}
#endif

Laut einem Mitarbeiter des Herstellers ist die Funktion (wie ich auch EIngangs schon erklärte) offenbar nicht in der dll vorhnden und muss quasi überdiese Headerdatei manuell ins Programm eingebaut werden.
Das würde ja evtl. erklären, wieso ich keinen Rückgabewert bzw. einen Fehlercode bekomme.

Wobei mir DANN aber nicht klar ist, wie der AuthCode IN die Dll kommt?
Irgendwie muss die den doch "erkennen", bzw. mitbekommen, dass ich (mein Programm) "darf"?
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 09:09

Hmmm, sie ist schon da, aber möglicherweise meint er, dass die Funktion nicht exportiert wird. Vielleicht guckt ja mal ein C-Experte rein, der sagen kann, wie man die Funktion erreichen kann. Ich weiß im Augenblick nicht weiter.
User avatar
Gucky_87
Posts: 345
Joined: 03 Jul 2014, 05:09

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 09:45

Du, bisher habe ich alleine heute doch schon mehr erreicht UND mehr
Hilfe bekommen als anderswo. Nun ist erstmal WE und ich wünsche Dir
ein schönes soclhes.

Nächste Woche ist auch wieder ein Montag, Dienstag, Mittwoch........

BTW: Haben wir hier vllt. auch einen C++ Experten, der diese Frage
sicher beantworten könnte?

Es muss auch nciht unbedingt C/C++ sein, da ich auch Beispiele in Delphi,
Fortran, VisualBasic, Pascal und anderen Sprachen habe. Allerdings kann
ich ausschließlich AHK, wenns nicht zu schwer wird (wie jetzt - zwinker).

Allen ein schönes WE,

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

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 09:52

Bevor wir uns ins Wochenende verabschieden:

Ich habe mir die Header-Datei und die DLL noch einmal angeschaut (ein kleines bisschen C kann ich schon lesen), und ich fürchte, die Funktion kann tatsächlich nicht per DllCall() aufgerufen werden. Es sieht so aus, als müsste man die letzte in der Header-Datei mit Namen SglAuthent definierte Funktion per AHK nachbilden, und dafür reicht es bei mir nicht. Vielleicht irre ich mich aber auch!?!

Schönes Wochenende!

just me
User avatar
nnnik
Posts: 4475
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

04 Jul 2014, 15:24

Code: Select all

unsigned  int SglAuthent(unsigned int *AuthentCode ) {

  
  unsigned int RandNum[2];
  unsigned int AppRandNum[2];
  unsigned int LibRandNum[2];
  unsigned int AuthentCodeLocal[8];
  unsigned int RetCode;
  unsigned int i;

  
  for( i=0; i<8; i++ ) {
    AuthentCodeLocal[i] = AuthentCode[i];
    AuthentCode[i]= (rand()<<16) | rand();
  }
  
  srand(AuthentCode[0]);
  RandNum[0] = (rand()<<16) | rand();
  RandNum[1] = (rand()<<16) | rand();

  AppRandNum[0] = RandNum[0];
  AppRandNum[1] = RandNum[1];
  
  RetCode = SglAuthentA(AuthentCodeLocal, AppRandNum, LibRandNum);

  for( i=0; i<8; i++ ) {
    AuthentCode[i] = AuthentCodeLocal[i];
  }

  if( RetCode != SGL_SUCCESS ) {
      return SGL_AUTHENTICATION_FAILED;
  }  
  
Das ist der Abschnitt in dem die Funktion definiert ist.
Recommends AHK Studio
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

05 Jul 2014, 01:55

@nnnik:
Ja, nur ist sie leider etwas länger

Code: Select all

unsigned  int
SglAuthent(
  unsigned int *AuthentCode ) {

  
  unsigned int RandNum[2];
  unsigned int AppRandNum[2];
  unsigned int LibRandNum[2];
  unsigned int AuthentCodeLocal[8];
  unsigned int RetCode;
  unsigned int i;

  
  for( i=0; i<8; i++ ) {
    AuthentCodeLocal[i] = AuthentCode[i];
    AuthentCode[i]= (rand()<<16) | rand();
  }
  
  srand(AuthentCode[0]);
  RandNum[0] = (rand()<<16) | rand();
  RandNum[1] = (rand()<<16) | rand();

  AppRandNum[0] = RandNum[0];
  AppRandNum[1] = RandNum[1];
  
  RetCode = SglAuthentA(
         AuthentCodeLocal,
         AppRandNum,
         LibRandNum);

  for( i=0; i<8; i++ ) {
    AuthentCode[i] = AuthentCodeLocal[i];
  }

  if( RetCode != SGL_SUCCESS ) {
      return SGL_AUTHENTICATION_FAILED;
  }  
  
  SglTeaEncipher( RandNum, RandNum, &AuthentCode[8] );

  if( (RandNum[0] != AppRandNum[0] ) || 
      (RandNum[1] != AppRandNum[1] ) ) {

      return SGL_AUTHENTICATION_FAILED;
      
  }

  SglTeaEncipher( LibRandNum, LibRandNum, &AuthentCode[8] );
  
  RetCode = SglAuthentB(
        LibRandNum);

  if( RetCode != SGL_SUCCESS ) {
      return SGL_AUTHENTICATION_FAILED;
  }  
  
  return SGL_SUCCESS;

}
und enthält noch weitere Aufrufe für Funktionen, von denen nach Allem, was ich herausfinden konnte, nur SglAuthentA() und SglAuthentB() von der DLL exportiert werden.

@Gucky_87:
Kannst Du auch noch die im PDF erwähnte .bas Datei für VB einstellen? Vielleicht kann man das leichter 'übersetzen'.
User avatar
nnnik
Posts: 4475
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

05 Jul 2014, 05:32

Und SglTeaEncipher
Recommends AHK Studio
HotKeyIt
Posts: 2157
Joined: 29 Sep 2013, 18:35
Contact:

Re: Hallo erstmel... Und meine erste Frage

05 Jul 2014, 06:26

Hier ist mein versuch für einen Wrapper ;)

Die neueste version von AutoHotkey_H v1 wird für SGL.ahk benötigt :!: ( Untested :!: )

Code: Select all

#Include SGL.ahk
; This is the DEMO authentication code ,
; every  regular SG−Lock user gets its
; own unique authentication code.
AuthentCode := Struct("UInt[12]",[0xF574D17B,0xA94628EE,0xF2857A8F,0x69346B4A,0x4136E8F2,0x89ADC688,0x80C2C1D4,0xA8C6327C,0x1A72699A,0x574B7CA0,0x1E8D3E98,0xD7DEFDC5])

If (SGL_SUCCESS!=ReturnValue:=SglAuthent(AuthentCode))
	MsgBox, 0, Error, Fehler bei SglAuthent = %ReturnValue%
SGL.ahk
just me
Posts: 7382
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Hallo erstmel... Und meine erste Frage

05 Jul 2014, 06:45

Hallo HotKeyIt,

danke! ;) (Ich werde selbstverständlich versuchen, das nach AHK 1.1 zu portieren.)

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 3 guests