HSPLet usage

Last modified by John Stroy on 2012/12/23 06:55

This is the HSPlet usage page.  It is a guide to porting HSP programs to run on the HSPlet framework.

What is HSPlet?

HSPlet is a framework for adapting programs written for the OpenHSP (also known as "HSP") environment to the Java Virtual Machine (JVM).  HSPlet consists of a set of runtime libraries and a static compiler that analyzes and transforms the HSP bytecode into JVM bytecode.

Who is the audience?

  • Developers: If you've invested significant effort in writing HSP programs, but would like to enable their use on non-Windows, Java-capable platforms, HSPlet may be an option.  Additionally, you might want some of the benefits that HSPlet delivers that OpenHSP does not.
  • Users: If you're using an HSP program with no access to source code, and would like to adapt and/or modify the program, HSPlet may be an option.  Additionally, if you are a user on a non-Windows but Java-capable platform, you might find HSPlet useful.

Why HSPlet?

HSPlet might make sense for a number of reasons:

  • You want to make a HSP program cross-platform.
  • You want to use a more modern platform than what's provided by OpenHSP (for example, binding to scripting engines, accessing Java libraries, etc.)
  • You want to test your program against an alternate implementation of HSP.
  • You want a safer environment where bounded buffers are rigorously checked (to avoid unmanaged buffer overflows).
  • You want to bring an HSP application into a Java applet in the browser.
  • You want to make changes to the program, but you don't have access to the source code.
  • You want to make changes to the program, but you can't read the source code. emoticon_smile

How?

Getting start.ax

To get started, you'll need a start.ax file, which contains the bytecode for the HSP program.  There are a few ways to get this:

  • Compile the source code for the HSP program
  • Extract the start.ax file from a DPM packfile.
  • Extract start.ax from the memory of an obfuscated or packed image.
  • Extract start.ax directly from an unobfuscated image (for example, program.exe)

From a compiler

You're all set!  Move on to the next step.

From a DPM packfile

To do.

From an obfuscated image

Typical HSP applications contain a virtual machine (bytecode interpreter or JIT?) and the bytecode for the actual program.  Since the VM needs to understand HSP opcodes in their original form, an obfuscater/packer normally extracts the bytecode image to memory.  Do this with a tool like WinDbg: 

  • Attach the debugger to the target application.  (You can elect to use a non-invasive attach.)
  • Allow the application to load into a steady state.
  • Break into the debugger.
  • Search for the magic bytes "HSP3".  Under WinDbg:
s -a 0 L?0xffffffff 'HSP3'

(Here, 0 L?0xffffffff denotes "The entire 0xffffffff-byte of virtual address range starting from 0, or simply, "from 0 to 0xffffffff".  This is overkill; if you know the valid ranges, you can reduce the search time; for example, on 32-bit platforms, at most 2 GBs need to be searched.)

  • Once you have found the offset of "HSP3", verify the next four bytes, which contains a 32-bit integer indicating the version of the bytecode.  Remember that the x86 family uses little-endian notation.  Typically, you should find something like 0x00030001.  You can find information about the start.ax header in hsp3code.txt
  • We're not interested in the next 4 bytes, so they can be skipped.
  • The 32-bit integer 12 bytes away from the offset of the beginning of the "HSP3" string indicates the size of the start.ax file.  Decode this (again, remember x86 is little-endian).
  • Dump the range of bytes from the offset of "HSP3" to the number of bytes found in the previous step.  Save this to a file, start.ax.

Suppose the offset is 0x12345678 and the size is 3141592 (in decimal).  Use the following command in WinDbg to save to a file:

.writemem C:\data\start.ax 0x12345678 L?3141592

From an unobfuscated image

You can follow the same steps as with an obfuscated image, but it isn't required.  If you have an unpacked/unobfuscated/cleartext image, you can use any generic hex editor to perform the same steps as above:

  • Locate the "HSP3" ASCII string in the file.  
  • The next four bytes after "HSP3" header should denote the version number and should be something like 0x00030001.  Don't forget that you're operating on x86, which is a little-endian machine.
  • The 32-bit integer 12 bytes away from the offset of the beginning of the "HSP3" string indicates the size of the start.ax file.  Decode this (again, remember x86 is little-endian).
  • Take the 32-bit integer obtained in the previous step and use this as the length, starting from the offset of the "HSP3" header.  Dump this range of bytes to start.ax.

Compiling HSPlet

Got your start.ax?  Good.

Get the source code for HSPlet here:

https://bitbucket.org/jdstroy/hsplet/

You can download the tarball from BitBucket or use the Mercurial client to check out the source code like so:

hg clone https://bitbucket.org/jdstroy/hsplet/ C:\repos\hsplet

You'll need to grab a few dependencies:

Library name in NetBeansVersionOfficial name of the libraryJAR nameDescriptionURL
JavaLayer>=1.0JLayerjl1.0.jarMP3 decoder library for Javahttp://www.javazoom.net/javalayer/javalayer.html
Java printf>=1.6Java printf packagehb16.jarhttp://www.braju.com/
WIPWIPWIPWIPWIPWIP

BrowserLauncher (BrowserLauncher2-10rc4.jar)
ObjectWeb_ASM (asm-debug.all-3.3.jar) - You may use the non-debug asm.all-3.3.jar instead for better compilation performance.
Xstream-XML-Library (xpp3_min-1.14c.jar) - This is the XML Pull Parser.  Some versions of the source code need this, but not all of them do.  See below.
Xstream-XML-Library (xstream-1.3.1.jar) - This is the XStream library.  Some versions of the source code need this, but not all of them do.  I use this for capturing the runtime state, when traditional debugging is too difficult due to memory / time constraints.  XStream, in some cases, depends on the XML Pull Parser, xpp3.
SQLiteJDBC (sqlitejdbc-v056.jar) - Actually not used yet!  You can fill in a dummy jar here for now, but I'm hoping to use this as an extension in HSPlet.
LiveConnect (plugin.jar) - You can find this in %JAVA_HOME%\lib\plugin.jar.  Don't know what that means?  Check where you installed Java.  It'll be under the lib directory.  This is used by all the applet support infrastructure.
Javolution (javolution-5.5.1.jar)
org.apache.commons.codec (commons-codec-1.7.jar)

Ant should be able to build HSPlet, provided that the dependencies are there, but the easiest way is to get the NetBeans IDE and fill in the missing dependencies.

I hope to move to Apache Maven some day soon, and when that happens, all of this should be as simple as "mvn package"

At this point, you should be able to get NetBeans to build HSPlet.  Now we want to run the hsplet.compiler.GuiFrontEnd class.

Compiling start.ax

Once you've started the GUI frontend to HSPlet, you can specify the start.ax file by clicking the "Add..." button.  There are three fields at the bottom of the panel; one specifies the location of your .JAR file, while another specifies the location of your output .HTML file, and finally, one specifies the template for the .HTML file.  All of them need to be specified, but the last two don't matter if you're building an application and not an applet.

Click the left button to compile.  If all goes well, you'll get a nice dialog box letting you know that compilation finished successfully.

Bundling the dependencies

We're ready to run your program.  Set up your classpath so that it includes all the .JAR from the dependencies, as well as the hsplet.jar you produced for running the compiler.

The Finish Line

If you named your HSP bytecode to start.ax, then you'll just want to call the hsplet.Application class.  If you named it anything else, let hsplet.Application know with the --startClass= option.