Rockey4ND User's Guide
Rockey4ND User's Guide
Rockey4ND User's Guide
User’s Guide
V1.1
Revision History:
All Products of Feitian Technologies Co., Ltd. (Feitian) including, but not limited to, evaluation copies, diskettes,
CD-ROMs, hardware and documentation, and all future orders, are subject to the terms of this Agreement. If you do
not agree with the terms herein, please return the evaluation package to us, postage and insurance prepaid, within
seven days of their receipt, and we will reimburse you the cost of the Product, less freight and reasonable handling
charges.
1. Allowable Use – You may merge and link the Software with other programs for the sole purpose of protecting
those programs in accordance with the usage described in the Developer’s Guide. You may make archival copies
of the Software.
2. Prohibited Use – The Software or hardware or any other part of the Product may not be copied, reengineered,
disassembled, decompiled, revised, enhanced or otherwise modified, except as specifically allowed in item 1.
You may not reverse engineer the Software or any part of the product or attempt to discover the Software’s
source code. You may not use the magnetic or optical media included with the Product for the purposes of
transferring or storing data that was not either an original part of the Product, or a Feitian provided enhancement
or upgrade to the Product.
3. Warranty – Feitian warrants that the hardware and Software storage media are substantially free from significant
defects of workmanship or materials for a time period of twelve (12) months from the date of delivery of the
Product to you.
4. Breach of Warranty – In the event of breach of this warranty, Feitian’s sole obligation is to replace or repair, at the
discretion of Feitian, any Product free of charge. Any replaced Product becomes the property of Feitian.
Warranty claims must be made in writing to Feitian during the warranty period and within fourteen (14) days after the
observation of the defect. All warranty claims must be accompanied by evidence of the defect that is deemed
satisfactory by Feitian. Any Products that you return to Feitian, or a Feitian authorized distributor, must be sent with
freight and insurance prepaid.
EXCEPT AS STATED ABOVE, THERE IS NO OTHER WARRANTY OR REPRESENTATION OF THE PRODUCT, EXPRESSED OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
5. Limitation of Feitian’s Liability – Feitian’s entire liability to you or any other party for any cause whatsoever,
whether in contract or in tort, including negligence, shall not exceed the price you paid for the unit of the Product
that caused the damages or are the subject of, or indirectly related to the cause of action. In no event shall
Feitian be liable for any damages caused by your failure to meet your obligations, nor for any loss of data, profit or
savings, or any other consequential and incidental damages, even if Feitian has been advised of the possibility of
damages, or for any claim by you based on any third-party claim.
6. Termination – This Agreement shall terminate if you fail to comply with the terms herein. Items 2, 3, 4 and 5
shall survive any termination of this Agreement.
Quick Start
■ The ROCKEY4ND evaluation kit is provided to developers for trial purpose. It includes the product package,
documentation, CD-ROM, extension cable, and dongle. The dongle is the same as the formal dongle, except that
the access password for it is public (P1: C44C, P2: C8F8, P3: 0799, P4: C43B). If customers want to purchase the
product after evaluation, a dongle with a unique password will be provided for security consideration.
■ To install ROCKEY4ND SDK, run Setup.exe in the kit, with which you can finish the installation of the SDK
through a wizard. For details, see Chapter 3 ROCKEY4ND SDK.
■ You can find the dongle editor Rockey4ND_Editor.exe under Editor directory in Utilities directory of the
SDK. You can modify, test, or write to the dongle using this tool. For details, see Chapter 5 ROCKEY4ND Editor.
■ An envelope encryption tool Envelope.exe is also provided under Envelope directory of the SDK. You can
encrypt Windows PE files, .Net files, and data files using this tool, simply by clicking on the target file and related
functions. For details, see Chapter 6 ROCKEY4ND Envelope Encryption.
■ By incorporating the ROCKEY4ND API into your applications to be protected, you can get the most out of
the dongle with the highest level of security. For details, see Chapter 7 ROCKEY4ND APIs.
■ You can find some frequently asked questions and the answers in Chapter 9.
■ For updates and any other things you are interested in, visit us at http://www.FTsafe.com.
Contents
Chapter 1. Introduction ............................................................................................................................. 1
1.1 About ROCKEY4ND......................................................................................................................................... 1
1.2 Software Protection Mechanism of ROCKEY4ND .......................................................................................... 1
1.3 Hardware Configuration ................................................................................................................................ 2
1.4 ROCKEY4ND Benefits ..................................................................................................................................... 2
1.5 How to Choose a Right Software Protection Solution ................................................................................... 2
Chapter 2. ROCKEY4ND Hardware Features ................................................................................................ 4
2.1 ROCKEY4ND Internal Structure ...................................................................................................................... 4
2.2 ROCKEY4ND Hardware Interface ................................................................................................................... 4
Chapter 3. Installing ROCKEY4ND SDK ........................................................................................................ 5
3.1 Installing SDK ................................................................................................................................................. 5
3.2 Uninstalling SDK ............................................................................................................................................. 8
Chapter 4. Basic Concepts.......................................................................................................................... 9
4.1 Passwords ...................................................................................................................................................... 9
4.2 Order Code..................................................................................................................................................... 9
4.3 Hardware ID ................................................................................................................................................... 9
4.4 User Data Zone .............................................................................................................................................. 9
4.5 Module Zone .................................................................................................................................................. 9
4.6 User Algorithm Zone .................................................................................................................................... 10
4.7 User ID ......................................................................................................................................................... 10
4.8 Random Number ......................................................................................................................................... 10
4.9 Seed and Return Values ............................................................................................................................... 10
Chapter 5. ROCKEY4ND Editor ..................................................................................................................11
5.1 Brief Introduction......................................................................................................................................... 11
5.2 Operation ..................................................................................................................................................... 14
5.3 Save Work .................................................................................................................................................... 17
Chapter 6. ROCKEY4ND Envelope Encryption.............................................................................................21
Chapter 7. ROCKEY4ND APIs .....................................................................................................................28
7.1 ROCKEY4ND Function Prototype and Definition.......................................................................................... 28
7.2 ROCKEY4ND API Services ............................................................................................................................. 30
7.3 Error Codes .................................................................................................................................................. 35
7.4 Basic Application Examples .......................................................................................................................... 36
7.5 Advanced Application Examples .................................................................................................................. 58
Chapter 8. ROCKEY4ND Hardware Algorithms ...........................................................................................89
8.1 ROCKEY User Defined Algorithm Introduction............................................................................................. 89
8.2 User Defined Algorithm Examples ............................................................................................................... 94
8.3 Tips ............................................................................................................................................................ 128
Chapter 9. FAQs ..................................................................................................................................... 130
9.1 Typical Solutions to Some Problems .......................................................................................................... 130
9.2 FAQs ........................................................................................................................................................... 130
Chapter 1. Introduction
Unlike some competing products, ROCKEY4ND is a powerful miniature computer, with a CPU, memory and
specialized firmware built-in that allows for a robust interaction with your application. You may write complex
algorithms that are securely stored in the dongle, and then call those algorithms from time-to-time in your
application. This method for software protection is strongly recommended and is very difficult to crack, and
although ROCKEY4ND was designed to implement extremely high levels of security - it is also relatively easy to
implement. The ROCKEY4ND API set has been simplified and improved based on experience gained from earlier
versions.
The ROCKEY4ND product also includes an Envelope encryption tool - Envelope.exe for encrypting Windows
Portable Executable files (such as .dll, .exe and .arx), .Net file, and data files. It is very easy to use. Only a few
seconds will be taken to encrypt a file. The ROCKEY4ND Envelope tool is an ideal solution if you do not possess
the source code for your application, or are unfamiliar with implementing an API. A security system that combines
both the API set and the Envelope program will offer the greatest level of protection.
There are several components to the ROCKEY4ND software security solution and each of them will be discussed in
this document. The following is an overview of the ROCKEY4ND components, along with a reference to where
they will be discussed in this document:
• The ROCKEY4ND Editor (Rockey4ND_Editor.exe) is a graphical tool for performing operations on the
dongle. The Editor may be used to read data from and write data to the dongle, perform arithmetic
operations in the dongle or test the dongle for malfunctions. (See Chapter 5: ROCKEY4ND Editor)
• ROCKEY4ND has an API set that you may use to create flexible and powerful software protection systems.
This document provides VC ++ examples and other examples are provided on the CD-ROM under Samples
directory. (See Chapter 7: ROCKEY4ND APIs)
The protected software application must call the ROCKEY4ND dongle during run time, since the application is
dependant on the hardware. It is impossible to duplicate the chipset of the ROCKEY4ND hardware, and so too it is
impossible to duplicate your software, ensuring your software is protected from piracy.
User memory is divided into 2 parts. The size of each is 500 bytes. The length of the algorithm area is 128 units.
The number of the modules is 64.
You may invoke the program Envelope.exe under Envelope directory of the SDK to perform the envelope
encryption function. As the name indicates, envelope encryption adds an envelope to the user’s designated files
to protect them. The envelope will call the dongle. When users execute the program protected by the envelope,
the protected program will automatically call the ROCKEY4ND and decide whether to allow the program to
continue according to the results of the call. The envelope program directly encrypts the compiled files. The
advantage of envelope encryption is that it is very easy and quick to implement and the source code does not
need to be modified. The envelope method is the ideal choice if there is no time for learning the API method or if
the source code is lost or unavailable. The disadvantage is that an envelope program uses a rule based encryption
method, and rule based encryption methods are not as strong as methods that use an encryption key. Also,
envelope encryption cannot support script languages that cannot be compiled, such as VBA.
For API encryption, developers need to choose the appropriate language interface according to their
programming language to access the dongle. API encryption was designed to be flexible; so you can make full use
of the encryption functions of ROCKEY4ND. Developers can decide where and how to encrypt their software. API
encryption is more secure than envelope encryption and especially so when the internal algorithm function of
ROCKEY4ND is utilized. But API encryption must work with the original program and it can take the developer
more time to become familiar with the API.
Note: ROCKEY4ND is a plug and play USB device. To unplug a ROCKEY4ND while writing/reading, the dongle may
cause crashes to the operating system in some instances.
The content of the CD-ROM consists of two parts: Tools under the directory Tools. Some documents on how to
use these tools are provides in the corresponding folder. APIs for different programming languages.
Step 1.
FEITIAN provides a Setup.exe installation wizard program on the CD-ROM. You may select the components you
need. The installation of the drivers is also integrated in this wizard. Double click the setup.exe file from the root
directory of the ROCKEY4ND CD-ROM. You will see the first screen of the Setup Wizard pictured below (Figure
3.1). Select language at the first step.
Figure 3.1
Step 2.
Close other application to avoid the need of rebooting the system.
Figure 3.2
Step 3.
View the software release agreement.
Figure 3.3
Step 4.
Figure 3.4 show the type of installation. Please select the content you want to install.
Figure 3.4
Step 5.
Select the path to install the SDK.
Figure 3.5
Step 6.
Finish installing the SDK.
Figure 3.6
4.1 Passwords
When developers purchase ROCKEY they will get 4 16-bit passwords. The first two are Basic passwords (first grade
passwords); the last two are Advanced passwords (second grade passwords). The 4 passwords for the demo
dongles in the SDK are: P1: C44C, P2: C8F8, P3: 0799, P4: C43B. The passwords are “burned” into the hardware so
that neither the user nor the manufacturer may change them. The developers must input the 4 passwords
correctly to have full access to the dongles. The developer should set any reference to the Advanced password set
to zero in the application program that is delivered to the end user – you should never reveal the Advanced
passwords to the end user in any form. The Basic passwords allow the end users to access all necessary ROCKEY
functions. We will discuss when one should input the Basic passwords, and when both Basic and Advanced
passwords are required in the chapters that follow.
4.3 Hardware ID
FEITIAN will burn a globally unique Hardware Identification (HID) number into each ROCKEY4ND dongle. The
HID cannot be changed. You may use the HID to positively identify an individual ROCKEY4ND. The HID is readable
with the Basic passwords. It is impossible to write HID even if you have the advanced passwords.
4.7 User ID
The User ID is a 32-bit memory allocation that may be used to store an application serial number or other
identification information.
It may be read with the Basic passwords and written with the Advanced passwords.
You may use the ROCKEY4ND Editor to edit data stored in ROCKEY4ND, test its functions or write in batch. The
Editor is a convenient tool for learning to use ROCKEY4ND and its edit operations. You can find the tool under
Editor directory of the SDK or in the installation directory. The ROCKEY4ND Editor interface is organized into five
parts: Tool Bar & Pull down Menu, Status Bar, Tree View, Operation Status Log and Operation Main Window. See
Figure 5.1.
Figure 5.1
1. Tool Bar & Pull down Menu - This is the very topmost section of the screen. The typical Windows functions can
be invoked from the icons or pull-down menus, such as print, save and refresh. Shortcut keys and icons are also
offered.
2. Status Bar -The Status Bar is at the bottom of the screen. The Status Bar message is for the dongle selected in
the “Device Selector” (See below) portion of the screen. Status messages are: Read, Write and Ready. See Figure
5.2.
Figure 5.2
3. Tree View - This is the upper left portion of the screen and shows the current OS version and ROCKEY4ND
dongles that are attached to the computer. See Figure 5.3.
Figure 5.3
4. Operation Status - The time, results and error prompt of the previous operations will display here. This section
is the lower left portion of the screen. See Figure 5.4.
Figure 5.4
5. Operation Main Window - The Operation Main Window has five selection tabs: Password, Edit, Test, Self Test
and Batch Write. Each tab corresponds to a screen and a function.
Template files (.rki) can be opened by dragging and dropping the template file to the open Editor window. It can
also be opened from the file pull down menu in the Editor or by clicking the file from Explorer. You may print
preview the template file and print it out. You may use the Editor without a ROCKEY4ND dongle attached to the
computer and save the results to a template file. The template file can later be used for a “Write” or “Batch
Write” to a ROCKEY4ND dongle(s). The template file may be updated with the Editor while dongles are attached.
A progress bar will display all your operation progress and you may stop your operations at any time.
Note: All numbers are input and displayed in hexadecimal with the exception of the number of generated seed
codes in the test screen.
5.2 Operation
Figure 5.5
Make sure you enter the correct passwords. If the Basic passwords are incorrect Editor cannot find the dongle. If
the Basic passwords are correct, and the Advanced passwords are invalid, the Editor should find the dongle and
allow Read functions, but it will not allow Write functions.
If you click “DEMO” button, you may perform any operations on DEMO dongles. The 4 passwords for DEMO
dongles are: P1: C44C, P2: C8F8, P3: 0799, P4: C43B.
The passwords will be saved automatically when you choose “Auto save password”. This function avoids future
password entry errors.
If the entered password information corresponds with the attached ROCKEY4ND dongle, you will be taken to the
“Edit” screen automatically. The system will automatically begin to search for attached dongles.
Note: You may edit, save, open and print template files without inputting the passwords. However, you cannot
operate the dongle without at least the Basic passwords. Entering the Basic passwords will allow you to both edit
template files and perform Read operations on the corresponding attached dongle.
5.2.2 Edit
The ROCKEY Hardware ID (HID) is displayed for all found dongles. The HID is globally unique and cannot be
changed. See Figure 5.6:
Dongle ID
Start statement
End Statement
Standalone Statement
User ID
Write 6 to Module 0
and allow decrement
Figure 5.6
Here you may edit the specified ROCKEY. There are 6 components on the Edit screen: User Data Zone (UDZ),
Module Zone, User Algorithm Zone (UAZ), User ID Zone (UIZ), Single Operation Zone (SOZ), and Batch Operation
Zone (BOZ).
User Data Zone (UDZ) – The UDZ is a user defined memory space. Data may be entered here in hexadecimal or
ASCII text in the field provided. Click the “Read” button to read data from the UDZ and “Write” to write to the
UDZ.
If you click the Read or Write button a progress bar will appear. After the operations are finished the results will
be displayed in the Operation Status section. See Figure 5.6.
Module Zone - This part of the screen is used to update the values and decrement attributes of the ROCKEY4ND
modules. To add new values to a module simply enter the new value in the field of the module, and click “Write”.
The Decrement attribute can likewise be altered. (All 64 ROCKEY4ND modules are displayed here, labeled 0 to F in
hexadecimal.)
User Algorithm Zone (UAZ) – You can write some algorithm statements here, which consist of operands and
operator(s), such as A=A+B (refer to Chapter 8). There is a button after each statement, marking the statement.
The flag of the start statement (S), end statement (E), intermediate statement (blank), and standalone statement
(SE) will be displayed on the button in turn when you click on it. If you check Auto S/E box, the statements you
have added will be marked automatically. See Figure 5.6.
User ID Zone (UIZ) - User identification information may be read from or written to the UIZ of the ROCKEY4ND
dongle in hexadecimal. See Figure 5.6.
Single Operation Zone (SOZ) – Click Read button to read the content of the dongle that has been selected into the
memory. Click Write button to write the content of the memory to the dongle that has been selected.
Batch Operation Zone (BOZ) – You can change all User IDs of the dongles in the edit area. Enter a start ID in the
User ID field. Choose a method for setting the ID (see below). Click Batch Write button to update all IDs of the
dongles.
User ID +: The value entered in User ID field will be written to the first dongle of the dongle list. Then, 1
is added onto the value and the updated value is written to the next dongle. For example, the values
“124” and “125” will be written to the second dongle and the third dongle respectively after the initial
value “123” is written to the first dongle if User ID + radio button is checked and Batch Write button is
clicked.
User ID -: Its function is similar to that of User ID + button, except that the ID value is descended.
Use Time ID: Use the time value of the system clock as the User ID.
No Change: The value of User ID field will be written to each of the dongles in the list, without any
change.
Figure 5.7
5.3.1 Test
There are five components to the Test screen: User Data Zone (UDZ), Calculation Zone, User ID Zone (UIZ),
Module Attribute Zone and the Seed Calculation Zone. See Figure 5.8.
Figure 5.8
User Data Zone –The UDZ is a user defined memory space. Data may be displayed in hexadecimal form, or as
ASCII text. Click the “Read” button to read data from the UDZ. You may view hexadecimal data or ASCII text here.
Calculation Zone – Be sure that you are familiar with the calculation functions before using the Calculation Zone.
First select the calculation you would like to test (For Calc1 and Calc3 a “Module” entry box will appear. For Calc2
a “Seed Code” box will appear.). Then input the start address of your algorithm stored in the UAZ. The start
address is where the instruction is marked with “S” or “SE”. Enter hexadecimal input values to the parameter A, B,
C and D. Enter the module number or seed code and click the “Calculate” button. The results of the operation will
be written to the parameters listed in the “Results” section of the Calculation Zone.
User ID Zone (UIZ) – Click the “Read” button to read the user defined ID from the UIZ of the ROCKEY4ND dongle
UIZ is 32 bits in length.
Module Attribute Zone – This zone indicates the status of the Zero Value and Decrement attributes of the
ROCKEY4ND modules. Click the “Read Module Attributes” button to update this portion of the Test screen. “N/A”
means that the Zero Value attribute is “0”. “Valid” means the Zero Value attribute is not “0”. If the “Dec” button is
grayed out the module cannot be decremented. If it is to be decremented, clicking the “Dec” button will reduce
the value stored in the module by “1”.
Seed Calculation Zone – There are two small sections to the Seed Calculation Zone. The top section will display
four calculated seed results for any entered seed code. Enter a decimal number in the “Number Generate” field in
the bottom section, and that same number of random seed codes and corresponding results will be written to a
text file defined in the “File” field. The default file is Random_Seed.txt under the directory of the executable.
5.3.2 Self-test
Test all ROCKEY4ND dongles attached to the computer one by one or test only selected dongle(s). First, you can
specify the items that will be tested. All specified dongles will be tested automatically.
Tested contents
Figure 5.9
Note: This test is like a “Format” command in that it will delete any data or parameters stored in the dongle. It
would be best to run the Self Test upon receipt of the dongle or if there is a significant problem with the dongle.
1. The components of the envelope tool include the interface program for entering parameters by users, the
enveloper based on the command line, and the enveloper module on the dongle.
2. Interface program
A. Parameters for all dongles from Feitian are supported.
B. The encryption parameters for PE, .NET, and data envelope files are supported. The files are divided into
two types: program and data.
C. Program types that can be recognized automatically: win32PE, WIN64PE, WIN32.NET, and WIN64.NET
D. Supported language environments: Simplified Chinese, Traditional Chinese, and English. More can be
specified by adding self-defined language environments to the folder language. A maximum of 16
language files can be specified for now.
E. When there is only one .DLL file in folder WIN32_PE, the dongle selection dialog box will not be displayed,
and the dongle type will be selected automatically to facilitate the integrated or individual release of this
system.
F. The types of the envelope file supported by the current dongle can be recognized automatically
according to the presence of related .DLL file in the folder. When an unsupported file type is added, a
message will be displayed.
3. The enveloper based on the command line
A. If you do not want to use the interface program, you can develop a self-defined upper-level interface
based on this command line program.
B. Apparently, the commands of the command line program are complex. If you do not want to learn how
to use them, the C source files for generating a command line from data structure can be available upon
request to facilitate your development of interface.
4. The enveloper module on the dongle
This is the core module for implementing different types of dongle and file enveloping. By developing this module
and place it into a corresponding folder, the required functions can be achieved, independent of the upper-level
interface and the command line program. Currently, the following modules have been implemented: win32_PE,
win32_DOTNET, and win32_DATA for Rockey4ND, and win32_PE, win32_DOTNET, and win32_DATA for
NetRockey4ND.
Screenshots:
Choose a dongle type (this box is not displayed if there is only one .DLL file under WIN32_PE folder):
Figure 6.1
Main interface:
Figure 6.2
Figure 6.3
Figure 6.4
The file type is recognized automatically. When a file is selected, related envelope options are displayed on the
right side:
PE envelope options:
Figure 6.5
Figure 6.6
Figure 6.7
Figure 6.8
Figure 6.9
Figure 6.10
WORD Rockey
(
WORD function,
WORD* handle,
DWORD* lp1,
DWORD* lp2,
WORD* p1,
WORD* p2,
WORD* p3,
WORD* p4,
BYTE* buffer
);
FEITIAN provides developers with a unified function from which they can employ all ROCKEY4ND operations.
This function is defined as a multi-function function.
Below is a call example for C language, and we will discuss future applications in a similar way. retcode =
Rockey(function,handle,lp1,lp2,p1,p2,p3,p4,buffer);
The “ROCKEY” function parameters are defined as: Note: All interface parameters must be defined in your
program.
ROCKEY4ND cannot transfer NULL or 0 pointers. Use of Null or 0 pointers in your program will generate an error.
number address
Note: All parameters must be defined in the program. Do not pass a Null pointer. Otherwise, an error will occur.
• “function” is a 16-bit number. It stands for the specific function and it is defined below:
1 // Find ROCKEY4ND
RY_FIND
Here we discuss the API services in detail. The following functions marked with [*] require the two Advanced
passwords.
Note: p3 and p4 are Advanced passwords. They are for developers to operate on the dongle. The Advanced
passwords should not appear in the software you offer to your customers and you should set the two Advanced
passwords “0” when searching for dongles in your application.
Return value:
A return value = “0” indicates that the function worked correctly. Any other return value indicates an error. A
successful operation will write the ROCKEY4ND Hardware ID (HID) to *lp1.
Input parameters:
function = RY_SET_MOUDLE
*handle = ROCKEY4ND's handle
*p1 = Module Number
*p2 = Module Unit Value
*p3 = If decreasing is allowed (1 = allowed, 0 = not allowed)
Return value:
A return value = “0” indicates that the function worked correctly. Any other return value indicates an error. A
successful operation will result in module unit # “*p1” storing value “*p2” and the Decrement attribute set to “0”
or “1”.
A return value = “0” indicates that the function worked correctly. Any other return value indicates
an error. A successful operation will reduce the value stored in module *p1 by “1”.
FEITIAN offers several program examples to help beginners quickly familiarize themselves with ROCKEY. These
sample programs are intentionally simplified to illustrate various security objectives and should not be construed
as sufficient for most real world implementations. These samples are for demonstration purposes only. This
document is not intended to illustrate how to take full advantage of the ROCKEY software protection system –
that will depend on particularities of the developer, the application and the licensing objectives. Section 7.5
Advanced Application Examples are also a good reference but the developer will need to determine the best
protection method given his own constraints and objectives.
Some key points that you need to pay attention to when programming:
• P3 and P4 are Advanced passwords enabling the developers to write to the dongles. Each of them should
be set to a valid value only in this case. They should be set to 0 in the software delivered to end users.
• Be sure that none of the address parameters in the ROCKET4ND functions are Null pointers. For example,
even if you do not require the Buffer, but it cannot be null, otherwise the result is unpredictable.
The following sample programs are written in VC 6.0. Let us discuss how to perform the required functions step
by step from an original program. Software developers who develop software in other languages please do not
skip this section. There are no special developing skills for the C language. Most software developers will
understand the concepts illustrated here.
#include <windows.h>
#include <stdio.h>
void main()
{
// Anyone begin from here.
printf("Hello FeiTian!\n");
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4;
DWORD lp1, lp2;
BYTE buffer[1024];
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0; // Program needn't Password3, Set to 0
p4 = 0; // Program needn't Password4, Set to 0
// ==============================================================
printf("Hello FeiTian!\n");
It is a very simple security objective. We only need to call the function “Find a ROCKEY dongle”. You may refer to
the introduction of the function “Find a ROCKEY dongle” in the section “ROCKEY4ND API Services”.
For testing purposes you might try to run this program with and without the ROCKEY4ND dongle attached to the
computer.
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
// ==============================================================
printf("Hello FeiTian!\n");
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
#include <windows.h>
#include <stdio.h>
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
retcode = Rockey(RY_FIND, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Not found
{
printf("ROCKEY not found!\n");
return;
}
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0; // Pos
p2 = 14; // Length
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
In Step 3 we have written “Hello FEITIAN!” to the ROCKEY dongle. In Step 4 we will read the contents of the
dongle.
Read dongle contents – Step 4:
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0; // Pos
p2 = 14; // Length
buffer[14] = 0;
retcode = Rockey(RY_READ, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
// ==============================================================
printf("%s\n", buffer);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
retcode = Rockey(RY_RANDOM, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Random:%04X,%04X,%04X,%04X\n", p1,p2,p3,p4);
p1 = 0; // Pos
p2 = 4; // Length
buffer[4] = 0;
retcode = Rockey(RY_READ, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Read: %s\n", buffer);
if(buffer)
printf("Hello FeiTian!\n");
else
exit(0);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
#include <windows.h>
#include <stdio.h>
void main()
{
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
return;
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
//seed Rockey
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
// Close Rockey
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
printf("\n");
getch();
Verify the return codes of the seed code to see if the program should be terminated - Step 7:
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
WORD retcode;
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
//seed Rockey
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
return;
// Close Rockey
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
#include <windows.h>
#include <stdio.h>
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
return;
}
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
lp1 = 0x88888888;
retcode = Rockey(RY_WRITE_USERID, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Write User ID: %08X\n", lp1);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
Verify the User ID. If the User ID is not 0x88888888 output “Hello DEMO!”. See Step 9:
#include <windows.h>
#include <stdio.h>
void main()
{
// ==============================================================
WORD retcode;
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
lp1 = 0;
retcode = Rockey(RY_READ_USERID, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
if (lp1==0x88888888)
printf("Hello FeiTian!\n");
else
{
printf("Hello DEMO!\n");
return;
}
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
Initialize ROCKEY and set module value. For example we set module 0 to be valid and its value cannot be
decreased. See Step 10:
#include <windows.h>
#include <stdio.h>
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
If module 0 is valid in the program, output “Hello FEITIAN!”. Otherwise terminate or exit the program. See Step
11:
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0;
retcode = Rockey(RY_CHECK_MOUDLE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
if (p2)
printf("Hello FeiTian!\n");
else
return;
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
In Step 10 we set p2=3(allowed software run times) and p3=1(Decrement allowed). That is to say module 0(p1=0)
sets the maximum software run time to 3. See Step 12:
#include <windows.h>
#include <stdio.h>
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0;
retcode = Rockey(RY_CHECK_MOUDLE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
if (p2!=1)
{
printf("Update Please!\n");
return;
}
if(p3==1)
{
p1=0;
retcode = Rockey(RY_DECREASE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if(retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
// ==============================================================
printf("Hello FeiTian!\n");
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
#include <windows.h>
#include <stdio.h>
void main()
{
int i, rynum;
WORD retcode;
WORD handle[16], p1, p2, p3, p4; // ROCKEY4ND Variable
DWORD lp1, lp2; // ROCKEY4ND Variable
BYTE buffer[1024]; // ROCKEY4ND Variable
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
}
printf("\n");
rynum = i;
// Do our work
for (i=0;i<rynum;i++)
{
// Read Rockey user memory
p1 = 0; // Pos
p2 = 12; // Length
buffer[12] = 0;
retcode = Rockey(RY_READ, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
lp1=0;
retcode = Rockey(RY_READ_USERID, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Read User ID: %08X\n", lp1);
p1=0;
retcode = Rockey(RY_CHECK_MOUDLE, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Allow Decrease\n");
else
printf("Not Allow Decrease\n");
{
printf("Error Code: %d\n", retcode);
return;
}
A maximum of 16 dongles may be attached to the same computer at the same time. The program can access any
dongle you specify.
In the above program we defined a handle array to save the opened ROCKEY handle to prepare for the next
operation on the specified dongle. When we find the dongle we open it and we close all opened ROCKEY handles
before exiting the program. Developers are better off operating in this manner, but for a large program it is OK to
open/close the dongle just once at the beginning/end of the program. Frequent open and close operations will
reduce performance. We open the dongle in share mode so that other programs may also simultaneously operate
with the dongle.
You can find the source code of the samples above from the CD-ROM or under Samples directory.
Note: We called function RY_OPEN and RY_CLOSE in the above program. We must open ROCKEY before all
operations with the exceptions of RY_FIND and RY_FIND_NEXT. This is similar to the operation on the disk files.
You should close the dongle immediately after finishing dongle related operations.
This section is dedicated to providing additional illustrative examples of methods you may employ to protect your
software with ROCKEY4ND. These examples are intentionally simplified and not intended to be a complete
solutions for software protection. The method appropriate for your application will depend on constraints set by
your licensing agreement and other factors. (If you are familiar with the API call already, you may skip to Chapter
8 ROCKEY4ND Hardware Algorithms.)
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
BYTE buf[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
p1 = 0;
p2 = 10;
p3 = 1;
strcpy((char*)buffer, "Hello ");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: Hello \n");
p1 = 12;
p2 = 12;
p3 = 1;
strcpy((char*)buffer, "FeiTian!");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: FeiTian!\n");
p1 = 0;
p2 = 10;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
p1 = 12;
p2 = 12;
memset(buf, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buf);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buf);
printf("\n");
printf("%s\n", strcat(buffer,buf));
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
getch();
}
Step 15: You may write a serial number in the User Data Zone (UDZ) and then verify it during run time as a means
of protecting and controlling a program module.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
p2 = 12;
p3 = 1;
strcpy((char*)buffer, "a1b2c3d4e5f6");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write:a1b2c3d4e5f6\n");
p1 = 0;
p2 = 2;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
if (!strcmp(buffer,"a1"))
printf("Run Module 1\n");
else
break;
p1 = 2;
p2 = 2;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
if (!strcmp(buffer,"b2"))
printf("Run Module 2\n");
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
Step 16: Write a number to the UDZ and decrease it during run time as a means of controlling a software module.
We recommend you use the encryption idea in Step 12 combined with Step 16.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
int i, j,num;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
p2 = 2;
p3 = 1;
strcpy((char*)buffer, "03");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: 03\n");
p1 = 0;
p2 = 1;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
num=atoi(buffer);
if(num)
{
printf("Hello FeiTian!\n");
num--;
}
else
{
return;
}
p1 = 0;
p2 = 1;
sprintf(buffer, "%ld", num);
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: %ld\n",num);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
Step 17: You may use different seed codes for different software modules or in different places in the application.
Then verify the seed codes in the applications.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
lp2 = 0x87654321;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
lp2 = 0x18273645;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
}
}
In Step 18 we use four outputs of the seed code function to encrypt and decrypt a character string. Be sure you
only include the “decrypt” portion of the code in the application version that is sent to end users.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
char str[20] = "Hello FeiTian!";
DWORD mykey = 12345678;
int n, slen;
int i,j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
// Encrypt my data
slen = strlen(str);
lp2 = mykey;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
for (n=0;n<slen;n++)
{
str[n] = str[n] + (char)p1 + (char)p2 + (char)p3 + (char)p4;
}
// Decrypt my data
lp2 = mykey;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
for (n=0;n<slen;n++)
{
str[n] = str[n] - (char)p1 - (char)p2 - (char)p3 - (char)p4;
}
printf("Decrypted data is %s\n", str);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
}
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
int i, j;
SYSTEMTIME st;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
lp1 = 0x20021101;
retcode = Rockey(RY_WRITE_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
lp1 = 0;
retcode = Rockey(RY_READ_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read User ID: %08X\n", lp1);
sprintf(buffer,"%08X",lp1);
GetLocalTime(&st);
printf("Date:%04d%02d%02d\n",st.wYear,st.wMonth,st.wDay);
sprintf(buf,"%04d%02d%02d",st.wYear,st.wMonth,st.wDay);
if(strcmp(buf,buffer)>=0)
{
printf("ok!\n");
}
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
{
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
p2 = 0x2121;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 0;
retcode = Rockey(RY_CHECK_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Check Moudle 0: ");
if (p2)
printf("Run Modul 1!\n");
else
break;
printf("\n");
p1 = 8;
p2 = 0xFFFF;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 8: Pass = %04X Decrease no allow\n", p2);
p1 = 8;
retcode = Rockey(RY_CHECK_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Check Moudle 8: ");
if (p2)
printf("Run Modul 2!");
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
Step 21: This program discussed how to perform multi-module encryption and check the status of the modules.
Many applications are segmented into program modules that users may choose or purchase separately. For
example, a user may purchase three of four available application modules and the licensing policy would allow
the user to execute only those modules that were purchased. ROCKEY4ND modules may be used to enforce this
licensing scheme.
#include <windows.h>
#include <stdio.h>
#include "Rockey4_ND_32.h" // Include ROCKEY4ND Header File
void main()
{
int i, j, rynum;
WORD retcode;
DWORD HID[16];
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
return;
}
}
printf("\n");
rynum = i;
// Do our work
for (i=0;i<rynum;i++)
{
for (i=0;i<rynum;i++)
{
retcode = Rockey(RY_CLOSE, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
The above program searches all dongles with the same passwords attached to the computer and displays the
status of every module in every listed dongle. “O” means that the module may be used and is not zero; “X” means
that the module cannot be used. In a protection scheme that relies on ROCKEY4ND modules this program would
help the developer identify modules that are usable from ones that should be terminated.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
WORD handleEnd;
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
{
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
/*p1 = 0;
p2 = 5;
p3 = 1;
strcpy((char*)buffer, "Ver10");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write:%s\n",buffer);
*/
p1 = 0;
p2 = 5;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
if (!strcmp(buffer,"Ver10"))
{
handleEnd=handle[j];
break;
}
{ //=========A==========
retcode = Rockey(RY_RANDOM, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Random: %04X\n", p1);
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_CLOSE, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
In Step 23 the UID is used to distinguish the dongles with the same passwords. For example, dongles with UID of
“11111111” (hexadecimal) correspond to software A.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
WORD handleEnd;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
/*lp1= 0x11111111;
retcode = Rockey(RY_WRITE_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write User ID: %08X\n", lp1);
*/
lp1 = 0;
retcode = Rockey(RY_READ_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
if(lp1==0x11111111)
{
handleEnd=handle[j];
break;
}
{ //=======A=============
p1 = 0;
p2 = 12;
p3 = 1;
strcpy((char*)buffer, "Hello Feitian!");
retcode = Rockey(RY_WRITE, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: %s\n",buffer);
p1 = 0;
p2 = 12;
buffer[512]=0;
retcode = Rockey(RY_READ, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n",buffer);
retcode = Rockey(RY_RANDOM, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Random: %04X\n", p1);
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
C A?B B?A
A<B 0 FFFF
A=B FFFF FFFF
A>B FFFF 0
It will write either “FFFF” or “0” to parameter C according to the table above.
First let us have a look at the algorithm example we will write to the dongle:
A= A+B, B = B + E, C = A * F, D = B + C, H = H ^ H
A, B, C… are registers in the dongle. There are a total of eight 16-bit registers in the dongle and they are designed:
A, B, C, D, E, F, G and H.
Register A = p1
Register B = p2
Register C = p3
Register D = p4
Register variables vary according to the calculation type: Register E, Register F, Register G, and Register H.
When receiving data from registers:
p1 = Register A
p2 = Register B
p3 = Register C
p4 = Register D
Registers A, B, C and D are user interface variables. Registers E, F, G and H are internal variables.
A P1
B P2
C P3
D P4
E High 16 bits of hardware ID
F Low 16 bits of hardware ID
G Value stored in module *lp2
H Random number
A P1
B P2
C P3
D P4
E Seed return value 1 (depending on the seed code in *lp2)
F Seed return value 2 (depending on the seed code in *lp2)
G Seed return value 3 (depending on the seed code in *lp2)
H Seed return value 4 (depending on the seed code in *lp2)
A P1
B P2
C P3
D P4
E Content of the module specified by *lp2
F Content of the module of *lp2 + 1
G Content of the module of *lp2 + 2
H Content of the module of *lp2 + 3
Return value A value of 0 indicates that the function works properly. Any other value
indicates an error.
If *p1 = 0 when inputting, then you may figure out the content of the module
specified by *p1 = *lp2 when returning, although you cannot read the content
of the module directly. If possible, you’d better verify the content of the
module with an algorithm, instead of comparing in the program.
function = RY_CALCULATE2
Input parameters
*handle = Handle of the dongle
*lp1 = Start point of calculation
*lp2 = Seed code
*p1 = Input value 1
*p2 = Input value 2
*p3 = Input value 3
*p4 = Input value 4
Return value A value of 0 indicates that the function works properly. Any other value
indicates an error.
function = RY_CALCULATE3
Input parameters
*handle = Handle of the dongle
*lp1 = Start point of calculation
*lp2 = Start address of module
*p1 = Input value 1
*p2 = Input value 2
*p3 = Input value 3
*p4 = Input value 4
Return value A value of 0 indicates that the function works properly. Any other value
indicates an error.
Aside from the use of ROCKEY4ND Editor, developers can also use the interface RY_WRITE_ARITHMETIC to
develop a program for writing algorithms themselves.
For example:
strcpy(buffer,"A=A+E,A=A+F,A=A+G,A=A+H");
p1 = 3;
retcode= Rockey(RY_WRITE_ARITHMETIC,handle,&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
You can see that the algorithm to be written is placed into buffer and the instructions are separated by commas.
The first instruction will be set to the start of the algorithm and the last instruction will be set to the end of the
algorithm automatically. For example:
Address 3 of algorithm area: A=A+E
Address 4 of algorithm area: A=A+F
Address 5 of algorithm area: A=A+G
Address 6 of algorithm area: A=A+H
“3” is the start point of the algorithm in the dongle; and “6” is the end point of the algorithm in the dongle. After
executing the instruction at address 6, the program will go to the user part. The calling of the program in the
dongle must begin from the start point of the algorithm. If the calling point is not the start point of the algorithm,
4 random numbers will be returned.
8.1.5.2 Restrictions on Algorithm Instruction
There are some restrictions on algorithm instruction. They are described below with some example instructions:
A=A+B Valid instruction
D=D^D Valid instruction
A=B Invalid instruction, must be in the format of algorithm, such as A = B | B
A=0 Invalid instruction, must be in the format of algorithm, such as A = A ^ A
C=3*B Invalid instruction, the constant must be postfixed, for example, C = B * 3
D=3+4 Invalid instruction, only 1 constant is allowed in an instruction
A=A/B Invalid instruction, the division operater is not supported
H = E*200 Invalid instruction, the constant must be lower than 64
A = A*63 Valid or invalid instruction, constants are not allowed in the first and last instructions
First we write the algorithm (We only need to write the algorithm once. The code used to write the algorithm(s)
to the dongle does not appear in the application delivered to the end user.)
p1 = 0;strcpy(buffer, "H=H^H, A=A*23, F=B*17, A=A+F, A=A+G, A=A<C, A=A^D, B=B^B,
C=C^C,D=D^D"); retcode = Rockey(RY_WRITE_ARITHMETIC, handle, &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
Then call the following algorithm from the program:
lp1 = 0; // Start point of calculation
Assuming that the value in module 7 is 0x2121, the result of this calculation will be:
((5*23 + 3*17 + 0x2121) < 1) ^ 0xffff = 0xbc71
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
char cmd[] = "H=H^H, A=A*23, F=B*17, A=A+F, A=A+G, A=A<C, A=A^D, B=B^B, C=C^C, D=D^D";
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
ShowERR(retcode);
return;
i++;
}
printf("\n");
for (j=0;j<i;j++)
{
/*
p1 = 7;
p2 = 0x2121;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 7: Pass = %04X Decrease no allow\n", p2);
printf("\n");
*/
p1 = 0;
strcpy((char*)buffer, cmd);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 1\n");
lp1 = 0;
lp2 = 7;
p1 = 5;
p2 = 3;
p3 = 1;
p4 = 0xffff;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=5, p2=3, p3=1, p4=0xffff\n");
printf("\n");
printf("Result = ((5*23 + 3*17 + 0x2121) < 1) ^ 0xffff = 0xBC71\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
}
In Step 25 we write algorithm ("A=A+B, A=A+C, A=A+D, A=A+E, A=A+F, A=A+G, A=A+H") to
the UAZ, and the calculation result is 0x7b17.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
printf("\n");
*/
p1 = 10;
strcpy((char*)buffer, cmd1);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 2\n");
lp1 = 10;
lp2 = 0x12345678;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE2, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("\n");
printf("Result =d03a + 94d6 + 96a9 + 7f54 + 1 + 2 + 3 + 4=0x7b17\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
}
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
p1 = 0;
p2 = 1;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 1;
p2 = 2;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 1: Pass = %04X Decrease no allow\n", p2);
p1 = 2;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 2: Pass = %04X Decrease no allow\n", p2);
p1 = 3;
p2 = 4;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 3: Pass = %04X Decrease no allow\n", p2);
printf("\n");
*/
p1 = 17;
strcpy((char*)buffer, cmd2);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 3\n");
lp1 = 17;
lp2 = 0;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE3, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("\n");
printf("Result = 1+2+3+4+1+2+3+4=0x14\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
In Step 27 we first search the dongle and get its hardware ID. Then we use the calculation 1 function in the
program to get the hardware ID again. Compare the two hardware IDs. If they are different the program will be
terminated.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
{
if (retcode == 0) return;
printf("Error Code: %d\n", retcode);
}
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD findlp1,truelp1;
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
findlp1=lp1;
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
p1 = 7;
p2 = 0x2121;
p3 = 0;
ShowERR(retcode);
return;
}
printf("Write Arithmetic 1\n");
*/
lp1 = 0;
lp2 = 7;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
printf("\n");
printf("Moudle 7 : %x\n", p3);
truelp1=MAKELONG(p2,p1);
printf("truelp1 : %x\n",truelp1);
if (findlp1==truelp1)
printf("Hello FeiTian!\n");
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
In Step 28 we get the return codes of a seed code with the calculation 2 function. Then we compare these return
codes with the return codes we get with the same seed code at the beginning of the program. If they are different
the program will be terminated.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
WORD rc[4];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
ShowERR(retcode);
return;
}
i++;
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
rc[0] = p1;
rc[1] = p2;
rc[2] = p3;
rc[3] = p4;
// :
p1 = 0;
strcpy((char*)buffer, cmd1);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 2\n");
lp1 = 0;
lp2 = 0x12345678;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE2, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
if(rc[0]==p1 && rc[1]==p2 && rc[2]==p3 && rc[3]==p4)
printf("Hello FeiTian!\n");
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
In Step 29 we get the values stored in the 64 modules by using the calculation 3 function. Remember that the
modules may not be read, even with the Advanced passwords. You may write some important data to the
modules or perform some other operations.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
p1 = 0;
p2 = 1;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 1;
p2 = 2;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 1: Pass = %04X Decrease no allow\n", p2);
p1 = 2;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 2: Pass = %04X Decrease no allow\n", p2);
p1 = 3;
p2 = 4;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
p1 = 0;
strcpy((char*)buffer, cmd2);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 3\n");
lp1 = 0;
lp2 = 0;
p1 = 0;
p2 = 0;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_CALCULATE3, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=0, p2=0, p3=0, p4=0\n");
printf("\n");
printf("Moudle 0: %x\n",p1);
printf("Moudle 1: %x\n",p2);
printf("Moudle 2: %x\n",p3);
printf("Moudle 3: %x\n",p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
In Step 30 we use all the three calculation functions and we write 4 calculation sections to the ROCKEY dongle.
The results of the three calculations are used for additional calculations. Of course you may let ROCKEY perform
much more complex calculations according to your situation.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "Rockey4_ND_32.h"
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
int t1,t2,t3;
char cmd[] = "H=H^H, A=A*23, F=B*17, A=A+F, A=A+G, A=A<C, A=A^D, B=B^B, C=C^C, D=D^D";
char cmd1[] = "A=A+B, A=A+C, A=A+D, A=A+E, A=A+F, A=A+G, A=A+H";
char cmd2[] = "A=A+B, A=A+C, A=A+D, A=A+E, A=A+F, A=A+G, A=A+H";
char cmd3[] = "H=H^H,A=A|A, B=B|B, C=C|C,D=A+B,D=D+C";
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("\n");
for (j=0;j<i;j++)
{
p1 = 7;
p2 = 0x2121;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 7: Pass = %04X Decrease no allow\n", p2);
printf("\n");
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
printf("\n");
p1 = 0;
p2 = 1;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 1;
p2 = 2;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 1: Pass = %04X Decrease no allow\n", p2);
p1 = 2;
p2 = 3;
p3 = 0;
p1 = 3;
p2 = 4;
p3 = 0;
retcode = Rockey(RY_SET_MOUDLE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 3: Pass = %04X Decrease no allow\n", p2);
printf("\n");
p1 = 0;
strcpy((char*)buffer, cmd);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 1\n");
lp1 = 0;
lp2 = 7;
p1 = 5;
p2 = 3;
p3 = 1;
p4 = 0xffff;
p1 = 10;
strcpy((char*)buffer, cmd1);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 2\n");
lp1 = 10;
lp2 = 0x12345678;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE2, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
p1 = 17;
strcpy((char*)buffer, cmd2);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 3\n");
lp1 = 17;
lp2 = 0;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE3, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("Result = 1+2+3+4+1+2+3+4=0x14\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
t3=p1;
printf("\n");
p1 = 24;
strcpy((char*)buffer, cmd3);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic \n");
lp1 = 24;
lp2 = 7;
p1 = t1;
p2 = t2;
p3 = t3;
p4 = 0;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
getch();
}
#include "stdafx.h"
#include "DrawCircle.h"
#include "DrawCircleDoc.h"
#include "DrawCircleView.h"
#include "DrawParamDlg.h"
#include "DrawMethodDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
TRACE("Origin\n");
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
m_lpCircleBuf[0].x = x;
m_lpCircleBuf[0].y = y;
m_nPointCount=1;
while(x<y)
{
x++;
if(p<0)
{
p+=2*x+1;
}
else
{
y--;
p+=2*(x-y)+1;
}
TRACE("%d,(%d,%d);",p,x,y);
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
m_lpCircleBuf[m_nPointCount].x = x;
m_lpCircleBuf[m_nPointCount].y = y;
m_nPointCount++;
}
TRACE("\n");
Initialize dongle:
#include "stdafx.h"
#include <windows.h>
#include "..\inc\Rockey4_ND_32.h"
retcode = Rockey(RY_FIND,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
if(retcode)
{
ReportErr(retcode);
return 0;
}
printf("Find successfully\n");
retcode = Rockey(RY_OPEN,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
if(retcode)
{
ReportErr(retcode);
return 0;
}
printf("Open successfully\n");
p1 = 10;
retcode =
Rockey(RY_WRITE_ARITHMETIC,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,cmdstr);
if(retcode)
{
ReportErr(retcode);
return 0;
}
printf("Write arithmetirc successfully\n");
retcode = Rockey(RY_CLOSE,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
return 0;
#include "stdafx.h"
#include "DrawCircle.h"
#include "DrawCircleDoc.h"
#include "DrawCircleView.h"
#include "DrawParamDlg.h"
#include "DrawMethodDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
WORD p1=0xc44c,p2=0xc8f8,p3=0x0799,p4=0xc43b;
DWORD lp1,lp2;
WORD handle[16];
BYTE buffer[1024];
int seed=0;
short p1,p2,p3,p4;
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
TRACE("Hardware\n");
m_lpCircleBuf[0].x = x;
m_lpCircleBuf[0].y = y;
m_nPointCount=1;
while(x<y)
{
p1 = p;
p2 = x;
p3 = y;
p4 = seed;
if(!RunRockey((WORD&)p1,(WORD&)p2,(WORD&)p3,(WORD&)p4))
{
// AfxMessageBox("Runtime error");
break;
}
if(p<0)
{
p = p1;
}
else
{
p = p2;
y--;
}
x++;
TRACE("%d,(%d,%d);",p,x,y);
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
m_lpCircleBuf[m_nPointCount].x = x;
m_lpCircleBuf[m_nPointCount].y = y;
m_nPointCount++;
}
TRACE("\n");
}
lp1 = 10;
retcode = Rockey(RY_CALCULATE1,&handle[0],&lp1,&lp2,&A,&B,&C,&D,buffer);
if(retcode)
return FALSE;
else
return TRUE;
Note: ROCKEY4ND has as many as 128 instructions. Developers do not need to consider the start and end
attributes of an algorithm. ROCKEY will automatically assign a Start/End attribute to the instructions. In practice
this means that if the developer writes a two-instruction algorithm to the User Algorithm Zone (UAZ), and then a
three instruction algorithm, the result will not be a single five instruction algorithm. Algorithms that begin with
“Null” or “E” will produce unpredictable results.
8.3 Tips
1. Make randomized calls to the ROCKEY API - Randomly scatter calls to the ROCKEY API from within your
application. Calls made to the API from time-to-time will make it very difficult to mimic the behavior of the
protection method or hack the application.
2. Use dynamic information with the seed code function -The use of dynamic information with the seed code
function, such as system date, makes the protection method stronger because the results can change with the
input and calculation.
3. Do not repeatedly use the same protection method in your application -If you use the same protection method
several times in your application it will be easier for the cracker to find the rule and crack your application.
Protection methods that are complex and rely on a number of different checks and calculations are the most
difficult to crack.
4. Encrypt the character string and data – In “Step 18” of this document we showed an encryption method using
information stored inside the dongle. Encrypting a character string in the manner described is a strong method
because a failure to properly decrypt the string can cause the application to terminate or take other actions in
accordance with the licensing agreement.
5. Use API encryption and Envelope encryption together – The strongest protection method will have the
developer first using a complex and dynamic implementation of the ROCKEY API, and then protecting this new file
with the ROCKEY Envelope.
Keep the end user environment in mind when you design the software protection solution. You should flexibly
adopt the methods suggested here within the limitations and objectives of your environment and licensing policy.
Chapter 9. FAQs
Some frequently asked questions about ROCKEY4ND are listed in this chapter. You may find the solution to your
problems with the use of the ROCKEY4ND dongle hereinafter.
Replace the current version of the driver with the newest version, which can be downloaded from Feitian
website. The website will be updated between whiles.
Check if the problem persists after using another computer with your device.
Check if your computer has been attacked by a virus or the like, which may block the program you are using.
9.2 FAQs
The evaluation kit is designed for developers to evaluate the dongle product. It usually includes a package,
documentation, a CD-ROM, and a dongle. The dongle is the same as the formal dongle, except that the access
password for it is public. If customers want to purchase the product after evaluation, a dongle with a unique
password will be provided for security consideration.
The order number is a reference number for management purpose in fact. It does not associate with the
passwords of the dongle directly.
That is impossible. The passwords of the dongle of each customer are different. We keep the record of each
customer. We can sign a security agreement with you if necessary. We will deliver the dongle to you as required.
Yes, they are very secure. They include 4 passwords divided into 2 levels. Each is 16 bits in length. The 1st level
includes 2 basic passwords for basic operations on the dongle. The 2nd-level passwords are dedicated advanced
passwords provided to developers for controlling writing to the dongle and defining encryption algorithms. These
2 passwords must not appear in the software delivered to end users. If the advanced passwords are entered in
error and the special memory has been written 4 times, the dongle will be locked for 2 seconds. No operations
can be performed during the 2 seconds. This measure prevents attempts of the passwords by attackers.
The dongles have the same order number. In other words, they share the same passwords. Each copy of the
software is delivered with a dongle to end users. Since all the delivered dongles have the same number, devopers
do not need to re-compile each copy of the software.
Use another dongle. Or, you must prove that you ordered that dongle before. For details, consult our post-sales.
The data sharer can be prevented if you do as follows: generate a random number at the beginning of the
program and store it at a fixed address in the memory of the dongle; and verify if the data at that address is equal
to the random number at runtime of the program. If the program is also running on another computer, which
works with the dongle, a different random number must have been written to that address.
9.2.8 Will it slow down the running of software to write a complex algorithm to the
ROCKEY4ND dongle?
No. The difference between the time consumed by the simplest algorithm and the time consumed by the most
compliex algorithm is merely several tens of milliseconds. If the complex algorithm is not invoked frequently, you
cannot perceive the slowness.
This problem occurs occasionally. Generally, your device is not attached properly to the computer, or some
interference exists. Remove your dongle and try to attach it again.
9.2.10 Why can’t I see the USB device in Device Manager when I use the dongle
with a Windows 98 computer which has a USB port?
If you are a testing user, you will be sent the last-minute updates. Otherwise, you can go to our website
(http://www.FTsafe.com) to get the latest DK.
9.2.12 I was prompted “Rockey4ND.dll not found” when protecting FoxPro and VB
programs by calling APIs. What is the problem?
Although Rockey4ND.dll is present under current directory, you must copy it to a system directory because FoxPro
and VB programs find the dynamic-linking libraries only in system directory.
Directory Description
Setup.exe Installer