Programming/JavaScript/JSSh/Command line

From Skypher

Jump to: navigation, search

Main Page
├─▼Programming
│ ├─▼JavaScript
│ │ ├─▼JSSh
│ │ │ └─●Command line
│ │ ├─○JavaScriptStringEncode()
│ │ ├─○serialize()
│ │ ├─○visualize()
│ │ ├─○stackDump()
│ │ ├─○errorHandler()
│ │ └─○Array extensions
│ ├─▷ASP
│ └─○Chimera code
└─▷Hacking

Contents


A simple command line version of JSSh exists: You can enter commands, which will be executed when you press ENTER. The result will be displayed in a useful format - see JS/visualize(). Pressing ENTER without entering a command terminates JSSh.

The code

The below file, JSSh.cmd, is chimera code, which is both a valid batch file as well as a JavaScript. You can run it from the command line, in which case it will be run as a batch file. The batch file does nothing more than load the javaScript using CSCRIPT.EXE. The JavaScript contains the main loop that asks for imput and executes it.

@if (!@_jscript) == (!@_jscript) (ECHO OFF) else BAT PART OF FILE STARTS HERE
CSCRIPT /Nologo /e:jscript "%~f0" %0 %*
GOTO :EOF
@end // JAVASCRIPT PART OF FILE STARTS HERE

function visualize(xValue, sPadding, iDepth) {
	if (typeof(sPadding) !== "string") sPadding = "";
	if (typeof(iDepth) !== "number") iDepth = 2;
	switch (typeof(xValue)) {
		case "undefined": return "undefined";
		case "boolean":   return xValue.toString();
		case "string":
			return "\"" +
				xValue.replace(/[\0-\x1F\"\\\x7F-\xA0\u0100-\uFFFF]/g, function (sChar) {
					switch (sChar) {
						case "\b": return "\\b";
						case "\t": return "\\t";
						case "\n": return "\\n";
						case "\f": return "\\f";
						case "\r": return "\\r";
						case "\\": return "\\\\";
						case "\"": return "\\\"";
					}
					var iChar = sChar.charCodeAt(0);
					if (iChar < 0x10) return "\\x0" + iChar.toString(16);
					if (iChar < 0x100) return "\\x" + iChar.toString(16);
					if (iChar < 0x1000) return "\\u0" + iChar.toString(16);
					return "\\u" + i.toString(16);
					return c;
				}) +
				"\"";
		case "number":
			// Inifinity, NaN, floats, small integers and negative numbers
			// are displayed as is:
			if (
				!isFinite(xValue) || isNaN(xValue) ||
				xValue != parseInt(xValue) || xValue < 10
			) {
				return xValue.toString();
			}
			// Otherwise we'll display as a decimal and hexadecimal number:
			return xValue.toString() + "  (0x" + xValue.toString(16).toUpperCase() + ")";
		case "function":
			var sFunction = xValue.toString();
			if (iDepth == 2) return sFunction.replace(/\r?\n/g, "$&" + sPadding);
			else return sFunction.replace(/\{[\s\S]*$/, "{ ... }");
		case "object":
			if (xValue == null) return "null";
			var sConstructor = null;
			try { sConstructor = xValue.constructor.toString(); }
			catch (e) { return "object unknown"; }
			var sHeader = "Unknown{", sFooter = "}";
			var oName = sConstructor.match(/^\r?\n?function (\w+)\([\s\S]*$/);
			if (oName) switch (oName[1]) {
				case "Boolean": return "Boolean(" + visualize(xValue.valueOf(), sPadding, iDepth) + ")";
				case "Date":    return "Date(" + visualize(xValue.toString(), sPadding, iDepth) + ")";
				case "Number":  return "Number(" + visualize(xValue.valueOf(), sPadding, iDepth) + ")";
				case "String":  return "String(" + visualize(xValue.valueOf(), sPadding, iDepth) + ")";
				case "RegExp":
					var sFlags = "";
					if (xValue.global) sFlags += "g";
					if (xValue.ignoreCase) sFlags += "i";
					if (xValue.multiline) sFlags += "m";
					return "RegExp(/" + xValue.source + "/" + sFlags + ")";
				case "Array":
					sHeader = "Array [", sFooter = "]";
					break;
				default:
					sHeader = "Object " + oName[1] + " {";
			} else try {
				oName = xValue.toString().match(/^\[(?:object )?(.*)\]$/);
				if (oName) sHeader = "Object [" + oName[1] + "] {";
			} catch (e) { }
			if (iDepth == 0) return sHeader + " ... " + sFooter;
			var asValues = [];
			try {
				for (var i in xValue) {
					// Integers are displayed as numbers, anything else as a string
					var sIndex = parseInt(i).toString() == i ?
						i:
						visualize(i);
					// A child object that is the same as its parent is displayed as "=> self",
					// Anything else is "visualized":
					var sValue = xValue[i] === xValue ?
						"=> self":
						visualize(xValue[i], sPadding + "    ", iDepth - 1);
					asValues.push(sPadding + "    " + sIndex + ": " + sValue);
				}
			} catch (e) {
				return "object unknown";
			}
			return sHeader + "\r\n" +
				asValues.join("\r\n") + "\r\n" +
				sPadding + sFooter;
		default:
			try { return typeof(xValue) + " " + new String(xValue); }
			catch(e) { return "unknown"; }
	}
}

var goFSO = new ActiveXObject("Scripting.FileSystemObject");
var goWSS = new ActiveXObject("WScript.Shell");
var goENV = goWSS.environment("PROCESS");

WScript.stdOut.writeLine("JavaScript Shell (CScript) build 080818 by Berend-Jan \"SkyLined\" Wever");
WScript.stdOut.writeLine("Global objects:");
WScript.stdOut.writeLine("  goFSO = new ActiveXObject(\"Scripting.FileSystemObject\")");
WScript.stdOut.writeLine("  goWSS = new ActiveXObject(\"WScript.Shell\")");
WScript.stdOut.writeLine("  goENV = goWSS.environment(\"PROCESS\")");
WScript.stdOut.writeLine("");
WScript.stdOut.writeLine("Enter commands or type \"quit\" or \"exit\" to quit:");

while (1) {
	WScript.stdOut.write("JSSh>");
	var sInput = WScript.stdIn.readLine();
	if (sInput.match(/^\s*$/)) {
		do {
			sInput += WScript.stdIn.readLine() + "\r\n";
		} while (!sInput.match(/\r\n\r\n$/));
	}
	if (sInput == "quit" || sInput == "exit") WScript.quit();
	var xResult;
	try {
		new Function(sInput);
	} catch (e) {
		WScript.stdOut.writeLine("Parse error: " + visualize(e));
		continue;
	}
	try {
		xResult = eval(sInput);
	} catch (e) {
		WScript.stdOut.writeLine("Exception thrown: " + visualize(e));
		continue;
	}
	WScript.stdOut.writeLine(visualize(xResult));
}

Example usage

C:\Windows\system32>jssh
JavaScript Shell (CScript) build 080818 by Berend-Jan "SkyLined" Wever
Global objects:
  goFSO = new ActiveXObject("Scripting.FileSystemObject")
  goWSS = new ActiveXObject("WScript.Shell")
  goENV = goWSS.environment("PROCESS")

Enter commands or type "quit" or "exit" to quit:
JSSh>1+1
number: 2
JSSh>WScript.stdOut.writeLine("hello, world!");
hello, world!
undefined: undefined
JSSh>Math.random();
number: 0.47396005286261244
JSSh>cause an exception
Exception: Expected ';'
JSSh>quit

C:\Windows\system32>
Personal tools