Jim Lawless' Blog


WSH2EXE part 1

Originally published on: Fri, 24 Apr 2009 22:31:20 +0000

Some time ago, I noticed a rise in interest from people in various online forums who wanted to be able to compile their VBScript or Javascript/Jscript Windows Script Host (WSH) source code into stand-alone executable files.

I wondered if they truly needed to have their compiled to machine-code or if they'd really just wanted to package a script in an EXE to prevent the casual user from tinkering with it.

I decided to create a utility called WSH2EXE.

My main goal with WSH2EXE was to keep from having to write the target VBScript or JavaScript code to the filesystem. I knew I would need to write some sort of stub to the filesystem to host the rest of the code with a call to eval() or Execute().

As I pondered various approaches, one emerged that I chose to test; I would try to have the host EXE set an environment variable with the full text of the script to be executed. Then, I would write out a short stub of script code that would eval()/Execute() the environment variable.


#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>

int main(int argc,char **argv) {
   FILE *fp;
   char buff[256];

      // write out the stub
   fp=fopen("stub.js","w");
   fprintf(fp,"WScript.Echo('Running the script!');\n");
   fprintf(fp,"shl=new ActiveXObject('WScript.Shell');\n");
   fprintf(fp,"env=shl.Environment('Process');\n");
   fprintf(fp,"eval(env('wsh_prog'));\n");
   fprintf(fp,"WScript.Echo('Done running the script!');\n");
   fclose(fp);

      // set the wsh_prog env variable
   putenv("wsh_prog=WScript.Echo('This is just a test.');");

      // run the console version of the WSH interpreter
   sprintf(buff,"cscript.exe /nologo stub.js");
   system(buff);
   printf("\nPress ENTER to continue.\n");
   while(!getch())
      getch();
   return 0;
}

The output from this compiled code is:

Running the script! This is just a test. Done running the script!

Press ENTER to continue.

The test stub Javascript code that was created looks like this:


WScript.Echo('Running the script!');
shl=new ActiveXObject('WScript.Shell');
env=shl.Environment('Process');
eval(env('wsh_prog'));
WScript.Echo('Done running the script!');

After the EXE terminated, the wsh_prog environment variable was nowhere to be found in the existing set of environment strings; it had been created only for the EXE process and all spawned processes.

Okay. The theory looked to be sound. Just to be certain, let's create another EXE that writes a VBScript stub to the filesystem and invokes the WSH interpreter on it.


#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>

int main(int argc,char **argv) {
   FILE *fp;
   char buff[256];

      // write out the stub
   fp=fopen("stub.vbs","w");
   fprintf(fp,"WScript.Echo \"Running the second script!\"\n");
   fprintf(fp,"Set shl=WScript.CreateObject(\"WScript.Shell\")\n");
   fprintf(fp,"Set env=shl.Environment(\"Process\")\n");
   fprintf(fp,"Execute(env(\"wsh_prog\"))\n");
   fprintf(fp,"WScript.Echo \"Done running the script!\"\n");
   fclose(fp);

      // set the wsh_prog env variable
   putenv("wsh_prog=WScript.Echo \"This is just a test.\"");

      // run the console version of the WSH interpreter
   sprintf(buff,"cscript.exe /nologo stub.vbs");
   system(buff);
   printf("\nPress ENTER to continue.\n");
   while(!getch())
      getch();
   return 0;
}

The output was as follows: Running the second script! This is just a test. Done running the script!

Press ENTER to continue.

The generated VBScript code looked like this:


WScript.Echo "Running the second script!"
Set shl=WScript.CreateObject("WScript.Shell")
Set env=shl.Environment("Process")
Execute(env("wsh_prog"))
WScript.Echo "Done running the script!"

Press ENTER to continue.

I had the beginnings of WSH2EXE. Now that my proof-of-concept was complete, I needed to flesh out the remainder of my goals for the utility.

To be continued...

Unless otherwise noted, all code and text entries are Copyright ©2009 by James K. Lawless

del_icio_us Save to del.icio.us
stumbleupon Save to StumbleUpon
digg Digg it
reddit Save to Reddit
facebook Share on Facebook
twitter Share on Twitter
aolfav More bookmarks



Previous post: Cheating the LZW
Next post:WSH2EXE part 2


Search this Blog (and site)

Search this Site with PicoSearch


Subscribe to this Blog

 Subscribe!


Contact Me

Email: jimbo@radiks.net


Follow me on Twitter

http://twitter.com/lawlessGuy


Recent Posts

Mad Schemes : Learning Lisp via SICP

Auto Save Clipboard Images Redux

Extending SpiderMonkey JavaScript on Windows

Rhino JavaScript to EXE with launch4j

Compiling Rhino JavaScript to Java

Directory Traversal in Rhino JavaScript

Taking Shape

We've Moved!


Popular Posts

A Command-Line MP3 Player for Windows

Auto Save Images from the Clipboard

Java in a Windows EXE with launch4j

An Interview with Tom Zimmer: Forth System Developer

Setting Windows Console Text Colors in C


Random Posts

RSS feed processing with AWK

Directory Traversal in Rhino JavaScript

Screen Captures with Java and Clojure

WSH2EXE - The Final Chapter

A Quine in C

Switching a Console Window to Full Screen or Windowed Mode

Computers I Have Known

Thwarting HTTP Referer Trackbacks

Mad Schemes : Learning Lisp via SICP

JRuby as a Java Obfuscation Utility


Full List of Posts

http://www.mailsend-online.com/bloglist.htm


Blogroll

MicroISV on a Shoestring
DadHacker
The Bottom Feeder
Writin' That Code!
The Recursive ISV
The Thomsen Blog
Prototypically Speaking
The Reinvigorated Programmer