Script Encoding
Overview
One thing that becomes immediately obvious to those who come to writing script from a programming background is that anything they create using script is easily and readily visible to anyone and everyone else. There is no compiler that turns the code into code that only a machine can make sense of. This was a real worry, but on the whole it didn't stop people writing and using scripts. It also had massive advantages for scripting in general. Just as the open, plain-text nature of HTML made learning Web design easier than say learning C++, the same ' open book' format for scripts encouraged a huge explosion of script use on the Web. Okay, thinking back to those times, some of it was pretty bad and looked pretty ugly, but we didn't care because it was scripting and it made our pages look more exciting than the others out there. Because it was so easy to see how scripts worked (and to copy the code from one page and paste it into another), the future of scripting was guaranteed .
However, now with the future of script use well established, a bit of privacy isn't a bad thing. Programmers who use script want to regain some of the mystique that they once had when using C++ or VB (using script to solve a problem is a bit like a magician in a see-through jacket). Things have moved on a little bit from the days of scripts being a total free-for-all and there are a few things you can do to make it harder for those script snoopers to see your secrets!
Limitations of Script Encoding
It's only fair that we inject a bit of reality and caution here. None of the methods that we will look at there for making it harder for the script snoopers to peek at your code are 100 percent guaranteed. In fact, the best of them, the Microsoft Script Encoder, isn't very robust at all. Why? Because ultimately the browser must still be able to execute the script. This means any technique you use will be a weak one. Of course, if you want to protect a script from viewing you could take an encryption program, such as PGP, and run that on your script. Taking all the proper precautions you could be pretty guaranteed that your script would be safe-the problem is that it's so safe the browser can't do anything with it anymore!
Fortunately, script snoopers come in a variety of forms:
- Someone that wants to take a look at how it works
- Someone wanting to learn how the script works
- Someone who wants to use or modify the script for a benign purpose
- Someone who wants to modify the script for malicious purposes
They also come in a variety of skill levels:
- The lower skilled 'casual' snooper
- The skilled 'interested' snooper
- The skilled 'determined' snooper
It doesn't really matter why someone is trying to snoop on your script (although that might factor into why you might want to protect the script), the real factor here is how skilled they are and how determined. Taking simple precautions will deter the casual snooper and send them on their way but if someone is really determined to see your script, and they are skilled, nothing here will stop them. That's the plain truth and while it sounds harsh , it is much harsher to find out the hard way.
Why Encode Scripts?
Protecting your scripts is much more than just protecting your intellectual property-although there's nothing wrong with doing that!
Most people out there are honest and few even bother to look at plain-text scripts anyway. But even so, taking precautions against accidental changes with some script (such as Windows Script Host scripts) makes sense. If you have a WSH script that searches folders for particular files, copies them and then deletes the originals , you wouldn't want that script tampered with, ending up with it just deleting files (I've seen this happen and it wasn't an example of someone doing it maliciously instead a genuine accident caused by someone who was unfamiliar with the script.). If you use the Microsoft Script Encoder, you have the added advantage that if an encoded script is modified, just one character changed, it will no longer work. Encoding scripts can help protect curious users from themselves as much as from malicious attack.
How to Encode Script
Let's see how scripts can be encoded. We'll be looking at how VBScript code can be encoded with the Microsoft Script Encoder primarily, but we will also look at some other things that you can do to discourage script snooping. These won't be as effective as the Microsoft Script Encoder but they are nonetheless worth bearing in mind and can be quite effective in appropriate circumstances.
The Microsoft Script Encoder
The Microsoft Script Encoder is a simple, easy to use command line tool that script programmers can use to encode the scripts that they have created so that the source cannot be viewed or modified. (This works with JScript too, although we'll only be looking at VBScript here.)
Note |
The application is a Script Encoder. It encodes the script, but doesn't encrypt it. Encryption is different to encoding, but the difference is subtle. With both you take a file and change its format but with encryption the file is unusable until it is decrypted. Encoding changes the file from the point of view of a human reader but the script engine can still understand what the file does. |
Availability
The Microsoft Script Encoder installation file is available free from Microsoft as a small download (approximately 130KB) from www.microsoft.com/scripting . It is available in English, Chinese (traditional), German, and Korean.
Installation
Installing the Microsoft Script Encoder is easy. Locate the download (the English language version is called sce10en.exe while the Chinese version is called sce10cht.exe , the German version sce10de.exe , and the Korean version sce10ko.exe ). Double click it and follow the prompts. The default installation location for the command line application and the help files is C:Program FilesWindows Script Encoder .
As well as installing the command line application and the help file, the installation application also modifies the Windows registry so that the system recognizes .vbe and .jse files (VBScript Encoded Script files and JScript Encoded Script files).
Note |
Installation of the Microsoft Script Encoder is not required for running encoded script files. Only the programmer needs to install the decode. |
Using the Microsoft Script Encoder
The Microsoft Script Encoder is, as we mentioned earlier, a command line utility and doesn't come with a Windows interface. This means that it's not as easy to use as a GUI application. However, it's not particularly difficult to start using it and you will find that having it as a command line tool gives the added advantage that it can be easily integrated into batch files.
The Microsoft Script Encoder doesn't do any encoding itself but rather uses the scripting runtime module ( scrrun.dll ) to do the encoding for it. All the Script Encoder executable does is provide a command- line mechanism for calling the scripting.encoder object implemented in the scripting runtime. This is very handy indeed because it provides the programmer with an extensible mechanism for using encoding in their applications or in third-party applications. This was done by Microsoft to ensure that the programmer could use script encoding wherever they wanted, rather than only in a few specific areas.
Because scripting.encoder is simply a COM object, it may be used wherever any other COM object would be. This means you could extend on the functions provided by the Script Encoder in your own applications.
Because the installation program doesn't add the path to the encoder to the PATH system variable, it isn't available from every folder in a command prompt window. So that using the Microsoft Script Encoder is smooth and trouble-free, we recommend you do one of the following:
- Add the path to the Microsoft Script Encoder (the default path is C:Program FilesWindows Script Encoder ) to the PATH system variable
- Copy the Microsoft Script Encoder executable (screnc.exe) to the folder you will be using for script encoding
- Copy all of the scripts you want to encode to the folder used by the Microsoft Script Encoder
For clarity and simplicity, we will copy all the scripts that we'll be encoding to the folder used by the Microsoft Script Encoder.
Syntax
The easiest way to familiarize yourself with the syntax of the Microsoft Script Encoder is to begin using it. Open a command prompt window and navigate to C:Program FilesWindows Script Encoder . (The Microsoft Script Encoder can also be run from the Run dialog box in the Start Menu of Windows.) Once there, type the following:
screnc ?
This will make the application list the Help for the application. This can be a very useful reference when you are in a hurry! The output is shown in Figure 14-1.
The syntax for the Microsoft Script Encoder is as follows .
screnc [/s] [/f] [/xl] [/l defLanguage ] [/e defExtension] source destination
Here is a run through of the switches supported by the application:
- /?-Optional. The switch that lists the Help for the Script Encoder.
- /s-Optional. The switch that specifies that the Script Encoder is to work silently, that is, it produces no screen output. If this switch is omitted, the default is to provide verbose output.
- /f-Optional. This switch specifies that the input file is to be overwritten by the output file. Note that this option will destroy your original input source file, and perhaps your only unencoded copy of the script! If omitted, the output file is not overwritten.
- /xl-Optional. This switch specifies that the @language directive is not added at the top of .ASP files. If omitted, @language directive is added at the top of all .ASP files.
- /l defLanguage-Optional. This switch specifies the default scripting language (JScript or VBScript) to be used during encoding. Script blocks within the file being encoded that do not contain a language attribute are assumed to be of this specified language. If omitted, JScript is the default language for HTML pages and scriptlets, while VBScript is the default for active server pages. For plain-text files, the file extension (either, .js or .vbs ) is used to determine the default scripting language.
- /e defExtension-Optional. This switch associates the input file with a specific file type. You should use this switch when the input file's extension doesn't make the file type clear, that is, when the input file extension is not one of the recognized extensions, but the file content does fall into one of the recognized types. There is no default for this option. If a file with an unrecognized extension is encountered and this option is not specified, the Script Encoder fails for that unrecognized file. Recognized file extensions are asa , asp , cdx , htm , html , js , sct , and vbs .
- source-Required. This is the name of the input file to be encoded, and it can include any necessary path information relative to the current directory.
- destination-Required. This is the name of the output file to be produced, and it can include any necessary path information relative to the current directory.
Figure 14-1
Let's now look at how to put the above together with some examples. What follows are a few examples of the use of the Microsoft Script Encoder, each accompanied by a brief explanation of the results.
To encode the input file unencoded.htm and produce an output file called encoded.htm , use:
screnc unencoded.html encoded.html
To encode the input file test.htm and overwrite the input file with the encoded output file, use:
screnc /f test.htm
To encode all files with the .ASP file extension in the current directory and place the encoded output files in c:output, use:
screnc *.asp c:output
To encode all files in the current directory as .asp files and place them in c:output, use:
screnc /e asp *.* c:output
To encode input file un encoded.htm and produce output file encoded.htm , while ensuring that all script blocks that don't have a specified language attribute are encoded as VBScript, use:
screnc /l vbscript unencoded.htm encoded.htm
To encode every scriptlet file ( .sct ) in the current directory and overwrite each of them with encoded files, while not displaying a message, use:
screnc /s /f *.sct
What Files Can I Encode?
There are four kinds of files than can be processed by the Script Encoder: HTML, ASP, Plain text, and Scriptlets.
HTML Files
Any HTML file can be processed by the Microsoft Script Encoder, but remember that it only acts on the script in the page, so encoding an HTML page that doesn't contain any script won't have any effect on it but also won't generate any message to say that it doesn't contain script.
Let's look at encoding an HTML page containing VBScript. Following is the code of page we will use.
Simple VBScript Example Click Me If You Can!!!
We have named the preceding file unencoded.htm for clarity. Let's now take a look at how to use to the Microsoft Script Encoder to encode this file.
As we mentioned earlier, we will copy this file to the folder that contains the Microsoft Script Encoder. Then we open a command prompt window and navigate to that folder. Once there you type in the following, followed by Enter .
screnc unencoded.htm encoded.htm
If everything has worked and there were no errors of faults, there will be no error messages displayed and the command prompt returns as shown in Figure 14-2. Many people are surprised by this and expect some sort of confirmation that everything has worked out right.
Figure 14-2
However, where in the beginning you had just the one HTML file (called unencoded.htm ) you now have another new one-this one called encoded.htm . If you open up a text editor and take a look at the source code for this new HTML page you will see some key differences.
Simple VBScript ExampleClick Me If You Can!!!
In fact, two significant changes have been made: The script that previously was unencoded is now encoded (pretty obvious!) and the script language attribute value has been changed from VBScript to VBScript.Encoded . Do not be alarmed by this as this is exactly as it now would be and the browser will understand it. To prove this, open the page in the browser and see if it still works. Click on the button and a message box should be displayed as shown in Figure 14-3 to show that indeed the VBScript code does still work!
Figure 14-3
The great thing about the Microsoft Script Encoder is that you don't have to encode all the script on the page. You can choose where the encoding should start using the following encoding marker in your VBScript code:
˜**Start Encode**
Note |
For JScript the encoding marker would be //**Start Encode** |
Take a look at this modified example that follows. This example uses the encoding marker to begin encoding at the second subprocedure.
Simple VBScript ExampleClick Me If You Can!!!Click On Me Too!!!
Encoding the file alters any code that appears below the encoding marker. This results in the following output.
Simple VBScript ExampleClick Me If You Can!!!Click On Me Too!!!
Both subprocedures work as exactly normal. There is no difference between the encoded code and the unencoded code when the page is loaded into Internet Explorer and the script run. The only difference is a visual one, that you can understand the unencoded script but not the encoded script.
Here's a great trick to prevent others making changes to your copyright notices in scripts. Make your copyright notice part of the script! Place the copyright notice string into a variable and check to see if that variable is unaltered at runtime.
Simple VBScript Example Check copyright notice
Encoding this script gives you the following:
Simple VBScript ExampleCheck copyright notice
Now, when you run the script with the unaltered copyright notice, the script proceeds normally. However, just making one small change to the copyright notice halts the script.
Dim strCopyright strCopyright = "This script is copyright to you instead, 2003!"
Figure 14-4 shows the result of such tampering! A message is shown indicating that the script has been tampered with. This message would be very hard to get rid of ( certainly too hard for someone who wanted to borrow your code in the first place.).
Figure 14-4
ASP Files
Encoding ASP files is a little more complex than encoding HTML. This is because the ASP file format provides more information about script. However, if you have a relatively simple ASP file that contains a single script element, you should be able to run it through the Script Encoder and have it encoded without much trouble.
ASP lets you embed script code using the <% %> notation and many ASP pages use this method rather than the alternate tags. The recognized file extensions are .sct and .wsh; nothing new in the way that things work here. The main thing to remember is to make sure that VBScript code contained within a scriptlet is properly identifies using the language attribute.
Encoding the script generated the expected output.
Encoded Scripts Do s and Don ts
Before and after encoding there are a few do's and don'ts you should follow to ensure trouble-free scripts after encoding:
- Do keep an unencoded backup of the script.
- Do take care over correctly specifying the script language used, is there an ambiguity or you have not used the default.
- Do remove comments prior to encoding-after encoding they are useless and add significant bulk to the script.
- Do test the script before and after it is encoded to make sure it works.
- Don't make any changes to the script once encoded.
- Don't leave testing and debugging until the script is encoded!
- Don't expect script encoding to offer 100 percent code security. There are ways that the 'determined' script snooper can get around it.
Decoding the Script
One question you may be asking is 'If you use the Script Encoder to encode a script, what decodes it before it is executed?' Good question! In fact, version 5 of Windows Script brought with it the ability for any application that uses VBScript and JScript to use the encoding feature. Once the language name is set to VBScript.Encode (or JScript.Encode) the ability to interpret encoded scripts is activated in the script engine while the debugging features are deactivated to prevent people simply loading up the script debugger and taking a look at your code that way. So all the decoding is handled by the script engine. The command line Script Encoder is only used to encode the script and nothing else.
Other Methods of Script Obfuscation
Here is a quick rundown of a few alternatives to using the Microsoft Script Encoder. None of these alternatives are as effective. They do, however, help make the code more 'confusing' to follow and will deter the casual viewer from using or altering the script.
Remember to keep at least one copy of the script in its original format so that you can understand and make changes to it easily!
Remove Comment Tags
Seems simple but it can be quit effective. Removing all comment tags before making the code live can aid in adding an obstacle in the way of a code snooper. Comments are generally designed for internal consumption so why offer assistance to others in reading and deciphering your scripts!
Substitute Good Variable Names for Bad Ones
Here's another good idea, but one you should leave until the script is finished. This goes against the concept of using clear, well-defined variable names but by using a simple find and replace you could change clear variable names (such as TaxRate or Your Name ) to more obscure ones (such as var1 and var2).
Add Remove White Space
White space is critical in making code readable. If you remove indents the code becomes harder to read. Likewise, erratic indentation will make the code more complex.
Some programmers add a lot of white space at the top of code so that when the code is opened in a text editor, it appears to be a blank file.
Summary
In this chapter you've been introduced to a few ways through which you can make code harder to read by people who you don't want reading your code. Without doubt, the best method of protecting code both from viewing and changing is the Microsoft Script Encoder. You've seen how the Microsoft Script Encoder can be used to encode scripts that reside in plain-text files (usually Windows Script Host files), HTML pages, ASP pages, and scriptlet files. The Microsoft Script Encoder doesn't offer 100 percent protection but it does offer a level of protection that makes using it worthwhile.
We also briefly touched on other methods which aren't anywhere near as effective as using the Windows Script Encoder, but which may help to protect your code from the casual code snoopers.
We hope that this chapter has made you realize that your code need not be released unprotected and that there are steps you can take to protect both your time invested in your code and your intellectual property.