Download as TXT, PDF, TXT or read online from Scribd
Download as txt, pdf, or txt
You are on page 1of 8
The Kelvinator - AutoLisp encryption utility.
Release 2a: The Kelvinator Strikes Back
by Kelvin R. Throop September 2nd, 1987 (C) Copyright 1986,1987 Autodesk, Inc. License is granted for the use of this software and documentation on a no charge, sharing basis. You may distribute and copy this software and documentation freely as long as it remains a complete unaltered package and is not sold for profit. ------------------------ Following the release of AutoCAD version 2.1, independent developers began to create complex applications employing the AutoCAD menu macro language and the Variables and Expressions feature as an embedded programming language. With the release of version 2.18, which introduced the AutoLisp programming language, AutoCAD became a fully programmable and extensible system. From inception, AutoCAD's open architecture has been intended to encourage outside developers and individual users to customize AutoCAD and implement applications for diverse markets. Since menu macros and AutoLisp are interpreted languages, applications must be shipped in source code form, and Autodesk recognized the need to protect the developers of these applications from theft of their proprietary products. Encryption of menu macros and AutoLisp programs was implemented and made available to authorized developers. This encryption never purported to be particularly secure, but it does prevent casual examination of distributed code. Given that a standard AutoCAD must be able to decode a file encrypted by any developer, there is no cryptological technique of which I am aware which would be significantly more secure than the one used. The fact that the encryption program is made available to hundreds of developers who cannot always prevent its further distribution makes penetration by reverse engineering of the program or a known-plaintext attack inevitable should somebody be so callous as to steal the work of our developers and undermine the viability of their businesses. A SECOND LAYER OF PROTECTION Since encrypting files cannot provide total security, a second level of defence was called for. The Kelvinator is a program which translates an AutoLisp program into a form which is essentially gibberish when examined by a human but which should execute identically to the original program. Thus, if the distributed program is decrypted, the resulting source code will be little use to the looter. Kelvination of a program consists of: 1) Deleting comments. 2) Translating variable names into gibberish. 3) Removing indentation and line breaks. As an example of the consequences of Kelvination, the following AutoLisp program was processed. ; ; Display spiral ; ; Designed and implemented by ; Kelvin R. Throop in January 1985 ; ; (cspiral <# rotations> <base point> ; <growth per rotation> ; <points per circle>) ; (defun cspiral (ntimes bpoint cfac lppass / ang dist tp ainc dinc circle bs cs) (setq cs (getvar "cmdecho")) (setq bs (getvar "blipmode")) (setvar "blipmode" 0) (setvar "cmdecho" 0) (setq circle (* 3.141596235 2)) (setq ainc (/ circle lppass)) (setq dinc (/ cfac lppass)) (setq ang 0.0) (setq dist 0.0) (command "pline" bpoint) (repeat ntimes (repeat lppass (setq tp (polar bpoint (setq ang (+ ang ainc)) (setq dist (+ dist dinc)))) (command tp) ) ) (command) (setvar "blipmode" bs) (setvar "cmdecho" cs) nil ) ; ; Interactive spiral generation ; (defun C:SPIRAL ( / nt bp cf lp) (prompt "\nCentre point: ") (setq bp (getpoint)) (prompt "\nNumber of rotations: ") (setq nt (getint)) (prompt "\nGrowth per rotation: ") (setq cf (getdist bp)) (prompt "\nPoints per rotation: ") (setq lp (getint)) (cond ((null lp) (setq lp 30))) (cspiral nt bp cf lp) ) The output of the Kelvinator is as follows (line breaks have been manually inserted: there were none in the actual output file). (DEFUN Qj(Q@ QQ Ql Q& / Q1 Q# Q0 Q$ QO Q| Q% Q?j)(SETQ Q?j(GETVAR"cmdecho"))(SETQ Q%(GETVAR"blipmode")) (SETVAR"blipmode"0)(SETVAR"cmdecho"0)(SETQ Q|(* 3.141596235 2))(SETQ Q$(/ Q| Q&))(SETQ QO(/ Ql Q&))(SETQ Q1 0.0)(SETQ Q# 0.0)(COMMAND"pline"QQ)(REPEAT Q@(REPEAT Q&(SETQ Q0(POLAR QQ(SETQ Q1(+ Q1 Q$))(SETQ Q#(+ Q# QO))))(COMMAND Q0)))(COMMAND)(SETVAR"blipmode"Q%) (SETVAR"cmdecho"Q?j)NIL)(DEFUN C:SPIRAL(/ Qjj Q@j QQj Qlj)(PROMPT"\nCentre point: ")(SETQ Q@j(GETPOINT))(PROMPT "\nNumber of rotations: " )(SETQ Qjj(GETINT))(PROMPT"\nGrowth per rotation: ")(SETQ QQj(GETDIST Q@j))(PROMPT"\nPoints per rotation: ") (SETQ Qlj(GETINT))(COND((NULL Qlj)(SETQ Qlj 30)))(Qj Qjj Q@j QQj Qlj)) If you imagine several thousand lines of this in a real application instead of the few lines generated by this simple AutoLisp program (which, by the way, was the first AutoLisp program ever written), it should be clear that not much can be gleaned from decrypting such ``source code''. Kelvinating a File To Kelvinate a file, use the command: KELV file [options] Input is read from the specified file. If no file type is specified, .lsp is assumed. Output is written to standard output, and will usually be redirected to a file. Various options can be specified to control the operation of the Kelvinator; these are discussed below. For example, to Kelvinate the AutoLisp application brainsim.lsp and write the output into ubrains.lsp, use the command: KELV brainsim >ubrains.lsp Note that a while a file type of .lsp is assumed for the input file, an explicit file type must be supplied when the output of the Kelvinator is redirected. The Definition File When a program is Kelvinated, all of the user-defined symbols are translated to gibberish, but AutoLisp's built-in symbols (such as CONS, SETQ, and ENTGET) must not be modified. In addition the application may wish to leave some symbols unchanged (for example the C:name used to invoke user-defined commands, or functions called by the user directly from the keyboard). Finally, when a multiple-file program is Kelvinated, consistent translation must be applied across all files comprising the program. All of these requirements are implemented via the Kelvinator definition file. If you are simply using the Kelvinator to protect standard AutoLisp programs, you probably won't have any need to examine or modify the definition file. Feel free to skip this section until you need it. When the Kelvinator is called as in the example above, it searches the current directory for a file named. If you wish to use a different definition file, multiple definition files, or a different source for the definition file, you may use the -d switch on the KELV call line to supply a different file name. For example: KELV prog1 >kp1.lsp -dmydefs.def KELV prog2 >kp2.lsp -d/usr/appdev/KELV.def KELV prog3 >kp3.lsp -dKELV.def -dlocal.def In the first example a locally-created definition file is used instead of the standard KELV.def. In the second, the Kelvinator is told to obtain its definition file from the specified path rather than from the current directory. In the third example, two definition files are used: the standard definitions and a local version specifying additional symbols. Any number of definition files may be specified when the Kelvinator is called; they are loaded in the order named on the call line. If a symbol is declared more than once, whether within one definition file or across several, the last declaration takes precedence (this allows local definitions to override those given in the standard KELV.def). A Kelvinator definition file is composed of four types of declarations: Protected symbols, Pattern masks, Translation specifications, and a Symbol code. Each type of declaration is placed in a section of the file introduced by a section definition statement whose first character is a right parenthesis `` )''. Blank lines and comment lines which begin with two right parentheses are ignored. Let's look at a simple definition file: )) Sample Kelvinator definition file )Pattern C:? )Protect cons setq entget )Translate mysym z1 yoursym z2 )Protect car )Code 200 This file contains five sections: one )Pattern section, two )Protect sections, one )Translate section, and one )Code section. A file may contain as many sections as you like. Capital and lower case letters are considered identical; this is consistent with AutoLisp's symbol syntax. THE )PROTECT SECTION The )Protect section consists simply of a list of names, one per line. Any symbol named in a )Protect section will be left unchanged by the Kelvinator. In this case, the four standard AutoLisp symbols CONS, SETQ, ENTGET, and CAR will be left intact when a file is Kelvinated. The standard KELV.def lists all AutoLisp built-in names as protected symbols. If a new built-in name is added in a subsequent release of AutoLisp, simply adding it to the KELV.def file will cause it to be correctly processed by the Kelvinator. If your application provides functions the user invokes from the keyboard (or from a menu), you may request the Kelvinator to leave these names untranslated by adding them to the )Protect section. The best way to accomplish this is to create a second definition file for your application and specify both KELV.def and your file with -d specifications when invoking the Kelvinator. THE )PATTERN SECTION Sometimes an entire syntactic class of symbols should be left untranslated. An example of this are the names used to invoke user-defined commands in AutoLisp; all user-defined commands are functions whose names begin with ``C:''. Each line in the pattern section specifies a pattern against which symbols are tested. If a symbol matches the pattern up to the length of the pattern, with the ``?'' character in the pattern matching any non-null character in the symbol, that symbol is automatically protected (i.e., not translated by the Kelvinator). The standard KELV.def file contains the pattern declaration `` ?:'', which protects all symbols with a colon as their second character; this is compatible with the original Kelvinator in which this was hard-coded. THE )TRANSLATE SECTION When the Kelvinator encounters a symbol in a program which is neither protected by matching a pattern nor by having been named in a )Protect section, it searches for the symbol in the translation table. If the symbol is found, the value from the translation table replaces the original symbol. If the symbol is not in the translation table, the Kelvinator creates a gibberish symbol and makes an entry in the translation table so that all subsequent occurrences of the new symbol will be translated to it. The standard definition file, KELV.def, contains no )Translate section, so all nonprotected symbols are assigned new gibberish values. If you wish to cause a symbol to be translated to a specific value rather than have the Kelvinator make up a gibberish value for it, simply specify the original symbol and the value it should be translated to, separated by a single blank character, as a line in the )Translate section. In the example above, all occurrences of `` mysym'' will be translated to `` z1'', and all occurrences of `` yoursym'' to `` z2''. The )Translate section is rarely used to perform explicit symbol translation. The primary application of the translate section is to permit convenient Kelvination of multi-file programs, as discussed below. THE )CODE SECTION When the Kelvinator processes a symbol not present in the Protect or Translate sections which does not match a pattern, a gibberish name is generated and this and all subsequent occurrences of the symbol are translated to the gibberish name. The gibberish name is generated programmatically from a symbol code which is incremented for each new symbol encountered. The Kelvinator normally starts this code at zero, but can be instructed to generate symbols starting at any desired code by specifying the starting number in a )Code section. If more than one number is specified, in one or more )Code section(s), the last number encountered is used. The )Code section is almost never specified explicitly; it is generated by the Kelvinator to allow automatic Kelvination of multi-file programs. MULTIPLE FILE PROGRAMS If an AutoLisp program is a single file which is loaded into AutoCAD and run as a unit, the default translation performed by the Kelvinator is usually adequate. If an application consists of more than one original .lsp file and the running program loads different AutoLisp modules during execution, special care must be taken when Kelvinating the application. Simply running the Kelvinator on a source file translates all the variable names in it into a standard format. If each module of a multiple module program were Kelvinated, this would result in two distinct problems: 1) Variables shared between modules would be given different names in different modules, so values passed would not be received correctly in the loaded module. 2) Variables with distinct names in the original source might be translated into the same name in the Kelvinated output. Thus duplication of variable names would almost certainly occur. SHARED VARIABLES The first problem may be addressed in any of several ways. One option is to simply give all variables shared between modules names which match a pattern that causes them to be remain untranslated. Using the standard pattern in KELV.def, simply using a colon as the second character of all shared variables accomplishes this. If you don't want to name the shared variables to match a pattern, you can simply make a list of all the shared variables and specify that list as a )Protect section in a definition file. None of the shared variables will be translated, and thus they will retain their values across modules. Finally, and by far the easiest, you can use the technique for automatic multiple file Kelvination given below. This will guarantee that variables with the same name in the original source will share the same encoded name in the Kelvinated output. UNIQUE VARIABLE NAMES There are two approaches to preventing inadvertent duplication of variable names as a result of Kelvination. The first technique requires the use of an option on the call to the Kelvinator which permits generation of unique names for each module. If the Kelvinator is called with a -P prefix argument, the generated variable names will begin with the specified prefix. If no prefix is specified, the default of `` Q'' is used. The prefix may be any string which is a valid AutoLisp symbol, but should not be a symbol likely to duplicate an AutoLisp-defined symbol. If you're Kelvinating a four module electronic application, you might use: KELV arisia -pZA >parisia.lsp KELV scapture -pZB >pscapt.lsp KELV pcboard -pZC >ppcbd.lsp KELV simulate -pZD >psim.lsp Symbols in the respective modules will be given prefixes of ZA through ZD, and are therefore guaranteed to be unique. Remember that AutoLisp is far more efficient when storing symbols of 6 characters or less, so don't go overboard in choosing a variable prefix. Two characters should be adequate. If you use the automatic multiple file Kelvination technique described below, you need not assign unique prefixes; distinct names in the original set of files will be guaranteed distinct in the Kelvinated output. AUTOMATIC MULTI-FILE KELVINATION The Kelvinator allows AutoLisp programs which span multiple files to be Kelvinated in a close-to-automatic manner. When the Kelvinator is used in this fashion, names will be translated for the program taken as a whole, thus preserving the uniqueness of names across modules and guaranteeing that two names which were distinct in the original set of files will never be translated to the same name. Automatic multi-file Kelvination is made possible by a feature which causes the Kelvinator to write out the translation table used to Kelvinate a file in a form that can be used as the definition file for a subsequent run of the Kelvinator. If the -W file specification is placed on a call to the Kelvinator, after a file has been Kelvinated a complete definition file is written to the named file. All protected symbols and patterns used for the Kelvination are written to the file, and )Translate commands are given for all symbols changed by the Kelvinator. In addition, a )Code section is written to start symbol generation at the correct point in the next module. By passing on these definition files from run to run of the Kelvinator, the translated names assigned by the Kelvinator may be made uniform across the input file set. For example, here are the commands you would use to perform automatic multi- file Kelvination on the electronic application mentioned in the last section: KELV -wd1.def arisia >parisia.lsp KELV -dd1.def -wd2.def scapture >pscapt.lsp KELV -dd2.def -wd3.def pcboard >ppcbd.lsp KELV -dd3.def -wd4.def simulate >psim.lsp Note how we pass the output definitions from each file (which include all of the information from the files processed before) on to the Kelvination of the next file. We don't specify the -D switch for the first file since we're starting with the standard KELV.def file for that run. We don't need to save the definitions from the last file, but we did in this case because the saved definition file can be a handy tool for debugging the application. If a Kelvinated program crashes, the AutoLisp walkback will contain mostly gibberish symbols. If you retain a copy of the final definition file from the Kelvination run, you can translate this walkback into the original code and more easily locate the problem in the source. This capability makes saving the definitions worthwhile even for a single file program. OTHER BENEFITS OF KELVINATION Even if security is not a consideration, you might consider Kelvinating your program. By removing comments and white space and replacing long descriptive variable names with short cryptic ones, Kelvination may radically reduce the size of an AutoLisp program. For example, Kelvination of AutoShade reduced the ASHADE.LSP file from 13669 bytes to 4095 bytes, a reduction of more than three to one (the code was heavily commented). In addition, if you intend to Kelvinate the file before shipment, you are free to use long variable names for documentation purposes; Kelvination will reduce them to short names that AutoLisp can store efficiently. The new Kelvinator compresses its output somewhat more densely than the original Kelvinator---it knows quite a bit more about AutoLisp's input parser and sails very close to the wind in eliminating spaces wherever AutoLisp doesn't need them to delimit symbols in the input. The only speed benefit of Kelvination is that gained while loading because a Kelvinated file is usually smaller. Once loaded, a Kelvinated program will run in exactly the same time as a non-Kelvinated one (unless shortening of variable names has increased free memory and thus reduced garbage collections, which will yield a small edge to the Kelvinated program). ------------------------------ ;;; Graphic Systems, Inc. provides this program 'as is', without warranty of ;;; any kind, either expressed or implied, including, but not limited to the ;;; implied warranties of merchantability and fitness for a particular purpose. ;;; ;;; In no event shall Graphic Systems, Inc. be liable to anyone for special, ;;; collateral, incidental, or consequential damages in connection with or ;;; arising out of purchase or use of these materials. The entire risk as to ;;; the quality and performance of the program is with the user. Should the ;;; program prove defective, the user assumes the entire cost of all necessary ;;; servicing, repair or correction. ;;; ;;; For condition of use and permission to use these materials for publication ;;; in other than the English language, contact Graphic Systems, Inc. ;;; ;;; Graphic Systems, Inc. reserves the right to revise and improve its products ;;; as it sees fit. This publication describes the state of this product at ;;; the time of its publication, and may not reflect the product at all times ;;; in the future.
Python Advanced Programming: The Guide to Learn Python Programming. Reference with Exercises and Samples About Dynamical Programming, Multithreading, Multiprocessing, Debugging, Testing and More