Software protection and hardware keys

Description

The MMS’s global study shows that 41% of all packaged software in use 2006 was
illegal. It is therefore important for software companies to protect their software
against illegal usage. MMS has developed a program for the Banking industry and
needs a way to protect their software.
This Master Thesis evaluates different techniques used for software protection.
We present a solution that builds on the use of a hardware key. Four hardware keys
are tested in order to select the right key. It is then adapted to meet MMS criteria.

Reviews
Shared by: Nilakshi Das
Stats
views:
283
rating:
not rated
reviews:
0
posted:
9/15/2009
language:
English
pages:
0
Hardware Based Software Protection Solution Nilakshi Das July 12, 2008 Indian Institute of Technology Kharagpur MSC in Engineering Department of Computer Science and Engineering 1 / 38 Preface This Master Thesis was written as the final examination of the MSC Programmer in Computer Science and Engineering at Indian Institute of technology Kharagpur. The subject was Software protection and the purpose was to help MMS (Mind Mill Software Limited protect their new program, BMill software, against software piracy. I want to thank MMS for giving me this opportunity, Luis D. Wasserman , my supervisor for all the support. Abstract The MMS’s global study shows that 41% of all packaged software in use 2006 was illegal. It is therefore important for software companies to protect their software against illegal usage. MMS has developed a program for the Banking industry and needs a way to protect their software. This Master Thesis evaluates different techniques used for software protection. We present a solution that builds on the use of a hardware key. Four hardware keys are tested in order to select the right key. It is then adapted to meet MMS criteria. 2 / 38 Table of Contents 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 1.1 Structure of the report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.2 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3 Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 7 2 Threat Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 Reverse engineering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Cracking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 2.2.2 Modification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.3 Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.4 Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Tools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1 Disassemblers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Decompilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . 3.3 Monitoring tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . 3.4 Other tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 7 7 7 8 8 8 8 8 9 9 4 C#, .NET and JIT compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 5 Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.1 Obfuscation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.1.1 Lexical transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.1.2 Control transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.1.3 Data transformation . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 10 5.1.4 Layout obfuscation . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 10 5.2 Tamper proofing . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 10 5.2.1 Checksums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.2.2 Guards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 5.3 Loaders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 5.4 Fingerprinting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 5.5 Diversity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 5.6 Cryptography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . 12 5.6.1 Symmetric cryptography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . 12 5.6.2 Asymmetric cryptography (also known as Public key cryptography) . . . 12 5.7 CD-protection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 5.7.1 Dummy Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5.7.2 Oversizing/Overburn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5.7.3 Physical errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5.8 Internet connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5.8.1 Activation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 14 5.8.2 Verification on each execution . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . 14 5.8.3 Client-Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 5.9 Hardware keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 5.9.1 Storage of data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . 14 5.9.2 Hardware encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . 14 5.9.3 Loaders and obfuscators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 5.9.4 Remote updating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3 / 38 5.9.5 Hardware clock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6 Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6.1 Components in a solution . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 15 6.1.1 License data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6.1.2 Storage place . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6.1.3 Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . 15 6.1.4 Protection of the program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6.2 Analyzing the alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . 16 6.2.1 Storage place . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 6.2.2 Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 6.2.3 Protection of the program file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 6.2.4 Consequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 6.3 Selection of solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . 17 7 Delimitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . 17 8 Hardware keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 9 Test plan. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 18 9.1 Modifying the program file . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 19 9.2 API-hooking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 9.3 Win32 debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 19 9.4 Remote update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 10 Presentation of the hardware keys. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 10.1 Aladdin Knowledge Systems . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 19 10.2 Safenet Inc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 10.3 SecuTech Solution Inc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 10.4 WIBU Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 11 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 11.1 The Hasp HL API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 11.2 The Sentinel API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 11.3 The UniKey API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 11.4 Codemeter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 12 Results of the test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 12.1 Modifying the program file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 12.1.1 Analysis of the program file . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . 24 12.1.2 Roundtripping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 12.1.3 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . 25 12.2 API-hooking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . 25 12.2.1 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 12.3 .NET debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 12.3.1 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 12.4 Remote updating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 13 Selecting a hardware key. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 13.1 UniKey. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4 / 38 13.2 Sentinel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 28 13.3 Codemeter and Hasp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 14 Additional work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . 28 14.1 Binding a key to a specific computer . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 14.2 Code generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . 29 14.3 Automate the Hasp Envelope . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 30 14.4 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 14.4.1 Class protection . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 31 14.4.2 Representation of encrypted data in textform . . . . . . . . . . . . . . . …. . 31 15 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 16 Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16.1 Future work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16.2 The subject . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . 16.3 The future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 33 33 33 Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Hardware Key Comparison Table. . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 38 5 / 38 1 Introduction 1.1 Structure of the report The report consists of eight parts: 1. Chapter 1 - We go through the background and purpose of the thesis. 2. Chapter 2 – 4 - Shows the threat model when we want to protect an application against illegal usage. 3. Chapter 5 - Lists software techniques used to combat crackers and reverse engineers. 4. Chapter 6 – 7 - Is where we decide how MMS program should be protected. 5. Chapter 8 – 13 - Cover the process of selecting the best hardware key for the job. 6. Chapter 14 - We adapt our solution to MMS needs. 7. Chapter 15 - The solution is evaluated. 8. Chapter 16 - We discuss future work, the subject and how software protection might evolve. 1.2 Background MMS is an India company that develops programs for banking simulation. The company’s previous program, CARE for Mining, was created for a single customer, Atlas Copco. It focused on loading and transportation. The new program, MMS , is used in Business development and targets all Finance companies. In order to prevent illegal copying of the program, MMS wants to use some kind of license protection. This protection should also stop legal customers from using more licenses than they have paid for, so called sublicensing [25] or softlifting. We believe that this category is the one that would cause the largest loss of income in the form of lost sales. The risks connected to overuse of licenses are smaller than for distributing the software to other companies. Protecting software against software piracy and sublicensing belongs to the area of Software protection. The area is still new but it is gaining more and more attention. P. C. van Oorschot [24] states that: Software protection falls between the gaps of security, cryptography and engineering, among other disciplines. Despite its name, software protection involves many assumptions related to hardware and other environmental aspects. A significant gulf currently exists between theory and practice. Inconsistencies have arisen in the relatively sparse (but growing) open literature as a result of differences in objectives, definitions and viewpoints. All of these issues provide research opportunities. Collberg and Thomborson [1] points out that the most research in computer security has focused on protecting a computer and its data against malicious programs. This scenario they call malicious clients. Software protection is based on the scenario called Malicious hosts where the software needs to be protected against the computer on which it is installed. Attacks on the software in this scenario are often classified as intellectual property violations. The interest for Software protection is raising since software piracy is a major concern for everyone that sells software. The BSA (Business Software Alliance) 6 / 38 estimates that 35% of all software installed on computers 2006 was illegal [26]. The estimated losses because of lost sales were 40 billion dollars. As Collberg and Thomborson [1] points out, it is much more difficult to protect a program against the computer it resides on than protecting a computer against a program. By restricting the number of actions the program might do, one can protect the computer. A program however cannot be protected in the same way since it is not able to restrict the actions of the computer. 1.3 Objectives The purpose of this Master Thesis is to develop a solution that does the following: • Prevents illegal distribution both inside the customer’s company and to people outside. • Supports licensing of extra modules. These should be bound to a single license of the main program. If a company buys two base licenses and one module license then the module license should only work with one base license. • The solution must be compatible with .NET 1.1. • A license should be bound to a certain program version. Licenses from an older generation should not be able to unlock newer generations. • A license should be bound to a computer. It is not supposed to be used on several computers. If possible, the solution should also support: • Time based licenses that only work for a certain time period. • Network licenses that enable the customer to use a specific number of licenses at the same time using a server on the customer’s company. 2 Threat Model The two main threats that the software should be protected against are reverse engineering and cracking. 2.1 Reverse engineering Reverse engineering is about learning how things work by taking them apart and study them [27]. A possible scenario is that a competing company extracts the most important parts of the program through reverse engineering. Then they use these parts in their own software and save developing time and money. Crackers, when trying to understand how the program is protected, also use reverse engineering. 2.2 Cracking Cracking is about circumventing or removing the protection of a program in order to run it without a license. Main and Oorschoft [4] divide attacks on software into four steps. Here we give a summary of the four steps when it comes to cracking. 2.2.1 Analysis Analyzing the software protection is the first step in removing it. If it is simple and entirely software based it can suffice to find the exact location of the call to the security code in the program file [5]. A few examples of tools used in this step are debuggers, disassemblers and decompilers. 7 / 38 2.2.2 Modification The next step is to modify the program. The goal can be to remove a license control or activate more functionality in a demo version. If the source code was retrieved in step 1, a cracker might make the changes in the code and then recompile it into a new executable. Another way is to make the changes directly in the program file using a hex editor or a similar tool. 2.2.3 Automation The program has successfully been modified. Many crackers then try to automate the modification so it can be distributed without the program file itself. It is common to create a patch file that, when executed, applies the changes to the program. If the changes are extensive the cracker might distribute the modified files instead, skipping step 3. 2.2.4 Distribution The patch or the files are then distributed to other people through, for example, forums on the Internet. One motive can be to make money, either through charging for the files or by distributing the files on web pages filled with commercial. The cracker could also look for recognition in cracker societies. An attack does not need to involve all the steps. Someone who just wants to unlock the program for personal use does not necessarily go through step 3 or 4. Reverse engineering can be said to consist of step 1, and sometimes step 2 if the program must be modified in order to allow study of the source code. 3 Tools In this chapter we list tools that are frequently used by crackers and reverse engineers. 3.1 Disassemblers A disassembler transforms binary code to assembler code. Legal uses are automated code optimization, troubleshooting programs and reconstruction of lost code. Disassemblers are used in reverse engineering to retrieve the source code in assembler format. More advanced disassemblers like IDA (Intelligent Disassembler Pro) [9] can identify API (Application Programming Interface) calls and generate call graphs. For disassembly of .NET applications there are several tools. One of them is ILDASM (MSIL Disassembler) [10] which is included in the .NET SDK (Software Development Kit). It can be used together with the assembler ILASM (MSIL Assembler) to achieve roundtripping. That means the program is disassembled, changes are made in the assembler code and the program is then assembled again. 3.2 Decompilers The decompiler is similar to the disassembler but performs additional steps to transform the assembler code into a high-level language. Programs written in non-type-safe languages like C and C++ are hard to decompile while programs compiled to an intermediate language intended to run on a virtual machine, are 8 / 38 relatively easily decompiled [4]. Two examples of intermediate languages are Java’s bytecode and .NET’s MSIL (Microsoft Intermediate Language). 3.3 Monitoring tools Process Monitor [12] is a monitoring tool for Windows. It monitors all processes in real-time and reports for example interactions with the file system or the registry and loading of DLLs (Dynamically Linked Library). A cracker can use Process Monitor to see which DLLs a program uses, which files it reads from or writes to and which keys in the registry that it uses. 3.4 Other tools Another type of monitoring tools is installation monitors that register every action during the installation of a program. The purpose is to enable the user to restore the computer to that state it was in before the installation. CrackZ’s [6] list over tools, that should be included in a cracker’s/reverse engineer’s toolbox, also includes InstallShield decompilers and resource editors. 4 C#, .NET and JIT compilation One of the goals with C# was that it should be platform independent. It has been achieved by letting the C# code be compiled to MSIL code and meta data which are then combined to a PE (Portable Executable) file or a DLL. In this way the generation of machine code is delayed. When the file is executed on a computer with a CLR (Common Language Runtime) compatible runtime environment, the methods in the program are compiled to machine code when they are used. This is called JIT (Just In Time) compilation. A method only needs to be compiled once during an execution because the result of the compilation is stored in the memory. The concept resembles Java’s bytecode. A difference is that Java programs often use an interpreter even if Java also supports JIT compilation. A downside with this concept is that the meta data included in the PE file contains lots of information about the MSIL code. Aladdin estimates that it can be compared to shipping an ordinary Win32 application with all the debug information included in the file [8]. This makes decompilation of .NET applications considerably simpler than decompilation of ordinary Win32 applications. 5 Theory 5.1 Obfuscation Obfuscation is about transforming source code in a way that preserves the behavior but makes the resulting code very hard to understand. The goal is to make analysis and understanding of the code so hard that it is simpler to write a new program with the same functionality [2]. If the program’s behavior has been preserved, the only differences a user will notice are the size of the files and the execution speed of the program. How these are affected depends on the original code and on which obfuscation techniques that are used. Collberg and Thomborson [1] divide obfuscation techniques into three categories: 5.1.1 Lexical transformation Programmers usually try to give all identifiers in the code informative names in 9 / 38 order to make it easier to understand. A lexical obfuscator renames as many identifiers as possible without breaking the program. Classes that are to be exported in DLLs cannot have their public parts lexically obfuscated. The programs using the DLL would not find the exported classes if they changed name. Although the code gets harder to understand, it is still the same code with different names, so a dedicated attacker can still figure out the purpose of the code. An example of a tool that uses lexical obfuscation is Dotfuscator [3]. A decompilation of a “dotfuscated” program shows that Dotfuscator tries to give all identifiers the same name by taking advantage of scope, method overriding, method overloading and more. In the cases when that is not possible it chooses a similar name to create further confusion. 5.1.2 Control transformation Control transformation tries to make the program flow hard to follow. Collberg’s and Thomborson’s [1] example uses, so called, opaque predicates, expressions whose results are known at obfuscation time but hard to calculate for a deobfuscator. With the help of these, code blocks can be divided into several parts and new code blocks added to the code. By using the opaque predicates to direct the program flow, it can be made sure that these new blocks are never executed even if it might seem so when analyzing the code. 5.1.3 Data transformation An example of data obfuscation is variable splitting. A variable is replaced by several new variables that together contain the value of the original variable. Simple Boolean comparisons can then be replaced by advanced integer expressions that involve all the new variables. Naumovich [2] also places techniques that obfuscate high-level design in this category. Examples of these techniques are merging several classes into one big class or splitting a class into several classes and connecting them through inheritance. 5.1.4 Layout obfuscation Naumovich [2] also adds the category Layout obfuscation to the other three. It contains techniques like inlining and outlining. Inlining is normally used in code optimization and replaces calls to a function with the code in the function. It is usually applied on small functions, which are frequently used, to save the extra instructions needed for a function call. Outlining is the opposite where code is replaced by a call to a function that contains the original code. Both techniques are here used to obfuscate how the original code was divided into functions. 5.2 Tamper proofing Here we present techniques that can be used to prevent modification of a program. 5.2.1 Checksums Checksums are used to detect changes in files. By calculating a checksum of the program file and compare it to a precalculated checksum, one can see if the file has been modified in any way. Popular algorithms for calculating checksums are MD5 (Message Digest) [15] and SHA-1 (Secure Hash Algorithm) [16]. The use of checksums does not in itself make the program tamper proof. Normally the checksum test is used in combination with code that acts on the result of 10 / 38 the test. The extra code could, for example, stop the execution of the program if the program file has been changed. 5.2.2 Guards Chang and Atallah [17] propose a scheme where a network of, so called, guards are added to a program. A guard monitors a part of the code by calculating a checksum and compares it to a reference value. If the code has been changed the guard can choose between actions such as crashing the program, log the change or try to repair the code. The guarded areas are chosen so that the guards protect each other’s guard code. If someone wants to change the code they will have to remove all guards. 5.3 Loaders The purpose of adding a loader to a program is to avoid storing the program in an unprotected form on the hard drive. The loader is packaged with a protected version of the program. The protection can consist of encryption and/or compression. When the file is executed the loader unpacks the program and then transfers the control to the program. Making changes to the program without unpacking it is extremely hard, especially if the encryption algorithm is of the type where a little change in the encrypted data affects a large part of the original data. A cracker usually tries to either modify the loader part so that it unpacks the program onto the hard drive or makes a memory dump to retrieve the unprotected program when it is unpacked in memory. A loader must therefore protect itself against debuggers in order to be secure. Many manufacturers of hardware keys ship their keys with software that can protect the program. Some examples are Hasp’s Envelope [18], UniKey’s envelope and Safenet’s Sentinel Shell [19]. A lot of these protection programs use loaders as a part of the protection. If the loaders use their keys to unpack the program they complicate static analysis and reverse engineering of the loaders compared to strictly software-based loaders. Software-based loaders usually have to store everything that is required to unpack the program, on the computer. Zunke [8] describes in his article a .NET loader that installs decrypting filters on the process’ I/O-communication before the control is transferred to .NET’s runtime environment. When the runtime environment reads the program from the file the filter transparently decrypts the data. We are unsure if all .NET loaders must use the same approach because of the JIT compilation or if the whole program can be decrypted directly and handed over to the runtime environment. The filter solution sounds more secure if it prevents a cracker from retrieving the whole program through one single memory dump. 5.4 Fingerprinting Fingerprints in software are used to track a program to its buyer. They are stored in the program and can consist of, for example, a text string that is shown when the 11 / 38 program encounters a specific input. If the customers are aware that their program can be tracked to them, they will be less eager to give away copies of their software. Fingerprints are related to watermarks. The techniques that are used are the same but the purposes are different. The purpose of watermarks is to prove who has written the software. Collberg and Thomborson [1] list several types of watermarks. Most of them are however destroyed if someone uses an obfuscator on the program. 5.5 Diversity In the nature, genetic diversity makes it more difficult for viruses and diseases to infect an entire population. Software diversity [14] uses the same idea for software. If every instance of the program differs from the others, it will make them more resistant to viruses and patches. If it is very difficult to create a generic patch, crackers will distribute the files instead. When this technique is combined with fingerprinting it will be possible to track the illegal copies, given that the fingerprint is still intact. 5.6 Cryptography Cryptography has been used for a long time [20]. The purpose of encryption is to convert a plaintext to a cipher text. The conversion from cipher text to plaintext is called decryption. Most modern encryption algorithms use a key as a secret parameter to the encryption process. It is not enough to know which algorithm that has been used. One needs to know the key in order to decrypt the message. Two areas in cryptography are symmetric and asymmetric cryptography. 5.6.1 Symmetric cryptography The same key is used for both encryption and decryption. The sender and receiver must share the key. Two categories of symmetric encryption algorithms are block ciphers and stream ciphers. Block ciphers encrypt one block of text of a certain size at a time. Popular block cipher algorithms are AES (Advanced Encryption Standard) [21] and DES (Data Encryption Standard) [22]. Dividing the data into blocks and then encrypting them separately does not hide patterns in the plaintext. That is why, so called, encryption modes [42] have been developed. They are algorithms that are used together with block cipher algorithms. ECB (Electronic Code Book) mode is the simplest one where every block is just encrypted separately. More advanced modes such as CBC (Cipher Block Chaining) and CFB (Cipher Feedback) uses data from other blocks when encrypting a block. That means a block will be encrypted differently if its position in the plaintext is changed. 5.6.2 Asymmetric cryptography (also known as Public key cryptography) In public key cryptography two keys are used, one public and one private. The keys are related but constructed so that it’s computationally infeasible to calculate the private key from the public key. Public key cryptography is easiest described by an example: A and B each have a public and a private key. They also have access to each other’s public keys. If A wants to send a message to B, then A uses B’s 12 / 38 public key to encrypt the text. The keys are chosen so that B’s private key is the only one that can decrypt the message. As long as B is the only one that has access to the private key, B will be the only one that can decrypt the message. The same goes for A’s keys. One big advantage over symmetric cryptography is that A and B do not need to agree on a shared secret key. They can also use the same keys when communicating with other people. And if someone manages to get hold of one of the private keys, they will only be able to listen to one of A and B. Most public key algorithms require computationally expensive operations compared to symmetric encryption. A solution is to use a combination of the algorithms. Public key cryptography is used to decide which symmetric key that will be used for the rest of the communication. Public key cryptography is also used for signing. A checksum is calculated on the data that is to be signed. Then the checksum is encrypted with the private key. Other people can then read the checksum with the public key and compare it to one they calculate themselves. But only the one who has the private key can change the checksum. .NET supports signing of assemblies. It is called strong naming [23]. 5.7 CD-protection One way of preventing illegal copying of a program is to protect the installation CD so that a user is not able to make copies of it. That does not, however, stop the user from installing the program on several computers. A solution might be to make the program require the CD when running. This type of protection is more suited for games than for office applications. If every office application needed a CD at runtime then each computer would need several CD-readers, if several programs need to be used at the same time. CD Media World [37] gives some examples on how a CD can be protected against copying: 5.7.1 Dummy Files Extra files are added to the disc. By modifying the FAT (File Allocation Table) these files can be made to contain a part of another file. If a program uses the FAT to copy the files it will seem like the disc contains more data than it should be able to. However, this won’t fool a program that does not use the FAT and only focuses on burning an exact copy. 5.7.2 Oversizing/Overburn Some discs are protected by burning extra data outside the regular area. Only some CD-writers are able to do this. Since not all CD-readers are able to read outside the regular area, the extra data usually is not used. It is only there to make copying harder. 5.7.3 Physical errors Another way to prevent copying of the disc is to burn errors onto the disc on purpose. A copy program will most likely report the disc as damaged and stop copying. 13 / 38 5.8 Internet connection An Internet connection can be used for several types of license protection schemes. Some examples are: 5.8.1 Activation The program is shipped in an inactive state and must be activated before it can be used. An activation can, for example, consist of the program connecting to a server at the manufacturer to be verified the first time it is run. To make the program inactive, when it is shipped, some important files could be excluded. The program then downloads them from the server when it is activated. The files should preferably be adjusted to work only with the computer where the activation took place. It will prevent that someone just copies the installed program after it has been activated. 5.8.2 Verification on each execution If the program connects to the license server on every execution the bond between them will be stronger. But it requires that the user’s computer has access to the Internet each time the program is started. An even stronger bond can be achieved if the server stores some critical data so that the program must access the server several times during an execution. 5.8.3 Client-Server The most secure solution is if the program is running on the server and the user interacts with it through a client program. However, a client-server solution requires a stable and fast Internet connection between the user and the manufacturer’s server. Otherwise the program might be slowed down or, if the connection is broken, not function at all. 5.9 Hardware keys A hardware key is a hardware component that is used together with the program it is supposed to protect. If the key is not connected to the computer then the program won’t work. The hardware keys often use the USB-port or the parallel port. Some newer keys are in the form of Smart Cards. A hardware key adds an extra cost to each copy of the program. Therefore hardware keys are mostly used with expensive programs where the price of the key does not affect the price of the software very much. The hardware keys have evolved over time. Here we list features that are somewhat common: 5.9.1 Storage of data Many keys can store extra data that can be used for license information, hardware fingerprints and more. The protected program can read from and write to the key, through the use of an API, which is a programming interface for the key. The API is often in the form of a programming library. 5.9.2 Hardware encryption Most keys offer the possibility to encrypt and decrypt data with the key. The data is passed to the key where it is encrypted and then returned. The same goes for 14 / 38 decryption. This means that the symmetric encryption key never has to leave the hardware key. 5.9.3 Loaders and obfuscators Many keys are shipped with software that can add a loader to the program that has to be protected. Often the software also obfuscates the original program for extra protection. This combination of loader and obfuscator has many names, for example hardened wrapper, shell or envelope. The loaders have an advantage over regular loaders in that they can use the hardware key for encryption and decryption. This means they do not have to store any encryption keys in the loader code itself. Often the protection software also adds periodic calls to the key in the program. The purpose is to make sure that the key is not removed after the start-up 5.9.4 Remote updating With early keys the customer was forced to send the key back to the software manufacturer if it was to be updated with new licenses. And during that time the customer was unable to use the software. It also resulted in extra work for the software manufacturer. That is why many keys now support remote updating of keys out in the field. The update often consists of an encrypted file that is sent to the customer and then applied through the use of a special program. 5.9.5 Hardware clock Some hardware keys contain a hardware clock for time-limited licenses. It gives the advantage of not having to rely on the system clock of the computer in any way. However, the clock requires a battery, which limits the lifetime of the key. But if the key is designed correctly only the time-limited licenses are affected. 6 Model 6.1 Components in a solution From MMSrequirements and considering the tools used by crackers, we concluded that our solution would need the following components: 6.1.1 License data Data that contains information about which licenses the customer has. Using this data the protection should be able to decide if it should allow the program to run and which additional modules it is allowed to use. 6.1.2 Storage place The license data must be stored somewhere where the protection can access it. The storage place should be protected so that a cracker can’t modify the data but it should allow updating if additional licenses are bought or existing licenses are upgraded. 6.1.3 Communication If the license data is not stored in the program itself then the program must communicate with the storage place. The communication must be protected against both eavesdropping and hijacking. One way is to use strong encryption. 6.1.4 Protection of the program Since there are several decompilers available for .NET, the program file must be 15 / 38 protected against decompilation and modification. It should also be protected against debuggers. We think that the program on the customer’s computer always should be protected in this way, even in a client-server solution. Protecting the client will make it harder to study the communication between the client and the server. 6.2 Analyzing the alternatives 6.2.1 Storage place We considered the hard drive (files or the registry), the CD, a server at MMS or a hardware key as storage places. A CD is permanent and updating licenses would require a new disc. The disc also needs to be present every time the program is run. The hard drive is a storage place where the user has full control. With programs like Process Monitor, a cracker could identify the files and registry values that might contain the license data. Since they can easily be copied to another computer the strength of the protection will depend on its ability to determine if the program still resides on the computer it was installed on. A server-solution means that a license server decides whether the program is allowed to start or not. This way the server can control that two computers using the same license can’t use the program at the same time. It limits the damage that can be done if a cracker manages to trick the program into believing that it is still on the computer where it was activated. A hardware key also limits the use of a license to one computer at a time since the program requires the key’s presence. If someone wants to use a single license on several computers at the same time they need to either copy the key, emulate it or remove the program’s dependence on the key. 6.2.2 Communication The communication between the license server and the protection can be protected with asymmetric encryption. Many hardware keys also use encryption to protect the communication between the key and the program. Often new keys are chosen for each execution to make eavesdropping and emulation harder. 6.2.3 Protection of the program file Protecting the program file can be done by using a loader. Then the program will not lie unprotected on the hard drive. An obfuscator should also be used so the code is hard to understand if a cracker manages to unpack the program. As mentioned earlier many hardware keys are shipped with software that can do this. An Internet solution has to use a separate loader. We think that the loaders taking advantage of the hardware keys in the loading process have a higher potential. A loader could retrieve critical data, like encryption keys, from a server or send data that is decrypted by the server. However, we have not found a loader that does this. There is also the risk that calls to a server might be easy to spot in the code. 6.2.4 Consequences If a hardware key is used to protect the program, the key will occupy one USBport. 16 / 38 The user also needs to keep the key safe when it is not used. If a program must contact a license server each time it is started or more often, it will require access to the Internet each time. Ongoing communication requires a stable and fast connection. The company must handle the hardware keys. They must be ordered and initialized before they can be shipped. Keys that get broken or get lost result in extra work for the support division on the company. A server-solution requires a server and a permanent Internet connection at the company. If the server is broken or the connection to the Internet is lost, none of the customers will be able to use the program. The first scenario can be avoided by having a backup server ready to take over if the primary server goes down. To avoid the second scenario an extra connection to the Internet is required. Preferably one that does not use the same network paths so that one error does not break both connections. A problem with a server-solution is that the program’s lifetime directly depends on how long the company will run the server. This means that the server must run as long as someone might still be using the program. An alternative is to state a maximal lifetime for the program when it is sold. 6.3 Selection of solution We decided to use a hardware key because it had the following advantages over the main competitor, the license server: • It does not require a server at the software company. • The program won’t require Internet access, which is an advantage especially in countries where the Internet infrastructure is bad. • There will be lesser changes in the code than if a part of the program would have been placed on a server. We are, however, aware that a client-server solution where all the program logic is located on the server would be the safest alternative. In order to use the program, without a license, one would have to either replace the server-part or trick it into believing that one has got a license. Replacing the server-part is practically to rewrite the part, perhaps with the help of a black box study of the server program. The license server should be hard to trick if it uses a list with all users allowed to use the program. And even if someone tricks the server, there will always be a chance that it is discovered because the server is still used. We should also mention that we would probably have chosen a client-server solution of some sort if MMS program had belonged to the lower price classes. This is because the extra price for a hardware key for every copy would have affected the price of the software too much. But here the price of a hardware key only makes up 1-2 percent of the price of the program. 7 Delimitations 17 / 38 There are many hardware keys on the market and there is not time enough to test them all. Therefore we choose to test only the keys that meet the following criteria: • The key has its own loader/obfuscator that supports .NET 1.1. We then get a loader that is most likely taking advantage of the hardware key. If this is done in a good way, access to the key can be a requirement if someone wants to remove the loader-part. Otherwise one might have to decrypt AES-encrypted data in order to run the program. Since only customers have keys, the number of potential attackers is greatly reduced. • It should be possible to remotely update a key in the field. This simplifies the updating process since the customer does not need to send the key to the software company. • The key must have an API for C# with .NET 1.1. • The key must support time-limited licenses. Furthermore, the following delimitations will be used: The hardware key’s own loader/obfuscator will be used for reasons mentioned above. We will not test separate loaders or obfuscators. Neither will we examine the possibility of writing our own loader, or obfuscator, when that is material for several master theses. We will analyze how secure the keys are. Unfortunately there is not time enough to cover all areas when several of areas require extensive studies. We have therefore chosen to focus on the program-side. The keys will not be picked apart and examined when such a test could be a master thesis in itself. Kingpin’s [25] test of three USB-keys is an example of how such a test would look like. The reason why we won’t investigate the guard concept, presented in section 5.2.2, further, is that their system was created to protect Win32 applications, not applications that are to be JIT compiled. The guards wouldn’t know the checksums for the assembler code since the code is generated at execution time instead of compile time. 8 Hardware keys Nine hardware keys were found using search engines and through references in articles about the subject, five of these met the requirements listed under delimitations. Most of the others were missing a loader/obfuscator that supported .NET. Of the five keys we found, MMS ordered four. They decided not to order the last one when they discovered that the company’s order form was not protected. Software Development Kits were ordered for the following keys: Company name Key model Aladdin Knowledge Systems Hasp HL (Time) Safenet Inc. Sentinel Hardware Keys SecuTech UniKey Time WIBU Systems Codemeter 18 / 38 9 Test plan In order to find out which key is best suited to protect MMS software, we will compare them in a number of areas. To avoid writing four different test programs we will create an adapter class [34] for each API. The test program will then be able to work in the same way with all four keys. This means that all code, except the part that directly communicates with the key’s API, can be reused. 9.1 Modifying the program file With the tools Reflector (decompiler), ILASM (.NET assembler), ILDASM (.NET disassembler) and CorDbg (.NET debugger) we will try to modify the test programs. In each test program (one for each key) we place a code piece that calls MessageBox’s Show-method to show a message. We will try to remove this call so that the message is no longer shown. The modification is to be done in such a way that nothing else in the program is affected. Reflector and CorDbg are used to locate where in the code the call takes place. ILDASM and ILASM are used to apply the changes through roundtripping. 9.2 API-hooking We will explore the possibility to replace the DLL, which contains the API for the hardware key, with our own DLL. This involves creating a DLL that exports the same symbols as the original one. And then we try to force the program to accept the new DLL. 9.3 Win32 debugger Running the programs with OllyDbg [44] tests their protection against debuggers. As the OllyDbg help file [43] states, the debugger is not made to debug .NET applications. .NET programs are compiled during execution, which means that the code displayed by the debugger can vary between different computers. The purpose of the test is to see if the loader-part is protected against debugging. Since loaders are executed before the .NET runtime environment takes control, they are not written in .NET. 9.4 Remote update Finally we will test how easy it is to update the keys using remote updates. For each hardware key we create an update that adds one license and removes another one. 10 Presentation of the hardware keys 10.1 Aladdin Knowledge Systems Aladdin Knowledge Systems [29] was founded in 1985 and has its headquarters in the USA and Israel. The SDK that was ordered contained a Hasp HL Time, which is the key in the HL-series that supports time-limited licenses with the help of a hardware clock in the key. 19 / 38 Figure 1: Hasp HL Time 10.2 Safenet Inc. Started as the company IRE (Industrial Resource Engineering) in 1983 [30] but changed the name to Safenet in the year 2000. The company merged with Rainbow Technologies in 2004. The headquarters lies in the USA. We tested the key model Sentinel Hardware Keys. Figure 2: Sentinel Hardware Keys 10.3 SecuTech SecuTech is a Canadian company that sells the hardware key UniKey. The key stands out with its reasonable price with flexible functions, especially they have customization service such as product labeling, OEM, device naming which attract high end software vendors. With the device naming service, the hacker will not know which brand of dongle the software vendor is using. The implementation service and free technical support service which make developers implement hardware keys easily. Figure 3: SecuTech UniKey Time 20 / 38 10.4 WIBU Systems WIBU Systems is a German company that was founded in 1989 [31]. The key we tested, Codemeter, is a part of what WIBU calls the fourth generation of software distribution [32]. The idea is that a user should be able to store licenses from several companies in the same key, which is then bought separately. The price of the key is then distributed over several licenses, which might make hardware keys an alternative even for software in the lower price classes. Figure 4: Codemeter 11 Implementation To be able to use the same test program for all keys we wrote an adapter class for each API. The test program could then work in the same way with all the keys. 11.1 The Hasp HL API To use the API we only needed to link an assembly. The API is built around the Hasp-class, which is used for logging into features. Features are Hasp’s representation of licenses and are identified by a number. There is also a zerolicense that is always available as long as the key is connected and the correct vendor code supplied in the login call. A Hasp-object that is logged in can be used to perform common tasks such as read, write and encrypt. Often only one function call is required for the task itself and some additional code that checks the return code from the function. The only problem we found was that the read- and write-functions in the Hasp-class did not accept any other value than 0 for the offset parameter. Hasp’s Swedish support, Kordab [35], helped us with a workaround. First we had to set the property FilePos, to the offset we wanted to use, before the call. We could then send 0 as offset and the function would use the offset in FilePos. 11.2 The Sentinel API Sentinel’s API is like Hasp’s API built around a main class, in this case SentinelKey. But they have chosen another approach to licenses. Here a main license is used, which contains features. A feature can, for example, be an integer, Boolean, string, counter or encryption with a specific key. The program Toolkit is used to specify which features a license will contain. It then generates some class files that must be included in the program that is to be protected. One of the files contains constants for the features that have been created. If these are changed, the files have to be regenerated through the Toolkit program. In order to use the API, a DLL is also required. It is linked with DLLImport in one of the generated files. The idea behind Sentinel’s features is that they can be used as licenses. For 21 / 38 example, the type of feature that offers AES-encryption can be time-limited. In our adapter class we choose to use Boolean features to represent licenses. Unlike Hasp, Sentinel’s AES-encryption could only encrypt 16 bytes at a time. In the manual Sentinel suggests “For larger data, you can use the functions in a loop.”[36]. That is in other words, Electronic Code Book mode [42]. This solution has a weakness in that the encryption does not hide patterns in the plaintext and that blocks can be manipulated without other block being affected. How serious this is depends on the data that is protected. We think that the API should have a function that takes a byte-array of arbitrary size and uses an encryption mode where the encryption of one block affects the others. Examples of such modes are Cipher Block Chaining or Cipher Feedback [42]. The key also supports signing and verification through the use of ECC (Elliptic Curve Cryptography) [39]. We didn’t encounter any problems with the API itself, only with the Toolkit program. It was not possible to create new license templates since the program claimed that a template with the same name already existed. It didn’t matter which name we picked. This could be remedied by uninstalling the program, removing the files left behind and then do a reinstallation. 11.3 UniKey API UniKey Enveloper works with Windows Portable Executable (PE) files. While the exe file generated by FoxPro, E-Book and Flash is not standard PE type. The advantage of UniKey Enveloper: Automatic Protection No Coding Work Needed Different Protection Sachems All the Content of Enveloped Application is encrypted Additional data file protection/encryption To protect PE file, you need to launch UniKey Enveloper and you will see UniKey Enveloper works You can implement more advanced functions in “UniKey Setting” tab. The meaning of specific items are:         PW1, PW2, PW3 and PW4” are the password to the UniKey dongle. Background Check”, check the UniKey attachment periodically. This means not only check the UniKey when the enveloped application starts, but also during the whole process of enveloped application running. The unit of interval is minute. Bind HID”, to enable this function so that the enveloped application is bind with the hardware of UniKey. This means the enveloped application can only work with one UniKey dongle, since the HID of a UniKey dongle is globally unique. Bind SoftID”, the enveloped application with a batch of UniKey. SoftID is in the 22 / 38 specific range. For example, you can bind the enveloped with a batch of UniKey dongle that the SoftID is from 100 to 200. Bind Module”, bind the enveloped application with a certain license module. This means if and only the license module is valid (not zero). Taking advantage of this function, you can use UniKey dongle to control execution of enveloped application without change source codes. Execution Count”, to set a limitation of execution counts. For example, you can set the enveloped application can only run 5 times. You need also specific the license module for this function. The function is for trail or demo software. Expiration Date”, the enveloped application can only run before this date. Since existence of time zone, such function has 24 hours error tolerance. Network” helps you to generate Network configuration file to protect application on the network. UniKey Enveloper support roaming license, and it is self adaptive. You can protect application either by local UniKey or a remote UniKey in a network. Check “Enable Network Function” to let UniKey Enveloper help you to make a network configuration file. For the detailed usage of UniKey network function, please refer to Chapter 8. For the meaning of each setting, please refer to Section 7.6. You can save all these settings in a .INI file,and load it for later usage. Enable “Create ini” will save all these settings into UniKeyEnveloper.ini. 11.4 Codemeter Unlike the other keys, Codemeter is designed to be used by several companies simultaneously. These companies can then each store licenses for several roducts. And each product license can use 32 features for extra licenses. However these features are just the bits in an integer and can therefore only be enabled or disabled, not time-limited or counter-based. So if module licenses are to be used one might want to use product licenses for the modules. The Codemeter API is the largest one of the four when it comes to number of classes. It was also the API which gave us the most trouble when creating the adapter classes. The main reason was the large amount of code required to write to the key’s memory. According to the manual [41], changes to the key’s memory are usually done by the CM-Talk protocols that are used for remote updating. There are two exceptions and we used one of them, to write to ProductItemOptionUserData. To our help we had an example generated in the program Codemeter API Guide. It was written to cover all possible cases and the function for writing contained 230 rows (including comments and empty rows). The classes used were only documented for C++, which made it harder to understand the code. Eventually we managed to extract the code we needed. It was 40 rows of code, not including comments and empty rows. We think that it is too much since the other APIs do the same thing in about 10 rows. Codemeter 23 / 38         supports both AES and ECIES (asymmetric) encryption. Unfortunately it has the same weakness as Sentinel in that it only can encrypt 16 bytes at a time. However, the API also offers, so called, indirect encryption where the key is used to encrypt some data that is then used to initialize the software encryption. The idea is to speed up the encryption by doing it in the memory. There are several algorithms available for the indirect encryption, for example AES (with CBC and CFB) and stream cipher. We think that the API was hard to use. The biggest reason was all the data structures that needed to be initialized and then sent as parameters to functions. The only complete documentation was written for C++. 12 Results of the test In this chapter we go through the results of our test. 12.1 Modifying the program file 12.1.1 Analysis of the program file Only the test program protected with Codemeter could be decompiled with Reflector. To get more programs to test we protected a test program with Hasp Envelope but only using Class protection. By excluding the loader-part called Win32 protection we were able to decompile the program. An unprotected test program was also included in the test to demonstrate the need of loaders and obfuscators. To find the place in the code where MessageBox was called we used the .NET debugger CorDbg. We put a breakpoint on System.Windows.Form.Messagebox::Show, which made the execution halt when the message was about to be shown. The call stack revealed in which function the call took place. The code we got by decompiling the unprotected program was nearly identical to the original code and the function was easily found. Codemeter’s test program was obfuscated and none of the original classes could be found in the decompiled code. Instead Codemeter’s AxProtector had generated new classes with names consisting of two letters. It was the same thing for Hasp’s Class protection but there the names consisted of several digits. For both the protected program CorDbg still claimed that the call to MessageBox took place in a function with the same name as in the original code. However, no such function could be found. At the bottom of the call stack there were function names that actually existed in the decompiled code. But between them and the function calling MessageBox there were several calls to functions in the System.Reflection namespace. Reflection can be used to generate new classes during runtime. We think that both AxProtector and Class protection use reflection in combination with the hardware key to create and use the classes of the original program during runtime. 12.1.2 Roundtripping The programs were disassembled with ILDASM. In the analysis we had located the 24 / 38 function calling MessageBox for the unprotected program. It was therefore easily found in the IL code. Notepad was used to remove the lines related to the call. Then the program was assembled with ILASM. The new program worked as the old one but no message was displayed. We also choose to test the protected programs even though we were unable to locate the call in them. No changes were made to the code. Instead we hoped to see whether the programs were protected against roundtripping. After the reassembling, Codemeter’s test program refused to start. Both Hasp and UniKey’s test program worked fine. 12.1.3 Conclusions One conclusion from the test was that unprotected programs are easily modified. The code that the decompiler generated was almost identical to the original code. The largest difference was that Reflector had to chose new names for the local variables. We could avoid searching through the whole code by using the debugger CorDbg to find the place we were looking for. In this case knowing which function we should put a breakpoint on helped us. Otherwise one has to guess the function or use CorDbg’s step-by-step execution. We used ILDASM and ILASM to perform the roundtrip because it involved less steps than, for example, using Reflector and the C# compiler. The code did not need to be transformed into C# code and the whole program was stored in one file. However, we had to do the changes in IL code instead of C# code which was a little bit trickier. We failed to modify the protected programs because we could not find the places to modify. Both programs were heavily obfuscated and no original classes could be found. Reflector had problems with many functions that could only be viewed in IL-format. Codemeter’s test program was protected against roundtripping while Hasp’s test program did not show any signs of that kind of protection. We believe that both protections make modification both hard and time consuming. Unfortunately we could not test Sentinel’s test programs thoroughly in this test because they could not be protected without the loader included. 12.2 API-hooking We started this test by trying to fool an unprotected program that used Hasp’s key. A new DLL was created which imitated Hasp’s API DLL hasp net windows.dll. But our DLL did not communicate with the key. Hasp’s DLL used strong naming which stopped the test program from accepting our DLL. But with the help of ILDASM/ILASM we could remove the row in the program file that contained the DLL’s public key token. After that the program accepted our DLL and could be used without a key. We then used the same technique on a test program protected with Hasp’s Class protection. The program did not work with our DLL. We do not know the exact reason why because Class protection itself uses another DLL. A possible explanation might be that Class protection discovers if the API is used when the Hasp Envelope is applied to the program file and then adds code that checks if the correct DLL is used. 25 / 38 With the UniKey Envelope, we can enhance overall security by adding multiple layers to thwart hacking attempts, preventing memory dumping and protecting against debuggers. The UniKey envelope enables you to embed licensing and protect your application in minutes, even if don't have access to source code. The UniKey envelope offers a way to quickly add protection and obfuscation to an application without requiring any alteration to the source code. Sentinel used DLLImport to link their API DLLs. To see if this made any difference compared to Hasp we created a DLL for UniKey’s API. We found out that the DLL did not use strong naming. In fact, the DLL could be used without us modifying the program. There wasn’t enough time to create a DLL for the Codemeter API. However, when looking at the program file we believe that an unprotected program using a Codemeter key could be tricked to use another DLL in the same way as the unprotected program that used Hasp. Codemeter’s AxProtector can, however, link the API statically when the program is protected. When this was done, the program did not need a separate DLL for the API. We assume that AxProtector included the code in the protected program file, which makes it impossible to replace the API with the technique used in this test. 12.2.1 Conclusions From the results of this test we draw the following conclusions: Our successful attempt at replacing the API DLLs for Sentinel means that we can monitor the API calls in the program. In order to return the correct answers we could let our DLL pass the call on to the real DLL and therefore to the key. Sentinel Shell still stop us from using the program without key but with control over the API we can fool the program what we have licenses that we haven’t bought. This is a serious weakness for the two keys. Hasp’s Class protection seems to control that the real DLL is used. By protecting the program with Win32 protection also, one cannot disable strong naming the way we did. However, since the purpose of strong naming is to prove the origin of a DLL, one should not trust it to seriously prevent API hooking. Codemeter offered the possibility to link the API statically, which in our opinion should be the safest protection against API-hooking through DLL replacement. 12.3 .NET debugger In our first test we tried to locate the call to MessageBox. We noticed that CorDbg could debug even programs protected with loaders. A new test was constructed because of this fact. By setting a breakpoint on functions in the keys’ APIs we hoped to retrieve the user-codes for the keys. The user-code is the one that is used to gain read and write access to the key. 12.3.1 Conclusions We managed to retrieve the user-code for both Hasp’s and UniKey’s by putting breakpoints on their login functions. Codemeter only has two places where the API can write to and neither required a user-code. But since we could 26 / 38 put a breakpoint on API functions in Codemeter’s test program, we would have retrieved the user-code if such had existed. The only one we could not put breakpoints in was UniKey’s test program. UniKey protected the program in a way that made it require .NET 2.0 to run. Because of this CorDbg 1.1 was unable to debug the program. We then compiled the program in .NET 2.0, but the CorDbg that was included in the .NET 2.0 SDK did not work properly. For some reason it started executing the program it was to debug without halting after loading the program as CorDbg 1.1 did. Because of this we were unable to place any breakpoints. Not even when the breakpoints were given as parameters to the program were they added in time. Instead they were added after the execution of the program had ended. We have no idea why it behaved like that. No similar case was found when we searched on Google. However, UniKey ’s user-code was already retrieved in the API-hooking test. 12.4 Remote updating In this test we updated each key using remote updating. Because UniKey Time directly supports more than one license, we just changed the values of the integers stored in the key. UniKey Updater generates an executable that the customer should execute in order to update the key. Hasp, Sentinel, UniKey and Codemeter all required that the customer first generated a file containing information of the key’s current state. This file is then sent to the software company and used by the update program as the base for the update. For UniKey, the creation of an update was very similar to the initialization of the key. We found it easy to add and remove licenses. Sentinel’s updates could only change the state of already existing licenses, not add new licenses. This means that a key must be shipped with all the licenses that the customer might buy later on. They can then be activated by remote updating. Codemeter’s updates could only be created through a console-based program. We think that the lack of a GUI made things more complicated. The reason why a graphical program was missing was probably that the key is intended to be updated mostly through CM Talk. The update is then sent to the customer through, for example, e-mail. Codemeter’s update was an executable while Sentinel’s needed a separate program to apply the update to the key. Hasp offered both alternatives. A table that shows a comparison of the hardware keys can be found at the end of the report. 13 Selecting a hardware key 13.1 UniKey By tricking the test program protected by UniKey into using API DLL, we were able to control what the functions returned to the program. This means that we can make the program believe we have bought all module licenses even when that is 27 / 38 not the case. We can also retrieve the user-code, as it must be passed each time the program reads from or writes to the key. With the user code, even the main license can be changed. For example a demo license that restricts the number of executions can be extended when needed. Therefore we can only recommend the key for programs that has a single unlimited license. By protecting the program with UniKey Envelope it will depend on the key in order to run. We only removed the need for the API DLL not the DLL used by UniKey Envelope. Some advantages with UniKey were: The standard key could be used for network licenses. Driverless , No driver needed. Life time product warranty 13.2 Sentinel The program protected by Sentinel could also be tricked into using an API DLL created by us. We were then able to control which information the program got from what it believed was the real key. Because of this, programs with module licenses should not be protected by Sentinel Hardware Keys. The real licenses can’t be changed through the API, which means the license used by Sentinel Shell will still restrict the usage. In Sentinel’s case, this license can be time-limited or counter-based because we have not been able to change the real licenses. Some advantages with Sentinel were: Both shell and API protection. Big size company 13.3 Codemeter Something that could also be classified as an advantage was that Codemeter didn’t require any special drivers in order to work. But instead it requires that a server program is running when the key is to be used by a program. The server program is started automatically when a program that uses the key is executed. Some advantages with Codemeter were: • The license program could be used as an order database. • AxProtector could statically link the API to the program. • The standard key could be used for network licenses. Both Hasp and UniKey have some advantages over Codemeter: • Hasp Envelope contained loader functionality, which prevents decompilation. • A hardware clock in Hasp HL Time and UniKey Time makes it hard to fool time-based licenses. • Remote updates were created in a way very similar to the initialization. Codemeter only offered a console-based program. In the end we picked Hasp and UniKey. One of the main reasons, aside from the advantages given above, was that it was easier to work with, both the API and the programs in the SDK. Another reason was that UniKey Time supports Network funcation while Hasp HL Time does not. The optimal solution would have been to assemble a solution by picking the best parts from each key. Since the user codes could be retrieved with the help of 28 / 38 CorDbg, we think that the other manufacturers should learn from Sentinel and offer fields that can only be written to once. Such fields are suited for storing hardware fingerprints and more. Sentinel Shell was able to protect .NET assemblies in DLL-form. The other keys should support this since it prevents reverse engineering. The possibility to statically link the API should be something that all keys offered. However, at the time of the test only Codemeter did. 14 Additional works The hardware key in itself fulfills several of MMS requirements: • The key stops the use of illegal copies since the key is required in order to run the program. • The key supports module licenses. These are bound to the key, which means they are bound to one main license. So if the customer has two keys and buys a module license, an update is sent that can only update one of the keys. • The key supports time-limited licenses (HL Time and UniKey Time) and UniKey time supports network licenses while only HASP HL Net supports this. • Even binding a license to a specific program version can be accomplished without adding extra code to the program. Hasp ships the keys in, so called, batches. The keys in a batch use the same encryption key. A program protected by Hasp or UniKey Envelope only works with a certain batch since the hardware decryption and encryption is used in the Envelope. By switching batch for each program generation, old keys will not be able to start a newer program. A downside is that if the customer wants to upgrade to the new program the key will have to be replaced instead of just updated. 14.1 Binding a key to a specific computer A requirement that was not fulfilled by the key alone was that a license should be bound to one computer. All the keys we tested were designed so that the program could be installed and used on several computers but only when the key is present. To create a bond between the key and the computer, two things are needed: A good way to identify the computer and a secure place in the key where the information is stored. We also want to bind the computer to the key so that the customer will not bind several keys to one computer by mistake. This second bond doesn’t need to be secure since there is nothing to gain by removing it. We explored two ways of identifying a computer. The first one was to find unique identifiers in the computer, preferably the hardware components. Microsoft uses this method for, among other programs, Windows XP. To increase the security, several identifiers are used [13]. Some examples are the volume’s serial number, hashes of BIOS, the product ID and language settings used by the operating system. However, if the hardware is changed too much, the protection might mistake the computer for a new computer and refuse to run the program or, in the case of Windows XP, the operating system. We had trouble finding suitable identifiers in the hardware. Many hardware components lacked unique serial numbers while others where easy to change, for example MAC addresses [38]. The second way to identify a computer was to add something unique to it that can 29 / 38 be used for identification. The problem is that it must be protected from modification. We could not find such a storage place on the computer. We were also forced to take the test results into consideration. They showed that the memory of the key was not a secure place to store data in. In the end we decided to use a combination of the two ways of identifying a computer. Data, which is encrypted with a key partly based on a hardware fingerprint from the computer, is stored in the key. At the same time data, encrypted with a key, partly based on the hardware key’s unique ID, is stored on the computer. The data in the key is related to the data on the computer. By comparing them after decryption, one can determine if the key is bound to the computer or not. The strength of this solution depends on the uniqueness of the hardware fingerprint. To minimize the gain from decrypting the hardware fingerprint we change the data at each execution. So if the key is tricked into running the program on another computer it will no longer be synchronized with the first computer. Someone who wants to use the key on two or more computers must synchronize the key for each move, which can be very inconvenient. 14.2 Code generator We wrote a code generator that generated pieces of code that used the key’s API. The purpose of the code-generator was to increase the number of calls to the Hasp HL API in the program, especially calls to the encrypt and decrypt functions. These require that the correct encryption key is used, which means the attacker has three choices if the program is to run without key. Remove the code parts that use the API, figure out the correct encryption key or record the answers from the real key. The first alternative requires the removal of Hasp Envelope. Because the key never leaves the hardware key the second alternative involves study of how known plaintexts are encrypted. We believe the last alternative requires the least work than the first two. The first defense is to protect the communication against eavesdropping and hijacking. A second defense can be to let the program encrypt and decrypt randomized data or data that is changed each execution. The program that records the communication will then find new answers the whole time, which will make it very difficult to know if all the critical answers have been saved. 14.3 Automate the Envelope We found it easy to add Envelope (both HASP and UniKey Envelope) to the build process of the program. The configuration of Envelope could be done through Envelope’s GUI and saved to a project file. This file could then be passed as a parameter on the command-line to Envelope. We then added a call to Envelope as a Post-build step. The only problem was that Visual Studio did not place the protected file into the setup project but instead choose the unprotected one. We were forced to add the protected file manually and create a filter that prevented the unprotected 30 / 38 one from being included. 14.4 Problems We encountered two larger problems while working on the solution. 14.4.1 Class protection When we protected MMS program, BMill , with Hasp Envelope we encountered problems as soon as Class protection was used. The error message that appeared when the program was executed informed us that a field was missing and also mentioned PrivateImplementationDetails. When we decompiled the program we saw that outside the namespace of the program there was a group with the name . It contained some data structures. With the help of Reflector’s analyzing tool we could identify the classes using these structures. The only thing the classes had in common was that both initialized arrays with the help of blocks. Our conclusion was that the .NET compiler puts the initialization block in PrivateImplementationDetails instead of the class itself. This was confirmed when we decompiled other programs using block initialization. When protecting a program with Class protection one gets to choose which classes that should be protected. For the programs using block initialization there is an additional class called PrivateImplementationDetails that one can select. We managed to reconstruct the error in a smaller test program and after trying all combinations of classes protected we came to the following conclusion: As soon as one class was protected, PrivateImplementationDetails was also protected even if it was not selected for protection. When it was protected all classes that used block initialization needed to be protected in order to work. The problem with MMSprogram was that it contained a class that for unknown reasons did not function if it was protected. It used block initialization, which required the class to be protected as soon as another class was protected with Class protection. Our solution was to initialize the array by assigning its elements values, one at a time. In this way, block initialization was not used and the class could be left unprotected when all the other were protected. This solved the problem and the program worked after being protected with both Win32 protection and Class protection. 14.4.2 Representation of encrypted data in textform Even if block initialization worked with Class protection in most cases, we didn’t want our generated code pieces to introduce this problem to more places in the code. We found that text strings did not end up in PrivateImplementationDetails and decided to store our byte data in text strings in the code. This, however, led to a problem we had earlier encountered when working with the test programs. If encrypted data is translated into ASCII-values there is a chance that some of these will be control characters like NULL or backspace. They have no visual representation and can disappear or otherwise affect the other characters when it passes through something that interprets them, for example a word editor. 31 / 38 To avoid losing data when it was copied from our code-generator to the program we used a technique we learned in Object-oriented programming II given at Skeria by Robert Brnnstr¨om. Each byte was divided in half. Then each part became the four least significant bits in a new byte. In this way there will only be 16 possible bit-combinations. By adding an offset to each byte we can make sure that none of the possible ASCII-characters is a control-character. For example, if offset 65 is selected then all the characters will be letters. The downside of this technique is that the data will become twice as large. 15 Evaluations Our solution meets the standard requirements issued by MMS. Both HASP and UniKey hardware keys, in combination with its Envelope, protect against illegal use of the program both inside and outside the customer’s company. The hardware key must be present when the program is used, which stops two copies from being used at the same time if only one key is available. The key has a built-in support for license management. Since the licenses are stored in the key they are automatically bound to it. We added extra code to the program that creates a bond between the key and one specific computer. In this way the licenses are bound to one computer. Both Hasp and UniKey are compatible with .NET 1.1. Keys for earlier program generations cannot unlock newer generations if they belong to different batches. An old key will not be able to even start the program because of Envelope. We considered a solution where the maximum allowed version number for the key was stored in its memory. But when our test showed that the memory was not a safe place we had to fall back to using batches. By using the real time model that contains a hardware clock one can have time-limited licenses without any changes to the code. Network licenses require some modifications to the binding code so that the clients will not overwrite each other’s data in the network key. The strength of the solution is based almost entirely on Envelope’s ability to bind the program to the key. Our tests showed that the API in itself was pretty easy to bypass. The API should therefore not be presented as a standalone protection. Its purpose is to provide methods for module license checks, hardware encryption and storage of data in the key. However, the memory proved to be an unsafe storage place because of our success in retrieving the vendor code. The bond between the program and the key can be cut at three locations: The program, the communication or the key. We believe that the most common way is to try to emulate the key in software. One way of doing this is to record the traffic between the key and the program so that the emulator then can pretend to be the key by returning the correct answers, so called replaying. An alternative is to retrieve the content of the key, including the symmetric encryption key, in order to completely emulate the key’s functionality. 32 / 38 To make emulation and replaying harder, Hasp uses “randomized scrambling” in the communication between the key and the Envelope, UniKey uses “anti crack Library”. We are not entirely sure of what it does but we assume that it corrupts the data in a way that the key and program have agreed upon. Unfortunately there was not enough time to do a thorough examination of the communication between the keys and their test programs. Our solution has one known weakness, the identification of computers. Picking as many identifiers as possible would have greatly increased the risk of stopping legitimate users from using their program if they make a change to their computers. For example, if a customer replaces his/her graphics card then the program would stop functioning if we had tied the hardware key to a specific graphics card serial number. This is a problem for several software companies. A solution might be TPM (Trusted Platform Module). It is a chip that is usually placed on the motherboard and is intended to be used as storing place for encryption keys and other data used to identify the computer. Behind TPM stands TCG (Trusted Computing Group), which includes Microsoft and several hardware companies. 16 Discussion 16.1 Future work There was not enough time to cover all the areas in the test. We focused on the techniques used to protect the program file and the APIs of the keys. Future work could consist of more thorough examination of the loaders, analyzing the traffic between the keys and the program or hardware analyzes of the keys. Since hardware keys introduce an extra cost for each copy of the program they are not suited for cheaper software. This makes solutions like client-server designs very interesting research areas. 16.2 The subject We found almost no books about the subject. Nearly all the theoretic literature was found on ACM (Association for Computing Machinery). It consisted mostly of surveys or proposed techniques targeting specific problems such as how to protect a program against tampering. Unfortunately the open research hasn’t gotten very far. We think that it suffers greatly from the secrecy surrounding the commercial solutions that exist. However, the subject is such that each solution, that is not completely secure, is weakened if it becomes known. And it is uncertain whether there actually exists a solution that is completely secure considering how exposed a program is on a hostile computer. One area that we think is overlooked is the implementation part. Even theoretically secure solutions, if such exist, can get flaws because of the way they are implemented or because of certain characteristics of the operating system the program will run on. Right now most research is highly abstract and does not take these things into consideration. We believe that research in this area would help programmers avoid the common pitfalls that exist and therefore make the programs more secure. 33 / 38 16.3 The future We believe that the next step in software protection will be to create a way for programs to identify a specific computer. NGSCB (The Next-Generation Secure Computing Base) tries to achieve this by offering several security features using the upcoming TMP 1.2. From a software protection view the two most interesting ones are strong process isolation and sealed storage. With the permission of the user, an application can run isolated in the memory which assures that it is not modified or observed by other programs or the operating system. This would protect the program against debuggers and other monitoring tools. We guess that programs could refuse to run if they detect that they are not in isolated mode. The other important feature is the sealed storage. According to the FAQ [45] we read, a program can store data on the chip and then restrict which programs that will be able to access the data. The user will have control over which programs that may access the chip. However, in order to protect the data the user probably won’t be allowed to modify the data, unless allowed by the program that created it. This is not confirmed in the FAQ but neither denied and it is required to make the storage place useful and safe. If NGSCB really works this way, then the protection will use the same concept as in the Malicious clients scenario. Security is achieved by introducing a chip that the user does not have full control over (and with full control we mean unrestricted modification privileges). From one point of view, that can be seen as restricting what the user can do with the computer. 34 / 38 References [1] C. Collberg, C. Thomborson, “Watermarking, Tamper-Proofing, and Obfuscation - Tools for Software Protection”, IEEE Transactions on Software Engineering Vol 28, NO. 8, (2002), URL: http://www.cs.auckland.ac.nz/ ~cthombor/Pubs/01027797a.pdf (accessed 2007-05-27). [2] G. Naumovich, N. Memon, “Preventing Piracy, Reverse Engineering, and Tampering”, Computer, Vol 36, no. 7, p 64-71, (2003, jul.). [3] Dotfuscator homepage, URL: http://www.preemptive.com/products/ dotfuscator/index.html (accessed 2007-05-27). [4] A. Main, P. C. van Oorschot, “Software Protection and Application Security: Understanding the Battleground”, (2003), URL: http://www.scs. carleton.ca/~paulv/papers/softprot8a.pdf (accessed 2007-05-27). [5] CrackZ, “Newbies First Steps - Tutorial”, (uppdaterad 2000), URL: http: //www.woodmann.com/crackz/Tutorials/Newbies.htm (accessed 2007-07-30). [6] CrackZ, “Reverse Engineering - Getting Started Guide”, (uppdaterad 2006), URL: http://www.woodmann.com/crackz/Getstart.htm (accessed 2007-05-27). [7] E. Schanzer, “Performance Considerations for Run-Time Technologies in the .NET Framework”, (2001 aug.), URL: http://msdn2.microsoft.com/ en-us/library/ms973838.aspx (accessed 2007-07-30). [8] M. Zunke, “Addressing New Challenges in Software Protection for .NET”, (2005), URL: http://www.aladdin.com/HASP/brochures.asp (requires registration, accessed 2007-05-27). [9] Intelligent Disassembler Pro, URL: http://www.datarescue.com/idabase/ (accessed 2007-05-27). [10] ILDASM, v 1.1.4322.573, URL: http://msdn2.microsoft.com/en-us/ library/f7dy01k1(vs.71).aspx (accessed 2007-05-27). [11] L. Roeder’s Reflector, v 5.0.32.0, URL: http://www.aisto.com/roeder/ dotnet/ (accessed 2007-07-30). [12] Process Monitor, v 1.2, URL: http://www.microsoft.com/technet/ sysinternals/utilities/processmonitor.mspx (accessed 2007-07-30). [13] Windows Genuine Advantage, “Genuine Microsoft Software”, URL: http: //www.microsoft.com/genuine/Facts.aspx?displaylang=en (accessed 200705-27). [14] B. Anckaert, B.D. Sutter, K.D. Bosschere, “Software Piracy Prevention through Diversity”, Proceedings of the 4th ACM workshop on Digital rights management DRM ’04 , (2004), URL: http://portal.acm.org/citation. cfm?id=1029157&coll=ACM&dl=ACM&CFID=23729305&CFTOKEN=62981456 (requires login, accessed 2007-05-27). 44 [15] Message Digest 5, URL: http://tools.ietf.org/html/rfc1321 (accessed 2007-07-30). [16] Security Hash Algorithm 1, URL: http://tools.ietf.org/html/rfc3174 (accessed 2007-07-30). [17] H. Chang, M.J. Atallah, “Protection Software Codes By Guards”, CERIAS 35 / 38 Tech Report 2001-49, (2001), URL: https://www.cerias.purdue.edu/ tools_and_resources/bibtex_archive/archive/2001-49.pdf (accessed 200705-27). [18] Hasp Envelope, URL: ftp://ftp.aladdin.com/pub/hasp/hl/windows/ installed/Docs/Additional_Docs/HASP_HL_Envelope_Tech_For_Developers. zip (accessed 2007-05-27). [19] Sentinel Keys Developer’s Guide, version 1.0, p 57-70. [20] F. Cohen, “2.1 - A Short History of Cryptography”, (1990), URL: http: //all.net/books/ip/Chap2-1.html (accessed 2007-07-30). [21] Advanced Encryption Standard, URL: http://www.csrc.nist.gov/ publications/fips/fips197/fips-197.pdf (accessed 2007-05-27). [22] Data Encryption Standard, URL: http://csrc.nist.gov/publications/ fips/fips46-3/fips46-3.pdf (accessed 2007-05-27). [23] M. Downen, “CLR Inside Out - Using Strong Name Signatures”, MSDN Magazine Jul 06, (2006), URL: http://msdn.microsoft.com/msdnmag/ issues/06/07/CLRInsideOut/ (accessed 2007-05-27). [24] P. C. van Oorschot, “Revisiting Software Protection”, (2003), URL: http: //www.scs.carleton.ca/~paulv/papers/isc5.pdf (accessed 2007-05-27). [25] Codemeter - Developer’s Guide v 3.00, (2006 Oct.), p 14. [26] BSA, “Fourth Annual BSA and IDC Global Software Piracy Study”, (2007), URL: http://www.bsa.org/globalstudy/ (accessed 2007-05-27). [27] Reverse engineering, URL: http://searchsmb.techtarget.com/ sDefinition/0,,sid44_gci507015,00.html (accessed 2007-05-27). [28] Kingpin, “Attacks on and Countermeasures for USB Hardware Token Devices”, Proceedings of the Fifth Nordic Workshop on Secure IT Systems Encouraging Co-operation, Reykjavik, Iceland, October 12-13, 2000, p 35-57, ISBN 99799483-0-2. URL: http://www.grandideastudio.com/files/ security/tokens/usb_hardware_token.pdf (accessed 2007-05-27). [29] Aladdin Knowledge Systems, URL: http://www.aladdin.com/about/ default.asp?lid=About&lpos=about_menu (accessed 2007-05-27). [30] Safenet Inc., URL: http://www.safenet-inc.com/company/history.asp (accessed 2007-05-27). [31] WIBU Systems, URL: http://wibu.com/history.php?lang=en (accessed 2007-05-27). 45 [32] Codemeter - Developer’s Guide v 3.00, (2006 Oct.), p 11-14. [33] UniKey, URL: http://www.esecutech.com (accessed 2007-05-27). [34] E. Gamma, R. Helm, R. Johnson, J. Vlissides, “Design Patterns”, p 139150, (1994), ISBN: 0-201-63361-2. [35] Kordab, URL: http://www.ekordab.se/ (accessed 2007-05-27). [36] Sentinel Keys Developer’s Guide, version 1.0, p 52. [37] CD Media World, “CD/DVD Protections”, URL: http://www. cdmediaworld.com/hardware/cdrom/cd_protections.shtml (accessed 200705-27). [38] SMAC, URL: http://www.klcconsulting.net/change_mac_w2k.htm (accessed 2007-05-27). [39] Elliptic Curve Cryptography Standards, URL: http://www.secg.org/ download/aid-385/sec1_final.pdf (accessed 2007-05-27). [40] Tinyness: An Overview of TEA and Related Ciphers, URL: http:// 36 / 38 www-users.cs.york.ac.uk/~matthew/TEA/TEA.html (accessed 2007-07-30). [41] Codemeter - Developer’s Guide v 3.00, (2006 Oct.), p 136. [42] M. Dworkin, “Recommendation for Block Cipher Modes of Operation”, NIST Special Publication 800-38A 2001 Edition, (2001), URL: http: //csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf (accessed 2007-05-27). [43] OllyDbg Helpfile, “How to start debugging session”, Included in http:// www.ollydbg.de/odbg110.zip (verified 2007-05-27). [44] OllyDbg, URL: http://www.ollydbg.de/ (accessed 2007-05-27). [45] Microsoft Next-Generation Secure Computing Base - Technical FAQ, URL: http://www.microsoft.com/technet/archive/security/news/ngscb. mspx?pf=true (accessed 2007-08-06). 37 / 38 Hardware Key Comparison Table Hardware keys Licenses Real Time Counter-based Network license Algorithms Symmetric Encryption Asymmetric Encryption Checksum API C# Samples C# documentation Full documentation Functions Remote updating Hardware clock Specification Memory Driverless Warranty Price/Unit Hasp HL YES YES NO UniKey Time YES YES YES Sentinel HK Codemeter NO YES YES NO YES YES YES NO NO YES NO YES YES NO NO YES YES.ECC YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES NO YES NO 4K NO ONE Year USD 49 4K YES Life Time USD 45 8K NO ONE Year USD 46 512M(Flash) YES ONE Year USD 60(with Flash) 38 / 38

Related docs
Hardware based Software protection
Views: 14  |  Downloads: 0
Hardware
Views: 13  |  Downloads: 1
QuickPanel Hardware
Views: 546  |  Downloads: 24
Hardware
Views: 8  |  Downloads: 4
On Hardware Based Software License Key
Views: 10  |  Downloads: 0
Hardware
Views: 3  |  Downloads: 0
On Software Protection Dongle
Views: 23  |  Downloads: 2
Copy Protection, Trusted Hardware, and More
Views: 0  |  Downloads: 0
Available Hardware
Views: 2  |  Downloads: 0
Hardware-&-Software-Needs-AsseSsment
Views: 2  |  Downloads: 0
XT1502 Hardware Guide
Views: 4  |  Downloads: 0