Files
PS_Dinkey/Dinkey Pro 7.6.1/Samples/WinDev/Runtime/protection check functions.txt
2026-05-06 07:47:36 +02:00

785 lines
30 KiB
Plaintext

// This code contains the following functions. Please choose the one that matches your needs:
// ProtCheck
// ProtCheckWithAlg (the function also depends on the function MyAlgorithm)
// WriteString
// ReadString
// EncryptUserData
// or the same functions but using DRIS and API data encryption
// (these functions also require the functions CryptDRIS and possibly CryptApiData and MyRWAlgorithm)
// ProtCheckEnc
// ProtCheckWithAlgEnc
// WriteStringEnc
// ReadStringEnc
// EncryptUserDataEnc
// Summary: does a standard protection check
// Syntax:
//[ <Result> = ] ProtCheck ()
// return value is 0 (success) or an error code
PROCEDURE ProtCheck()
hLib, ret_code are system int
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = PROTECTION_CHECK // standard protection check
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
Info("It worked!")
// Summary: does a standard protection check and executes an algorithm
// NB for this to work you must program at least "user algorithm" into the dongle
// NB We have used a very simple algorithm here (in the MyAlgorithm function). You must patch this with the
// sample code generated by DinkeyAdd for the algorithm that you are using. For Lite models copy the sample
// code from DinkeyLook
// Syntax:
//[ <Result> = ] ProtCheckWithAlg ()
// return value is 0 (success) or an error code
PROCEDURE ProtCheckWithAlg()
hLib, ret_code are system int
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = EXECUTE_ALGORITHM // protection check and execute specified algorithm
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.alg_number = 1
// !!!! you should remove these entries if you are using Dinkey Lite so that algorithm arguments are random
DRIS.var_a = 1 // sample values
DRIS.var_b = 2
DRIS.var_c = 3
DRIS.var_d = 4
DRIS.var_e = 5
DRIS.var_f = 6
DRIS.var_g = 7
DRIS.var_h = 8
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
DelayBeforeClosing(1000)
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
// if you want you can check the algorithm answer - however if algorithm is from your code then best to just use the answer in your code
// !!!! Make sure you have replaced the MyAlgorithm routine with the algorithm you have specified in DinkeyAdd
IF (MyAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) <> DRIS.alg_answer) THEN
Info("Dinkey protection error!", "You have not patched your algorithm in the MyAlgorithm routine")
RESULT -1
END
Info("It worked!")
// Summary:
// !!!! You should replace this function with the one generated by the
// "generate source code" button in Algorithm tab for DinkeyAdd (if you have specified an algorithm)
// or from DinkeyLook if you are using a Dinkey Lite dongle. You can modify the C code to make it compatiable with Windev.
// Syntax:
//[ <Result> = ] MyAlgorithm (<var_a> is int, <var_b> is int, <var_c> is int, <var_d> is int, <var_e> is int, <var_f> is int, <var_g> is int, <var_h> is int)
//
PROCEDURE MyAlgorithm(var_a is int, var_b is int, var_c is int, var_d is int, var_e is int, var_f is int, var_g is int, var_h is int)
RESULT var_a + var_b + var_c + var_d + var_e + var_f + var_g + var_h
// Summary: This function does a protection check and writes the string "Hello, World!" to the data area at offset 7
// In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
// NB you can easily modify the code to write a byte array instead of a string
// Syntax:
//[ <Result> = ] WriteString ()
// return value is 0 (success) or an error code
//
PROCEDURE WriteString()
hLib, ret_code are system int
OurString is fixed string on 1024 = "Hello, World!" // NB max. data write is 1K
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = WRITE_DATA_AREA // protection check and write specified data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.rw_offset = 7
DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes)
DRIS.rw_data_ptr = &OurString
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
Info("It worked!")
// Summary: This function does a protection check and reads 13 bytes of data from the data area at offset 7
// In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
// NB you can amend this code to read a byte array instead of a string if you prefer.
// Syntax:
//[ <Result> = ] ReadString ()
// return value is 0 (success) or an error code
//
PROCEDURE ReadString()
hLib, ret_code are system int
OurString is fixed string on 1024 // NB max. data read is 1K
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = READ_DATA_AREA // protection check and read data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.rw_offset = 7
DRIS.rw_length = 13
DRIS.rw_data_ptr = &OurString
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString)
// Summary: this function will do a protection check and ask the dongle to encrypt some data using encryption key 1
// It will then do another protection check & decrypt the data. NB you can modify the code to encrypt byte arrays instead of strings
// NB you can amend this code to read a byte array instead of a string if you prefer.
// Syntax:
//[ <Result> = ] EncryptUserData ()
// return value is 0 (success) or an error code
//
PROCEDURE EncryptUserData()
hLib, ret_code are system int
OurString is fixed string on 1024 = "Hello, World!" // NB max. data we can encrypt is 1K
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = ENCRYPT_USER_DATA // protection check and encrypt specified data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.data_crypt_key_num = 1
DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes)
DRIS.rw_data_ptr = &OurString
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
FreeDLL(hLib)
RESULT ret_code
END
// NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function)
// Now decrypt the same data to get the original values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = DECRYPT_USER_DATA // protection check and decrypt specified data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.data_crypt_key_num = 1
DRIS.rw_length = 13 // the length of the string (in this case 13 bytes)
DRIS.rw_data_ptr = &OurString // NB the data is encrypted at this point
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function)
Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString)
// !!!!!!!!!!! all the functions listed below encrypt all parameters to our API !!!!!!!!!!!!!!!!!!!!!
// In order for them to work properly you need to choose "Encrypt DRIS" and "Encrypt Data passed to API"
// in the Extra Security tab of DinkeyAdd. In this example, for Data Encryption I use the r/w algorithm
// but the code can be modified easily to use the 3 encryption parameters.
// !!!! please overwrite this function with the one generated by DinkeyAdd for R/W Algorithm (you will have to adapt the C code generated by DinkeyAdd)
PROCEDURE MyRWAlgorithm(var_a is int, var_b is int, var_c is int, var_d is int, var_e is int, var_f is int, nVar_g is int, nVar_h is int)
RESULT BinaryXOR(BinaryXOR(BinaryXOR(BinaryXOR(BinaryXOR(var_a, var_b), var_c), var_d), var_e), var_f)
// !!!! please overwrite this function with the one generated by DinkeyAdd
// (just modify the parameters specified in DinkeyAdd in the positiions indicated below):
// Note arrays in Windev are 1-base which makes it a real pain
PROCEDURE CryptDRIS()
i, j, k are int
bigseed, S are array of 256 1-byte unsigned int
DRIS_bytes is an array of Length(DRIS) 1-byte unsigned int
temp, t are 1-byte unsigned int
FOR i = 1 _TO_ 256 STEP 8
Transfer(&bigseed[i], &DRIS.seed1, 4)
Transfer(&bigseed[i+4], &DRIS.seed2, 4)
END
FOR i = 0 _TO_ 255
S[i+1] = i
END
j = 0
FOR i = 0 _TO_ 255
j = (j + S[i+1] + bigseed[i+1] + 123) modulo 256 // parameter 1, modify 123
temp = S[i+1]
S[i+1] = S[j+1]
S[j+1] = temp
END
Transfer(&DRIS_bytes, &DRIS, Length(DRIS)) // convert DRIS to bytes
i = 0
j = 0
FOR k = 17 _TO_ Length(DRIS)
i = (i + 1) modulo 256
j = (j + S[i+1] + 212) modulo 256 // parameter 2, modify 212
temp = S[i+1]
S[i+1] = S[j+1]
S[j+1] = temp
t = (S[i+1] + S[j+1] + 97) modulo 256 // parameter 3, modify 97
DRIS_bytes[k] = BinaryXOR(DRIS_bytes[k], S[t+1])
END
Transfer(&DRIS, &DRIS_bytes, Length(DRIS)) // convert back again
// Note arrays in Windev are 1-base which makes it a real pain
// Summary: <specify the procedure action>
// Syntax:
//CryptApiData (<data>, <enc_length> is 4-byte unsigned int, <alg_ans> is int)
PROCEDURE CryptApiData(data, enc_length is unsigned int, alg_ans is int)
i, j, k are int
bigseed, S are array of 256 1-byte unsigned int
temp, t are 1-byte unsigned int
FOR i = 1 _TO_ 256 STEP 8
Transfer(&bigseed[i], &DRIS.seed1, 4)
Transfer(&bigseed[i+4], &DRIS.seed2, 4)
END
FOR i = 0 _TO_ 255
S[i+1] = i
END
j = 0
FOR i = 0 _TO_ 255
j = (j + S[i+1] + bigseed[i+1] + BinaryAND(alg_ans, 0xff)) modulo 256
temp = S[i+1]
S[i+1] = S[j+1]
S[j+1] = temp
END
i = 0
j = 0
FOR k = 1 _TO_ enc_length
i = (i + 1) modulo 256
j = (j + S[i+1] + (BinaryAND(alg_ans, 0xff00))/256) modulo 256
temp = S[i+1]
S[i+1] = S[j+1]
S[j+1] = temp
t = (S[i+1] + S[j+1] + (BinaryAND(alg_ans, 0xff0000))/65536) modulo 256
data[k] = BinaryXOR(data[k], S[t+1])
END
// Summary: does a standard protection check and encrypt the DRIS we pass and from the API.
// We encrypt the DRIS passed to the API. !!!! Patch the CryptDRIS function in this file from source code generated by DinkeyAdd.
// Syntax:
//[ <Result> = ] ProtCheckEnc ()
// return value is 0 (success) or an error code
PROCEDURE ProtCheckEnc()
hLib, ret_code are system int
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = PROTECTION_CHECK // standard protection check
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
Info("It worked!")
// Summary: does a standard protection check and executes an algorithm and encrypts the DRIS
// NB for this to work you must program at least one "user algorithm" into the dongle
// NB We have used a very simple algorithm here (in the MyAlgorithm function). You must patch this with the
// sample code generated by DinkeyAdd for the algorithm that you are using. For Lite models copy the sample
// code from DinkeyLook.
// We encrypt the DRIS passed to the API. !!!! Patch the CryptDRIS function in this file from source code generated by DinkeyAdd.
// Syntax:
//[ <Result> = ] ProtCheckWithAlgEnc ()
// return value is 0 (success) or an error code
PROCEDURE ProtCheckWithAlgEnc()
hLib, ret_code are system int
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = EXECUTE_ALGORITHM // protection check and execute specified algorithm
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.alg_number = 1
// !!!! you should remove these entries if you are using Dinkey Lite so that algorithm arguments are random
DRIS.var_a = 1 // sample values
DRIS.var_b = 2
DRIS.var_c = 3
DRIS.var_d = 4
DRIS.var_e = 5
DRIS.var_f = 6
DRIS.var_g = 7
DRIS.var_h = 8
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
DelayBeforeClosing(1000)
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
// if you want you can check the algorithm answer - however if algorithm is from your code then best to just use the answer in your code
// !!!! Make sure you have replaced the MyAlgorithm routine with the algorithm you have specified in DinkeyAdd
IF (MyAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h) <> DRIS.alg_answer) THEN
Info("Dinkey protection error!", "You have not patched your algorithm in the MyAlgorithm routine")
RESULT -1
END
Info("It worked!")
// Summary: This function does a protection check and writes the string "Hello, World!" to the data area at offset 7
// In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
// NB you can easily modify the code to write a byte array instead of a string
// We encrypt the DRIS and Data passed to the API. !!!! Patch the CryptDRIS, CryptApiData and MyRWAlgorithm functions in this file from source code generated by DinkeyAdd.
// Syntax:
//[ <Result> = ] WriteStringEnc ()
// return value is 0 (success) or an error code
//
PROCEDURE WriteStringEnc()
hLib, ret_code are system int
alg_ans are int
OurString is fixed string on 1024 = "Hello, World!" // NB max. data write is 1K
OurString_bytes is array of 1024 1-byte unsigned int // byte-array of the encrypted string
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = WRITE_DATA_AREA // protection check and write specified data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.rw_offset = 7
DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes)
DRIS.rw_data_ptr = &OurString_bytes // we convert the string to write to a byte array (so we can encrypt it) and then we pass that value to our API
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
// calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code generated by DinkeyAdd
alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h)
// encrypt data we want to write (we must first convert it to a byte array so we can encrypt)
Transfer(&OurString_bytes, &OurString, DRIS.rw_length)
CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans)
CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
Info("It worked!")
// Summary: This function does a protection check and reads 13 bytes of data from the data area at offset 7
// In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
// NB you can amend this code to read a byte array instead of a string if you prefer.
// We encrypt the DRIS and Data passed to the API. !!!! Patch the CryptDRIS, CryptApiData and MyRWAlgorithm functions in this file from source code generated by DinkeyAdd.
// Syntax:
//[ <Result> = ] ReadStringEnc ()
// return value is 0 (success) or an error code
//
PROCEDURE ReadStringEnc()
hLib, ret_code are system int
alg_ans are int
OurString is fixed string on 1024 // NB max. data read is 1K
OurString_bytes is array of 1024 1-byte unsigned int // byte-array of the encrypted string
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = READ_DATA_AREA // protection check and read data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.rw_offset = 7
DRIS.rw_length = 13
DRIS.rw_data_ptr = &OurString_bytes // read it to our byte array first and then convert to a string
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
// calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code generated by DinkeyAdd
alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h)
CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// later in your code you can check other values in the DRIS...
IF (DRIS.sdsn <> MY_SDSN) THEN
Info("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
RESULT -1
END
IF (ExtractString(DRIS.prodcode, 1, Charact(0)) <> MY_PRODCODE) THEN
Info("Incorrect Product Code. Please modify your source code so that MY_PRODCODE is set to be your Product Code.")
RESULT -1
END
// later on in your program you can check the return code again
IF (DRIS.ret_code <> 0) THEN
Info("Dinkey Dongle protection error")
RESULT -1
END
// decrypt data we have just read (then convert to string)
CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans)
Transfer(&OurString, &OurString_bytes, DRIS.rw_length)
Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString)
// Summary: this function will do a protection check and ask the dongle to encrypt some data using encryption key 1
// It will then do another protection check & decrypt the data. NB you can modify the code to encrypt byte arrays instead of strings
// NB you can amend this code to read a byte array instead of a string if you prefer.
// We encrypt the DRIS and Data passed to the API. !!!! Patch the CryptDRIS, CryptApiData and MyRWAlgorithm functions in this file from source code generated by DinkeyAdd.
// Syntax:
//[ <Result> = ] EncryptUserDataEnc ()
// return value is 0 (success) or an error code
//
PROCEDURE EncryptUserDataEnc()
hLib, ret_code are system int
alg_ans is int
OurString is fixed string on 1024 = "Hello, World!" // NB max. data we can encrypt is 1K
OurString_bytes is array of 1024 1-byte unsigned int // byte-array of the encrypted string
// set the DRIS to have random values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = ENCRYPT_USER_DATA // protection check and encrypt specified data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.data_crypt_key_num = 1
DRIS.rw_length = Length(Left(OurString)) // the length of the string (in this case 13 bytes)
DRIS.rw_data_ptr = &OurString_bytes // we convert the string to encrypt to a byte array (so we can encrypt it) and then we pass that to the API
// Load the protection DLL.
hLib = LoadDLL(protectdllname)
IF hLib = 0 THEN
Info("Cannot load " + protectdllname, "This DLL should be in the same folder as this executable")
RESULT -1
END
// calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code generated by DinkeyAdd
alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h)
// encrypt data we want to write (we must first convert it to a byte array so we can encrypt)
Transfer(&OurString_bytes, &OurString, DRIS.rw_length)
CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans)
CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
//do a protection check
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
FreeDLL(hLib)
RESULT ret_code
END
// NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function)
// Now decrypt the same data to get the original values
RandomSet()
// then set the values we want to use
DRIS.header = "DRIS"
DRIS.size = Length(DRIS)
DRIS.dpfunction = DECRYPT_USER_DATA // protection check and decrypt specified data
DRIS.flags = 0 // no extra flags, but you may want to specify some if you want to start a network user or decrement execs...
DRIS.data_crypt_key_num = 1
DRIS.rw_length = 13 // the length of the string (in this case 13 bytes)
DRIS.rw_data_ptr = &OurString_bytes // NB this wil still be the encrypted data at this point
alg_ans = MyRWAlgorithm(DRIS.var_a, DRIS.var_b, DRIS.var_c, DRIS.var_d, DRIS.var_e, DRIS.var_f, DRIS.var_g, DRIS.var_h)
CryptDRIS() // encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
ret_code = CallDLL32(protectdllname, "DDProtCheck", &DRIS, 0)
FreeDLL(hLib)
CryptDRIS() // decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)
IF ret_code <> 0 THEN // an error occured so display an appropriate error message
DisplayError(ret_code, DRIS.ext_err)
RESULT ret_code
END
// NB can add code to check other elements of the DRIS e.g. SDSN, ProductCode (see ProtCheck function)
// decrypt the returned value and convert to a string
CryptApiData(OurString_bytes, DRIS.rw_length, alg_ans)
Transfer(&OurString, &OurString_bytes, DRIS.rw_length)
Info("It worked! Dinkey Dongle data area at offset 7 is:", OurString)