Process and system for controlling the use of software6421703Abstract This is a process and a system for controlling the use of software developed under a specified platform, associated with a device, in which signals are processed in the device and/or are returned from the device to the computer in response to signals transmitted from this computer. The circuit of the device is written to and read from by calling upon a function built into an object file (.OBJ) or a Dynamic Library file (.DLL), the function having the following form: result=cnrm(var1, var2, . . . varn) with n>3. The function is devised so as automatically to detect the type of specified platform, and calculate the software execution context as a function of the platform. Claims What is claimed is: Description The present invention relates to a process for controlling the use of software developed under a specified platform, associated with a device provided with an electronic circuit with read/write retentive memory, connected to the terminals of a parallel port between a computer and a peripheral apparatus, in which signals are processed in the device and/or are returned from said device to the computer in response to signals transmitted from this computer.
Contents of the variables
Before.sub.= call After.sub.= call
Var1 0 + CfgFun True
Var2 Code0 cfgKey
Var3 Code1 cfgFun
Var4 Key0 or 0 if Key0 0
not initialized
Var5 0 Duration of execution of the
function
Var6 0 or unit of time Time of start of execution
or True of the function
Var7 0 Version of the software or
Date of the software
Var8 0 Address of the parallel port
Before Call: Initialization of the Variables The values between [ ] are optional. Var1: 0 [+cfgFun]-Function number. Add cfgFun for a local key so that the test is faster. Var2: Code0--High-order bits of the editor code supplied by the key vendor Var3: Code1--Low-order bits of the editor code supplied by the key vendor Var4: 0 or password - if the password is not initialized, then 0 must be used, otherwise the password must be used. Var5: 0 Var6: 1 or 2 or 3 or 4 or True: with the value True a request is made to return the date in var7. 1 makes it possible to request a duration of execution value in microseconds, 2 makes it possible to obtain the duration in milliseconds, 3 makes it possible to obtain the duration in clock ticks (55 ms), and 4 makes it possible to obtain a duration in seconds. For any other value the function returns a time in microseconds in Var6 and the version of the software in Var7. Var7: 0--Reserved Var8: 0--Reserved After call: Contents of the Variables if the Key is present Var1: True if the key is present, otherwise random value. Var2: cfgKey--This value gives information about the location and the type of key. Var3: cfgFun--This value gives information about the location and the type of key. Var4: Always 0 Var5: Duration of execution of the call to the function. This time depends on the unit specified in var4, and constitutes only an approximate value. It is possible to obtain the exact values as follows: If the time is expressed in microseconds, divide this value by 1.193180 If the time is expressed in milliseconds, divide this value by 1.193180 If the time is expressed in clock ticks, divide the value by 18.20648193 to obtain the time in seconds. The time in seconds is that of the internal clock. However, it should be noted here that in 32-bit protected mode (32-bit WINDOWS, 32-bit DOS EXTENDERS), the time is not returned. Var6: Time of start of execution of the function. The time is expressed in the unit specified by Var4 Here again, in 32-bit protected mode (32-bit WINDOWS, 32-bit DOS EXTENDERS), the time is not returned Var7: Version of the software or date compacted. If before the call var6 contained True, then Var7 contains the date in the compacted format: bits 15141387654321012109 Value Year+1980 Month Day In the other cases var7 contains the version of the software to two decimal places. Example: 100 corresponds to version 1.00 Var8: Address of the parallel port on which the key is situated. Function 01: Initialization of the Password (local only) Public: No System: Yes Read: No Write: No Write once: Yes Password: Yes, to initialize it SSII access: Function 65 Protection:No On the first order from a developer, the key manufacturer allocates, for example, two codes Code 0 and Code 1. A third code is available for an initialization by the developer. However, for better management of the developer's keys, the manufacturer may also initialize it. In the mode described here the password will be written once only and it may neither be read nor modified. If the developer tries to reinitialize it, Var1 will contain a value different from True during the call. In this instance it is then recommended that the same password always be used after initialization. If the password is present, it will be obligatory in order to access all the functions.
Contents of the variables
Before.sub.= call After call
Var1 0 + CfgFun True
Var2 Code0 cfgKey
Var3 Code1 cfgFun
Var4 Key0 password 0
to be initialized
Var5 0 reserved
Var6 0 reserved
Var7 0 Value of the password
written to the key
Var8 0 Address of the parallel port
Before call: Initialization of the Variables The values between [ ] are optional. Var1: 01 [+cfgFun]-Function number. Add cfgFun to select a particular local key. Var2: Code0-High-order bits of the editor code supplied by the manufacturer Var3: Code1-Low-order bits of the editor code supplied by the manufacturer Var4: key 0=password to be initialized always different from 0. Var5: 0 Var6: 0--Reserved Var7: 0--Reserved Var8: 0--Reserved After call: Contents of the Variables if the Key is Present and Key0 not Initialized Var1: True if the key is present, and was able to be initialized. Var2: cfgKey--This value gives information about the location and the type of key. Var3: cfgFun--This value gives information about the location and the type of key. Var4: 0 Var5: Reserved Var6: Reserved Var7: Contains the value of the password written to the key provided that this is the first initialization of the latter. If the key is absent or already initialized, an unspecified value will be displayed. Var8: Address of the parallel port on which the key is situated. Function 02: Key Login Public: No System: Yes Read: Yes Write: No Write once: No Password: Yes SSII access: Function 66 Protection: Yes This function allows an application to attach itself to a key, the objective being to guarantee that the latter is linked with the correct key when there are several. Login also makes it possible to set up the channel with the key server in the network environment. Usually, an application which uses login is designed to operate in all possible cases: one or more local-mode keys one or more network-mode keys one key for several application packages several applications on identical keys (same editor) It is obligatory to go via login in order to be able to execute the functions of index higher than 2. It is possible either to carry out a general login (var6=var7 var8=0 on calling), or a login on a register (var6=True, Var7=register number and var7=value which the register must contain). The number of connection to the key server will always be counted by the machine, hence a machine can make as many logins as it desires, while using up just a single connection. In what follows, the general login is regarded as a login on register number -1, for any value: it is therefore also a register login.
Contents of the variables
Before call After call
Var1 02 + CfgFun True
Var2 Code0 cfgKey
Var3 Code1 cfgFun
Var4 Key0 cfgLog or 0 in the event of
a memory error
Var5 0 Number of connections still
available (for the logged
key)
Var6 True Number of connections
already installed (for the
logged key)
Var7 Value of the Maximum number of
register connections permitted (for
(application code) the logged key)
Var8 Address of the Address of the parallel port
register
Before call: Initialization of the Variables The values between [ ] are optional. Var1: 02 [+cfgFun]--Function number. Add cfgFun to select a particular key. Var2: Code0--High-order bits of the editor code supplied by ACTIKEY Var3: Code1--Low-order bits of the editor code supplied by ACTIKEY Var4: key 0 password Var5: 0 Var6: 0 or True for a login on a register Var7: Value of the register (application code) if Var6=True Var8: Address of the register if Var6=True After call: Contents of the Variables if the Key is Present and Login has Occurred Correctly Var1: True if the key is present, otherwise random value. A value of 0 indicates a login error for which the error code is in var8. This error code corresponds to that returned by the last server encountered. 0: Memory allocation error 1: Failure to initialize the network APIs : No network driver 2: Failure to connect with the network APIs: Network operating error 3: No key server has been found 4: Error in dialog with the key server 5: Access refused since the user has not logged on 6: Access refused since the maximum number of connection has been reached 10: IPX not installed 11: Impossible to open a socket 254: Key absent 255: Unexpected error Var2: cfgKey--This value gives information about the location and the type of key. Var3: cfgFun--This value gives information about the location and the type of key. Var4: cfgLog: login handle to be used in all subsequent calls Var5: Number of connections still available if the network is connected Var6: Number of connections already installed if the network is connected Var7: Maximum number of connections permitted Var8: var8: Address of the parallel port on which the key is situated. How to Provide Protection with the Function 02 This function allows and guarantees the unique association between an application and a key, even within the framework of networks (for network keys). As a general rule, a register is defined per application, with internally an application code which will be the version number of the application. The software then performs a login which will find the key which corresponds to the application and to its version, doing so in single-station or network mode, irrespective of the number of keys present. Thus, the same key can be programmed to operate on several application packages. In network mode it is possible to protect up to 1024 users with a single key, by installing it on the server for NOVELL or on a station for NOVELL or NETBIOS. Var1: Its value must always be equal to True. If you have some other value, either the key is absent or login has failed Var2: Do not use to provide protection. Var3: Do not use to provide protection Var4: cfgLog: login handle. This value of var4 must be retained for calls to the other functions of index higher than 2. Each login returns a different cfgLog, and as many logouts must be made as logins in order to release the connection of the keys in network mode. If var4 contains a 0 after the call, then the login has failed and no subsequent function can succeed. Var5: Number of users available for the connection Var6: Number of users connected at the moment of the call Var7: Maximum number of users permitted Var8: Address of the parallel port. The constructors implement the parallel ports at the addresses 0378h, 0278h and 3BCh. If you obtain a different value it is certain to be because a replacement routine has been installed, in which case it would be better to exit the program. It is also possible that the machine may not possess a non-compatible parallel port. In the latter case the key is not usable. See function 47 to ascertain the number of logins on a register per machine, and number of logins on a register for the whole of the network. The other functions 03, 04, etc. are defined so as to obtain the results sought. They are programmed in a manner known per se to the person skilled in the art, in a similar manner to the three functions specified above. In advantageous embodiments and in order to cater for a larger number of cases in point, the function cnrm is additionally supplemented with other functions. Let us recall that in all the declarations below, and for a Windows platform (16 or 32 bits) it is necessary to qualify the functions of WINAPI. The following modes are thus provided for: a--Function cnrm with passing of parameters by value Model integer cnrm(value var1, value var2, value var3, value var4, value var5, value var6, value var7, value var8) Declaration in C int cnrm(int var1, int var2, int var3, int var4, int var5, int var6, int var7, int var8); Declaration in Pascal Function cnrm(var1, var2, var3, var4, var5, var6, var7, var8: integer): integer; It should be observed that the name of the function is the same as in the case of passing by reference. The only difference stems from the fact that in the first case references are transmitted to the function, whereas in the second case values are transmitted to the function. The definition of the arguments is similar to that already described. On the other hand, to obtain the contents of the variables after the call, the function cnrmvar described below will be used. Additionally, it is entirely possible to mix the types of call in the same program, for example login can be carried out by value, and the reading of a register can be carried out by reference. b--Function Cnrmvar Cnrmvar is a function which makes it possible to retrieve the post-call parameters of cnrm for the latest call if login has been successful. It is mainly used together with the calling of cnrm by value, but can also be called in the case of calls by reference: in this case this makes it possible to store in memory the state of the values returned until the next call to cnrm. Model integer cnrmvar(int cfgLog, int numVar) Declaration in C int cnrmvar(int cfgLog, int numVar); Declaration in Pascal Function cnrmvar(cfgLog, numVar: integer): integer; cfgLog: Value returned during login numVar: 1 to 8: request to return var1 to var8 respectively 9: request to return the error code of the latest call to cnrm 10 to 13: request to return the error code received from the NOVELL type key servers for server number 0 to 3 respectively 20 to 23: request to return the error code received from the NETBIOS type key servers for server number 0 to 3 For all the other values of numVar, cnrmvar returns cfgLog An example of the mode of operation is given below: EXAMPLE // login is assumed to be correct cfgLog=cnrm(13, 12127, 2221, 1654, cfgLog, 0, 0, 0); // reading register 0 passing by value if (cnrmvar(cfgLog, 1)==True) {// test if var1 =True<==>action successful v=cnrmvar(cfgLog, 7); // v contains the value of register 0 } c--Function Cnrmcb: Definition of a Return Call The return call (or callBack) is a function which will be called by cnrm during calls following the fetch by cnrmcb. The interest in it lies in the possibility of ascertaining which operation cnrm is performing, of halting execution of cnrm prematurely, but also of improving protection by making it possible indirectly to call important functions of the protected application software during the execution of cnrm. This function considerably increases the protection of programs which use cnrm in the form of a dynamic library(DLL), if it defines a callBack of an application-critical function, such as for example the initialization of sensitive data, one of the components of which is stored in the key. Callback will only be done for actions of index>2, and only if login is successful. We have: Model integer cnrmcb(int cfgLog, reference cb, integer unsigned long Object) Declaration in C int cnrmcb(int cfgLog, callBack *cb, unsigned long Object); Declaration in Pascal Function cnrmcb(cfgLog: Integer; cb: _callBack; Object: longInt): integer; far; external; cfgLog: value received during login cb: address of the return function Object: a value which will always be transmitted to the function called back cnrmcb always returns cfgLog, hence if cfgLog is invalid it is the value 0 The general form of the function called back is moreover as follows: Model int callBack(unsigned long Object, int E, int SE, int cfgLog); Declaration in C typedef int _callBack(unsigned long Object, int E, int SE, int cfgLog); Declaration in Pascal type _callBack=Function(Object: longint; E: integer; SE: integer; cfgLog: integer): integer; If callBack returns the value 0 then execution of cnrm is halted in the current state, otherwise the execution of cnrm continues. "Object" is an unsigned integer which is left available: in general a pointer this for a C++ object is placed thereon. Object has been given during the fetch of the callBack E is the value of the internal state of cnrm at the time of the call to callback E=0=START: begin cnrm E=1=LOCAL: before calling cnrm in local mode (local test) E=2=NOVELL before calling cnrm on NOVELL E=3=NETBIOS: before calling cnrm on NETBIOS E=255=END: before exiting cnrm The order of the calls is guaranteed only for E=0 and E=255. The other states may be given several times in any order. SE gives sub-state information which depends on E. if E=0 or E=255, SE always equals 0 if E=1, SE can take values from 1 to 99 if E=2, SE can take values from 1 to 99 if E=3, SE can take values from 1 to 99 CfgLog makes it possible to retrieve the state of the variables passed as parameter during the call to cnrm for all the values of E<255, or the values after the call for all the values of E>=255. The callBack function must not call cnrm except if E=255, but it can call cnrmcb to fetch a new function back which will be called for the next state, or call cnrmccb to cancel the callBack. If the callBack function calls cnrm for E<>255, nothing will happen. On the other hand if E=255, cnrm is called normally, but without calling the function back. Therefore, no precaution needs to be taken in the callBacks to avoid recursion since it cannot occur. d--Function Cnrmccb: Cancelling a Callback Callback is a function which will be called by cnrm during calls following the fetch by cnrmcb. It is possible to delete this callback at any time, even within a callBack function, with the help of cnrmccb Model integer cnrmccb(int cfgLog) Declaration in C int cnrmccb(int cfgLog); Declaration in Pascal Function cnrmccb(cfgLog: Integer): integer; far; external, cfgLog: value received during login cnrmccb always returns cfgLog, hence if cfgLog is not valid it is 0 e--Function Cnrmseg: Returns the Segment of a Variable (16-bit Environment only) The function cnrmseg returns the segment of a far type variable. It is generally used with languages which do not allow the segments and offset to be retrieved (example: VISUAL BASIC). Model int cnrmseg(void far *s); // with s the variable whose segment is to be extracted Declaration in C int cnrmseg(char far *s); Declaration in Pascal Function cnrmseg(p: pointer): integer; far; external; f--Function Cnrmoff: Returns the Offset of a Variable (16-bit Environment Only) The function cnrmoff returns the segment of a far type variable. It is generally used with languages which do not allow the segments and offset to be retrieved (example: VISUAL BASIC). Model int cnrmoff(void far *s); // with s the variable whose segment is to be extracted Declaration in C int cnrmoff(char far *s); Declaration in Pascal Function cnrmoff(p: pointer): integer; far; external; Whether it be in the form of a static library (.LIB or .OBJ). or in the form of dynamic libraries, the functions described above are all accessible, (however, cnrmseg and cnrmoff are only meaningful for the 16-bit environments). Two examples of protections will now be described according to the embodiments of the invention more particularly described here. These examples are given by way of indication, the objective of the protections given here being to be reliable by guaranteeing a dependence of the application on the contents of the key, and a genuine execution of the software interfaces is for access to the key. This type of protection is especially recommended when using DLL. In the modes described more particularly below, an external encryption tool to be applied to the final executable programme is moreover called upon. This tool is the same for both applications and is given by way of non-limiting example. In all cases, the developer will have to adapt it as a function of his particular case. The two examples enlist an application for calculating the diameter of a circle, its circumference, the volume of a cylinder based on the circle and the weight of said cylinder. The result is displayed each time. The first example is in the C language, the source provided here being in the 16-bit environment. Here, the principle of protection is to choose a few sensitive functions of the software to be protected, to mask the entry point of these functions by an indirect call, and to encrypt the structure which contains the entry point of said functions. Thus, the key is guaranteed to be properly read otherwise decryption will not be performed, and in this case the entry points of the functions are not valid. If a normal user who has a licence does not put in his key, he will obtain the "key absent" message. If a pirate tries to replace the key or to delete the test for the presence of the key, decryption is not carried out and in this case the entry points of the functions are not valid. Encryption is carried out by an external program after compilation and link editing. It uses the string TAG1 which must be unique to find the area to be encrypted and the length of said area. The sole objective of the string TAG1 is the identification of a data section seen by the external program, the latter being unable to read the sources of the program to be protected. An example of the mode of operation of this encryption program is specified with reference to FIG. 5. More precisely the program R1 includes a first step 90 in which the executable file to be protected is opened, followed by a test 91 on the end of the file. If the file has not terminated, the routine is halted (step 97). If the end of the file is observed, a step 92 for reading the next character is undertaken, followed by a test 93 for comparing the character read with a reference character R, which is the character of the start of the so-called TAG1 string. If this is not the correct character, the next character is then read (return to step 92), otherwise the next n characters are read (step 94), for example six characters. A test step 95 is then performed to verify whether this is the so-called TAG1 string. If this is not the case, we return to step 92, if it is the case, step 96 for encrypting the data structure is then initiated just after the TAG1 string. Once encryption has been performed, the relevant routine is halted (step 97).
#include <windows.h>
#include <stdio.h>
#include <stdlib>
#include "ACTIKEY.H"
//#define _DEBUG_1 /* makes it possible to tailor the
program withour protection */
// codes of the key
#define NoCli 4000 // customer
reference
#define code0 12127 // editor code
No 0
#define code1 2221 // editor code
No 1
#define key0 1654 // editor
password
#define true 12345 // if key
present
// work variables for key
int cfgLog, var1, var2, var3, var4, var5, var6, var7,
var8;
const double pi = 3.1415; "As its name indicates"
// initial values
double R = 10.0; // radius of 10 Cm
double H = 10.0; // height in Cm
double D = 1.0; // density in G/Cm3
// declaration of the functions
void compute (HWND hwnd);
// declaration of the functions to be protected
// it must be declared near for this to work
// if they are called by an external module it must be
done through a call
// through a far function in this module which calls
the near function
// example : double farDiameter(double radius) {return
diameter(radius);}
double near diameter(double radius);
double near circumference(double radius);
double near volume(double radius, double height);
double near weight(double radius, double height, double
density);
void near displayResult (HANDLE hwnd, int ctrl, double
value); // display function
// special declarations for protection
typedef void near fV_V(void); // function with a void
parameter which returns a void
typedef double near fD_D(double p1); // Double
parameter function which returns a double
typedef double near fDD_D(double p1, double p2); //
function with two double parameters which returns a
double
typedef double near fDDD_D(double p1, double p2, double
p3); // function with three double parameters which
returns double
typedef void near fHID_V(HANDLE hwnd, int ctrl, double
p2);
// function which has a parameter HANDLE, Int and
Double which returns Void
// ATTENTION THIS ASSUMES THAT ALL THE FUNCTIONS ABOVE
ARE IN THE
// SAME SEGMENT OF CODE
// HENCE THEY MUST BE PLACED IN THE SAME SOURCE FILE AS
_ref void near _ref(void {;} // empty reference
function
typedef struct {
char tag[10]; // serves to encrypt
int nbFunction; // number of functions in the
structure
fV_V near *ref; // serves to have a reference
fD_D near *diameter;
fD_D near *circumference;
fDD_D near *volume;
fDDD_D near *weight;
fHID_V near *displayResult;
} _fct;
_fct fct = {
"*TAG1*", // tag
6 // 6 functions
_ref, // entry point: entry
number 0
diameter, // function 1
circumference, // function 2
volume, // function 3
weight, // function 4
displayResult// function 5
};
// the structure as global variable
_fct fct;
#define CODE_.SOFTWARE 6754; // a code to make sure
this is the correct key
#define REG_SOFTWARE 0 // in register 0
// end of declarations for protection
// protos of cnrm
int WINAPI cnrm(int far *var1, int far *var2, int far
*var3, int far *var4,
int far *var5, int far *var6, int far *var7,
int far *var8);
int WINAPI cnrmseg (void far *s);
int WINAPI cnrmoff (void far *s);
// Program
// declaration of the procedure of the dialog window
BOOL CALLBACK WindowProc(HWND hwndDlg, UINT msg, WPARAM
wParam, LPARAM lParam);
// main program
#pragma argsused
int PASCAL WinMain(HANDLE hInstance, HANDLE
hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
DLGPROC dlgProc;
int delta;
// login key
var1=2;
var2=code0;
var3=code1;
var4=key0;
var5=0;
var6=true;
var7=CODE_SOFTWARE;
var8=REF_SOFTWARE;
cfgLog=cnrm(&var1,&var2,&var3,&var4,&var5,&var6,
&var7,&var8);
if (cfgLog && var1 == true) {
// the key is present
#ifndef _DEBUG.sub.--
// install protection and do calculations for
correct execution
// request decryption of the structure
var1=30;
var2=code0;
var3=code1;
var4-cfgLog;
var5=cnrmseg(&fct.ref);
var6=cnrmoff(&fct.ref);
var7=fct.nbFunction * 2; // 2 bytes per
pointer since these are NEAR functions
var8=0;
cfgLog=cnrm(&var1,&var2,&var3,&var4,&var5,&var6,
&var7,&var8);
// end of installation of protection
#endif
// the dialog window responsible for carrying
out the work is opened
dlgProc =
MakeProcInstance((FARPROC)WindowProc, hInstance);
DialogBox(hInstance, "ACTIKEY", NULL, dlgProc);
FreeProcInstance((FARPROC) dlgProc);
}
else {
MessageBox(NULL, "Error : Key absent !",
"ACTIKEY", MB_OK);
}
// key logout
var1=3;
var2=code0;
var3=code1;
var4=cfgLog;
var5=0;-
var6=0;
var7=0;
var8=0;
cfgLog=cnrm(&var1,&var2,&var3,&var4,&var5,&var6,
&var7,&var8);
return 0;
}
// Callback procedure associated with the dialog window
#pragma argsused
BOOL CALLBACK WindowProc(HWND hwndDlg, UINT msg, WPARAM
wParam, LPARAM lParam)
{
switch (msg) {
case WM_COMMAND:
if (LOWORD(wParam) == IDOK) {
// end button : exit
Post Message(hwndDlg, WM_CLOSE, 0, 0);
return 1;
}
if (LOWORD(wParam) == IDC_CALCUL) {
// the results are recalculated as a
function of the data
compute (hwndDlg):
return 1;
}
break
case WM_CLOSE :
EndDialog(hwndDlg, 0);
return 1;
case WM_INITDIALOG :
// the controls are completed with the
default values
#ifdef_DEBUG.sub.--
displayResult(hwdnDlg, IDC_RADIUS, R);
// unprotected direct call
displayResult(hwdnDlg, IDC_HEIGHT, H);
// unprotected direct call
displayResult(hwdnDlg, IDC_DENSITY, D);
// unprotected direct call
#else
fct.displayResult(hwdnDlg, IDC_RADIUS,
R); // protected indirect call
fct.displayResult(hwdnDlg, IDC_HEIGHT,
H); // protected indirect call
fct.displayResult(hwdnDlg, IDC_DENSITY,
D); // protected indirect call
#endif
// and we calculate the results
compute (hwndDlg);
return 1;
} // end switch
return 0;
}
void compute(HWND hwnd)
{
char buf[37];
#ifdef _DEBUG.sub.--
// conventional method of calling the functions
without protection
GetDIgItemText(hwnd, IDC_RADIUS, buf, 37);
R = strtod(buf, NULL);
displayResult(hwnd, IDC--RADIUS R);
GetDIgItemText(hwnd, IDC_HEIGHT, buf, 37);
H = strtod(buf, NULL);
displayResult(hwnd, IDC_HEIGHT, H);
GetDIgItemText(hwnd, IDC--DENSITY, buf, 37);
D = strtod (buf, NULL);
displayResult(hwnd, IDC_DENSITY, D);
displayResult(hwnd, IDC_DIAMETER, diameter(R));
displayResult(hwnd, IDC_CIRCUMFERENCE,
circumference(R));
displayResult(hwnd, IDC_VOLUME, volume(R, H));
displayResult(hwnd, IDC_WEIGHT, weight(R, H,
D));
#else
// method of calling protected functions
// the difference lies in the prefix fct. in
front of the name of the function according to the
declarations
// this is an indirect call for which there is
no known entry point
// since it is calculated when the protection
is put in place
// the values are recovered in the input fields
GetDIgItemText(hwnd, IDC_RADIUS, buf, 37);
R = strtod(buf, NULL);
// and they are overwritten so as to supply the
value actually used
fct.displayResult(hwnd, IDC_RADIUS, R); // call
GetDIgItemText(hwnd, IDC_HEIGHT, buf, 37);
H = strtod(buf, NULL);
// and they are overwritten so as to supply the
value actually used
fct.displayResult(hwnd, IDC_HEIGHT, H); //
protected call
GetDIgItemText(hwnd, IDC_DENSITY, buf, 37);
D = strtod(buf, NULL);
// and they are overwritten so as to supply the
value actually used
fct.displayResult(hwnd, IDC_DENSITY, D); //
protected call
fct.displayResult(hwnd, IDC_DIAMETER,
fct.diameter(R));
fct.displayResult(hwnd, IDC_CIRCUMFERENCE,
fct.circumference(R));
The second example is that of an application with a very high level of protection in Visual Basic. This application calls upon a DLL and does not allow the use of techniques which are possible with C.
Begin VB.Form Form1
' description of the visual objects and
controls
' they comprise controls on the display of
named results
' Diameter, Circumference, Volume, Weights
End
Attribute VB_Name = "Form1"
Attribute VB_Creatable = False
Atribute VB_Exposed = False
'Protection demonstration program
'The principle here consists in masking the names of
the controls and the important constants in the code
'They are encrypted by an external program vbCrypte.exe
'To do this they are stored in a constant which can
appear once only
'throughout the application
'The structure of this string is as follows:
' TAG: a unique string (*TAG1* for this example)
' The size of the elements to be encrypted in the
string on 3 characters
' The elements to be encrypted preceded by a space
' an ending space
' example for 2 names of controls to be encrypted
' "*TAG1*020 control1 control2"
'Hence, we count all the space characters lying after
the length
'Owing to the nature of Visual Basic we cannot merely
store the constant
'somewhere in the code, else it would not be retrieved
by the encryption tools. The trick therefore consists
in storing it in an invisible control
'#Const DEBUG_ = 1 'Set to 1 for deburg 0 for
definitive version
'For protection
' Declaration of the APIs of cnrm
Private Declare Function cnrm Lib "CNRMA000.DLL" (ByRef
V1 As Integer ByRef v2 As Integer, ByRef v3 As Integer,
ByRef v4 As Integer, ByRef v5 As Integer, ByRef v6 As
Integer, ByRef v7 As Integer, ByRef v8 As Integer) As
Integer
Private Declare Function cnrmseg Lib "CNRMA000.DLL"
(ByVal s As String) As Integer
Private Declare Function cnrmoff Lib "CNRMA000.DLL"
(ByVal s As String) As Integer
' Code of the key
Const NoCli = 4000 ' customer no.
Const code0 = 12127 ' customer code 0 high-order
bit
Const code1 = 2221 ' customer code 1 low-order
bit
Const key0 = 1654 ' customer password
Const true = 12345 ' true if key present
' work variables
Dim cfgLog As Integer
Dim var1 As Integer
Dim var2 As Integer
Dim var3 As Integer
Dim var4 As Integer
Dim var5 As Integer
Dim var6 As Integer
Dim var7 As Integer
Dim var8 As Integer
' Declaration of the constants for the application
Dim Pi As Double ' = 3.1415 : will also be encrypted
'Initial values
Const Rini = 10#
Const Hini = 10#
Const Dini = 10#
' Work variables
Dim R As Double
Dim H As Double
Dim D As Double
' the names of the controls after decryption
Dim cD As String 'Diameter
Dim cC As String 'Circumference
Dim cV As String 'Volume
Dim cP As String 'Weight
Sub DisplayResult( )
' Display the result
#If DEBUG_ Then
Diameter.Text = Format(ComputeDiameter(R),
"0.0000")
Circumference.Text =
Format(ComputeCircumference(R), "0.0000")
Volume.Text = Format(ComputeVolume(R, H),
"0.0000")
Weight.Text = Format(ComputeWeight(R, H, D),
"0.0000")
#Else
Controls("Diameter").Text = "toto"
Controls(cD).Text = Format(ComputeDiameter(R),
"0.0000")
Controls(cC) = Format(ComputeCircumference(R),
"0.0000")
Controls(cV) = Format(ComputeVolume(R, H),
"0.0000")
Controls(cP) = Format(ComputeWeight(R, H, D),
"0.0000")
#End If
End Sub
Sub calcul( )
Dim V As Variant
R = CDb1(Radius.Text)
H = CDb1(Height.Text)
D = CDb1(Density.Text)
' Reset the values properly
Radius.Text = Format(R, "0.0000")
Height.Text = Format(H, "0.0000")
Density.Text = Format(D, "0.0000")
DisplayResult
End Sub
Function ComputeCircumference(R As Double) As Double
' calculate the circumference
ComputeCircumference = 2 * Pi * R
End Function
Function ComputeDiameter(R As Double) As Double
' calculate the diameter
ComputeDiameter = R * 2
End Function
Function ComputeWeight(R As Double, H As Double, D As
Double) As Double
' compute the weight
ComputeWeight = ComputeVolume(R, H) *D
End Function
Function ComputeVolume(R As Double, H As Double) As
Double
ComputeVolume = Pi * R * R * H
End Function
Private Sub bCompute_Click( )
compute
End Sub
Private Sub bExit_Click( )
Unload Screen.ActiveForm
End Sub
Private Sub Form_Load( )
' here we must set in place the operating elements
of the program
' hence decrypt the string so as to address the
correct controls
' Retrieval of the string to be encrypted : it is
unique for the whole code
fct = fct_.Text '"TAG1*043 3.1415 Diameter
Circumference Volume Weight --"
' the ending -- serve no purpose other than to
verify through a dump that
' the encryption is correct
Dim s As String
' Login key
var1 = 2 'Function 2 Login
var2 = code0 'editor code 0
var3 = code1 'editor code 1
var4 = key0 'password
var5 = 0 '
var6 = 0 '
var7 = 0 '
var8 = 0 '
' call the function CNRM
cfgLog = cnrm(var1, var2, var3, var4, var5, var6,
var7, var8)
If (var1 < > true) Then
MsgBox "Error key absent !", MB_OK, "ACTIKEY"
End
End If
' set up protection
s = Mid$(fct, InStr(fct, " ")) ' the only piece to
be decrypted
var1 = 30 'Decryption function
var2 = code0 'editor code 0
var3 = code1 'editor code 1
var4 = cfgLog 'cfgLog
var5 = cnrmseg(s)
var6 = cnrmoff(s)
var7 = Len(Mid$(fct, InStr(fct, " "), Len(fct)))
'the length
var8 = 0 '
' call the function CNRM
cfgLog = cnrm(var1, var2, var3, var4, var5, var6,
var7, var8)
' normally this is decrypted
' extract the first element (Pi)
s = Mid$(s, 2, Len(s)) 'skip the first space
Pi = Val(Mid$(s, 1, InStr(s, " ") - 1))
' extract the second element (cD)
s = Mid$(s, InStr(s, " ") + 1, Len(fct))
cD = Mid$(s, 1, InStr(s, " ") -1)
' extract the next element
s = Mid$(s, InStr(s, " ") + 1, Len(fct))
cC = Mid$(s, 1, InStr(s, " ") -1)
' extract the next (cV)
s = Mid$(s, InStr(s, " ") + 1, Len(fct))
cV = Mid$(s, 1, InStr(s, " ") - 1)
' extract the last (cP)
s = Mid$(s, InStr(s, " ") + 1, Len(fct))
cP = Mid$(s, 1, InStr(s, " ") - 1)
' End setup of protection
' Initial states
Radius.Text = Format(Rini, "0.0000")
Height.Text = Format(Hini, "0.0000")
Density.Text = Format(Dini, "0.0000")
compute
End Sub
Private Sub Form_Unload(Cancel As Integer)
' do a key logout
var1 = 3 'function 3 Logout
var2 = code0 editor code 0
var3 = code1 editor code 1
var4 = cfgLog 'Login
var5 = 0
var6 = 0
var7 = 0
var8 = 0
' call the function CNRM contained in the file
CNRMCxxx.DLL
cfgLog =cnrm(var1, var2, var3, var4, var5, var6,
var7, var8)
End Sub
As goes without saying and as moreover follows from the foregoing, the present invention is not limited to the embodiments more particularly described, but on the contrary embraces all variants thereof and especially those in which other methods of encryption are used.
|
Same subclass Same class Consider this |
||||||||||
