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



Views expressed in this blog are those of the author and do not necessary reflect those of the author's employer. Views expressed in the comments are those of the responding individual.

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


About Jim ...


Click **here**
to try out MailWrench;
a command-line SMTP /
SMTPS (Google Gmail)
mailer for Windows.


Follow me on Twitter

http://twitter.com/lawlessGuy


Recent Posts

A JavaScript REPL for Android Devices

MailSend is Free

My Blog Engine

The October 10th Bug

A Review of Kevin Mitnick's Book Ghost in the Wires

Spellbound by Web Programming

Backlinks to my Blog Posts

Play MP3 Files with Python on Windows


Random Posts

A Quine in Forth

Scrolling GIF Banners with PerlMagick

BPL: Batch Programming Language Interpreter

Learning Z-80 Assembly Language on the TRS-80

FIF Isn't Forth

Internet Protocols and Rhino JavaScript

Auto Save Images from the Clipboard

Book Review : Using Google App Engine

Changing the C64 Text Color in C

The Protection Racket


Full List of Posts

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


Recent Posts from my Other Blog

Remembering Dr. San Guinary

Why Some Web Sites will go Dark on Jan 18th

SNL Superhero Skit

More Ruby Games

My Ruby Game Challenge Entry

Steal this Bookmarklet

Nerd Toys

Learn New Jargon, You Must

Spot the Wiebe

Tech Magazine Glory Days

Book Review : Paull Allen - Idea Man

A 90's Experiment in Online Systems - The U.S. West CommunityLink Service