Jim Lawless' Blog


WSH2EXE part 2

Originally published on: Sat, 25 Apr 2009 22:39:18 +0000

My goals and requirements for WSH2EXE were simple:

  1. WSH2EXE would be a command-line program
  2. WSH2EXE should be able to run either the windowed script-interpreter (wscript.exe) or the console script-interpreter against the embedded script
  3. WSH2EXE should be able to invoke either a VBScript script or a JavaScript script
  4. WSH2EXE should allow the developer to specify a temporary directory by name

The data held in WSH2EXE would be a set of flags and variables containing the settings from the above and two stub EXE's; I would need a console-mode EXE to launch a console version of a script and a windowed-mode EXE to launch a windowed version of a script.

Keep in mind that I want the end-result EXE to contain the scripts and all of the above configuration data. My choices in storing this data in an already-compiled EXE include the option to overwrite some known portion of the EXE file itself, append the data to the EXE, or I could find a way to embed all of the data that I want as a Windows Resource data block into the EXE.

I chose to explore the second option; I would build a utility to stamp a block of data into a compiled EXE.

Please consider the source code for embedded.c below:


#include <stdio.h>

struct internalData {
   int someNumber;
   char someString[20];
} *dat;


char globalData[sizeof(struct internalData)]="[[[[[[[[" ;


int main(int argc,char **argv) {
   dat=(struct internalData *) globalData;
   printf("someNumber is %d\n",dat->someNumber);
   printf("someString is %s\n",dat->someString);
   return 0;
}

The output from this compiled code is: someNumber is 1532713819 someString is [[[[

I have set a pointer to a struct of type internalData to refer to a char block that I have initialized with eight left-bracket characters. When the someNumber element is displayed, it has treated each of the first four '[' characters as data and displays the number 1532713819.

The element someString occupies the remainder of the block of data. When we display it, we only see the first four characters ( which are the last four '[' characters of the eight that I had specified ) and then nothing else once the zero byte is encountered.

I created the string of eight '[' bytes to act as a sentinel value so that I could create a separate utility to find and overwrite that block of the EXE.

Please consider the following program stamp.c:


#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct internalData {
   int someNumber;
   char someString[20];
} ;


int main(int argc,char **argv) {
#define MAX (1024*1024)
   FILE *fin,*fout;
   char *buff;
   struct internalData tmp;
   int i,sz;

   tmp.someNumber=42;
   strcpy(tmp.someString,"Don't look up!");
   fin=fopen("embedded.exe","rb");
   if(fin==NULL) {
      fprintf(stderr,"Cannot open input file embedded.exe \n");
      return 1;
   }
   fout=fopen("embedded2.exe","wb");
   if(fout==NULL) {
      fclose(fin);
      fprintf(stderr,"Cannot open output file embedded2.exe \n");
      return 1;
   }

   buff=(char *)malloc(MAX);
   sz=fread(buff,1,MAX,fin);
   if(sz<=0) {
      fclose(fin);
      fclose(fout);
      fprintf(stderr,"Unable to read input file.");
      return 1;
   }
   fclose(fin);
   for(i=0;i<(sz-7);i++) {
      if( (buff[i]=='[')&&
          (buff[i+1]=='[')&&
          (buff[i+2]=='[')&&
          (buff[i+3]=='[')&&
          (buff[i+4]=='[')&&
          (buff[i+5]=='[')&&
          (buff[i+6]=='[')&&
          (buff[i+7]=='[')) {
             memcpy(buff+i,&tmp,sizeof(struct internalData));
             break;
      }
   }
   fwrite(buff,1,sz,fout);
   fclose(fout);
   return 0;
}

The above program will open embedded.exe, which should be the output of the compiled embedded.c program, and will overwrite the internalData struct so that someString is "Don't look up!" and someNumber is 42.

Stamp.exe will then write the new EXE to a file named embedded2.exe.

The output of embedded2.exe is: someNumber is 42 someString is Don't look up!

The data-stamping technique looked to be a plausible option. However, I didn't feel like defining a static buffer in WSH2EXE big enough to hold all of the data that would be needed by the two stub EXE's. I chose to use the stamping technique to embed the flags and variables.

My next proof-of-concept was to build a mechanism to append the stub EXE's to WSH2EXE.

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: WSH2EXE part 1
Next post:Stacking Images with PerlMagick


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

Understanding TRS-80 CMD Files

Pi Day Meets the HTML5 Canvas

Mad Schemes : Learning Lisp via SICP

A Command-Line CD Tray Opener

Tracing XSLT with a Tiny Java Web Server

Preventing Windows Screen-Saver Activation

BPL: Batch Programming Language Interpreter

Stacking Images with PerlMagick

Compiling Rhino JavaScript to Java

Command-Line Image Format Conversion


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