Skip to content

Instantly share code, notes, and snippets.

@ildar-shaimordanov
Forked from yaauie/hello.jscript.bat
Last active May 28, 2024 23:05
Show Gist options
  • Save ildar-shaimordanov/88d7a5544c0eeacaa3bc to your computer and use it in GitHub Desktop.
Save ildar-shaimordanov/88d7a5544c0eeacaa3bc to your computer and use it in GitHub Desktop.

Windows lacks anything quite like Unix's shebang, which provides a way for a script to tell its interpreter how to interpret it, but polyglots can be used to provide similar functionality.

A polyglot is a script that works in multiple interpreters, hiding functionality and syntax specific to one language from another language's interpreter by clever use of each language/interpreter's specific features.

Let's look at how each of our two interpreters deal with the above script:

  • BATCH allows redirection to occur anywhere in a command line, not just a the tail. It does this by actually rearranging the command in pre-parsing, turning our first line 0</*! :: into :: 0</*!, which is a comment and is not executed. Line 5 is a hello from batch, Line 6 executes the called script in cscript/node with the appropriate arguments (subtitute your interpreter here), and line 9 sends us to :EOF, ignoring the rest of the script.

  • JAVASCRIPT / NODEJS: Lines 1-11 are reduced to a single instruction once the multi-line comment is ignored: 0<0;. This adds minimal weight and no memory overhead, and the script continues as normal.

  • /*!: The special form of comments denoting smart obfuscators not touch this comment and leave it as is. This could be useful for sensitive comments like resources for javascript scripts, copyrights or important documentation for those who will read the text of the script.

0</*! ::
@echo off
echo:Hello, batch!
cscript //nologo //e:jscript "%~f0" %*
echo:Hello, batch again!
goto :EOF
*/0;
WScript.Echo('Hello, jscript!');
Hello, batch!
Hello, jscript!
Hello, batch again!
0</*! ::
@echo off
echo:Hello, batch!
node "%~f0" %*
echo:Hello, batch again!
goto :EOF
*/0;
console.log("Hello, NodeJS!");
Hello, batch!
Hello, NodeJS!
Hello, batch again!
0</*! ::
@echo off
echo:Hello, batch!
java -jar js.jar "%~f0" %*
echo:Hello, batch again!
goto :EOF
*/0;
print("Hello, Rhino!");
Hello, batch!
Hello, Rhino!
Hello, batch again!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment