DEV Community

Mike
Mike

Posted on

This Windows script isn't a cry for help

0< /* ::

@echo off

set /a min = 15
set /a max = 45

:loop

CScript //nologo //E:JScript "%~F0" "+{F15}"
set /a rand = (%RANDOM% * (%max% - %min% + 1) / 32768) + %min% + 1
ping -n %rand% -w 1 127.0.0.1 > NUL

goto :loop

*/ 0;

WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));
Enter fullscreen mode Exit fullscreen mode

What does this do?

Take a moment and see if you can figure out what's happening here.

Go on. I'll wait for 15 to 45 seconds, and then send the Shift + F15 key combination.

Why would you do that?

Because the F15 key exists but most keyboards no longer have it, so pressing Shift + F15 is very unlikely to do anything except act as a key combination being pressed in general, preventing the computer from sleeping in most cases (except some VDI setups).

It works without admin rights and on a vanilla Windows install, although some admins disable JScript.

How the f...

0< /* :: is input redirection from a file for file descriptor 0, which is a special case and refers to standard input (STDIN). For example, if you ran 0< test.txt find "hello", the shell would actually run find "hello" 0<test.txt, which would be the equivalent of running find "hello" then typing in the contents of test.txt into the prompt. So what does this do? 0< /* actually produces an error. But when you put a comment command (either :: or REM) at the end, the command becomes :: 0< /* which does nothing as it's a comment. We use :: instead of REM because REM will print out the line to the terminal while :: will not do that, so aesthetically :: is nicer.

So why the /* when any string can go there? Because that's the start of a javascript/jscript block comment and the jscript interpreter needs to not try to parse the batch scripting between the /* and the */. But then how does the jscript interpreter see this chunk of code? It reads the entire block from 0< /* :: to */ 0; as: 0 < 0; which evaluates to false, but that doesn't matter - it's valid jscript and doesn't have any side effects and the primary hurdle has been accomplished: a way to selectively parse batch script or jscript based on which interpreter is reading the file.

I'm going to skip over turning off echo, setting variables, and label looping, as these are fairly simple concepts, although fun fact - ECMAScript also has labels.

The next important line is CScript //nologo //E:JScript "%~F0" "+{F15}", which sends this .bat file to CScript. CScript starts a script in a command-line environment with several script engine choices (JScript in thise case). WScript is similar but runs a script in a Windows GUI and in this context is not completely related to the last line in the batch file. $~F0 is the full path, filename, and extension of the batch file currently running. +{F15} is Shift and the F15 key for SendKeys. To reiterate, when this batch file is sent, it sees the entire batch script as just 0<0; then runs the last line, which is also valid JScript.

The only interesting things about set /a rand = (%RANDOM% * (%max% - %min% + 1) / 32768) + %min% + 1 is that %RANDOM% is a built-in variable that produces an integer from 0 to 32767 (inclusive), using set /a always rounds down, and the last + 1 is specifically for the following line; when using sleep or timeout, you would not add the extra 1.

The next line, ping -n %rand% -w 1 127.0.0.1 > NUL, is an old way to create a timer that's less processor intensive than sleep and timeout. You basically ping yourself %rand% times with 1 second between each attempt; the +1 from the previous line is because there is no wait before the first ping. > NUL redirects the standard output to NUL, which of course just discards it.

If this script didn't have an infinite loop, you'd want to have a goto :eof before */ 0; to make your batch script skip over the remainder of the file that is not valid script.

And we finally get to the end and the actual JScript: WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));. JScript is roughly equivalent to JavaScript 1.5/ECMAScript3 and has a WScript API roughly analogous to VBScript.

Wrap up

Probably don't do things this way. But maybe you might want to, and now some of it makes sense.

Top comments (0)