Status: Work-in-progress
Last update: 07/09/2021
Source: MarkTiedemann/hta
TODOFor more details, see the Wikipedia article or read "Introduction to HTML Applications (HTAs)" in the Microsoft documentation.
TODO
TODOFor more details, see the Microsoft documentation.
mshta.exe
:
C:\> assoc .hta .hta=htafile C:\> ftype htafile htafile=C:\Windows\SysWOW64\mshta.exe "%1" (...) %*Therefore, HTA files can be executed directly. For example:
C:\> hello.hta
C:\> mshta "javascript: alert(screen.availWidth); close();"
<script> alert(location.pathname); close(); </script>
commandLine
property of the application object returns a quoted path to the HTA file
as well as additional command-line arguments.
For example, assuming the following HTA file args.hta
:
<hta:application id="app" /> <ol></ol> <script> window.onload = function () { var ol = document.getElementsByTagName("ol")[0]; var args = app.commandLine.split(/\s+/); for (var i = 0; i < args.length; i++) { var li = document.createElement("li"); li.innerText = args[i]; ol.appendChild(li); } }; </script>Executing the HTA as:
C:\dev> .\args.hta one two=three fourWould generate the following HTML:
To determine user compatibility, you may use the documentMode
and
compatMode
properties of the document
object:
document.documentMode
can be 5
, 7
, 8
, 9
, 10
, or 11
,
depending on the IE mode that was used to render the page.
document.compatMode
can be "BackCompat"
if the document is in quirks mode,
or "CSS1Compat"
if the document is in (almost) standards mode.
<script> function compatMode() { switch (document.compatMode) { case "BackCompat": return "quirks mode"; case "CSS1Compat": return "standards mode"; } } // Should alert "IE5 in quirks mode" alert("IE" + document.documentMode + " in " + compatMode()); close(); </script>
<meta http-equiv="x-ua-compatible" content="ie=9" />
TODO
<object id="minimize" classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"> <param name="command" value="minimize" /> </object>Click the object:
<button onclick="minimize.Click();">Minimize</button>
<object id="maximize" classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"> <param name="command" value="maximize" /> </object>Click the object:
<button onclick="maximize.Click();">Maximize</button>Note that maximizing an already maximized window will restore its original size.
<script> close(); // Or alternatively: window.close(); self.close(); </script>
FileSystemObject
has a number of methods that allow you to manipulate files, folders, paths, and drives.
Another important object in this category is the
TextStream
object which is used for reading and writing files.
<script> // Write "hello" into the file "world.txt" var fs = new ActiveXObject("Scripting.FileSystemObject"); var stream = fs.createTextFile("world.txt", /*Overwrite*/ true); stream.write("hello"); stream.close(); close(); </script>
<script> // Read "hello" from the file "world.txt" var fs = new ActiveXObject("Scripting.FileSystemObject"); var stream = fs.openTextFile("world.txt", /*ForReading*/ 1); alert(stream.readAll()); stream.close(); close(); </script>
WScript.Shell
documentation.
ExpandEnvironmentStrings
method of the
WshShell
object.
For example, the following code will expand the %windir%
environment variable
and print its value (C:\Windows
, on most systems):
<script> var sh = new ActiveXObject("WScript.Shell"); alert(sh.expandEnvironmentStrings("%windir%")); close(); </script>
<script> var sh = new ActiveXObject("WScript.Shell"); sh.run("calc"); close(); </script>
<script> var sh = new ActiveXObject("WScript.Shell"); sh.run("cmd /c \"php -S localhost:8000\"", 0, false); close(); </script>
powershell
and print its version:
<script> var sh = new ActiveXObject("WScript.Shell"); var proc = sh.exec("powershell -c $PSVersionTable.PSVersion.toString()"); alert(proc.stdout.readAll()); close(); </script>
WshShell
object also contains methods for working with the Windows Registry, specifically
RegWrite
,
RegRead
, and
RegDelete
:
<script> // Write "hello" into the registry entry HKCU\Software\world var sh = new ActiveXObject("WScript.Shell"); sh.regWrite("HKCU\\Software\\world", "hello"); close(); </script>
<script> // Read "hello" from the registry entry HKCU\Software\world var sh = new ActiveXObject("WScript.Shell"); alert(sh.regRead("HKCU\\Software\\world")); close(); </script>
<script> // Delete the registry entry HKCU\Software\world var sh = new ActiveXObject("WScript.Shell"); sh.regDelete("HKCU\\Software\\world"); close(); </script>
TODO
Name
and ProcessId
of all running processes
and display them in a table.
<h1>Processes</h1> <table> <thead> <tr> <th>Name</th> <th>ProcessId</th> </tr> </thead> <tbody></tbody> </table> <script> window.onload = function () { var tbody = document.getElementsByTagName("tbody")[0]; var locator = new ActiveXObject("WbemScripting.SWbemLocator"); var service = locator.ConnectServer(".", "root\\cimv2"); var collection = service.ExecQuery("SELECT Name, ProcessId FROM Win32_Process"); var enumerator = new Enumerator(collection); while (!enumerator.atEnd()) { var item = enumerator.item(); appendRow(tbody, item); enumerator.moveNext(); } }; function appendRow(tbody, item) { var tr = document.createElement("tr"); var tdName = document.createElement("td"); var tdProcessId = document.createElement("td"); tdName.innerText = item.Name; tdProcessId.innerText = item.ProcessId; tr.appendChild(tdName); tr.appendChild(tdProcessId); tbody.appendChild(tr); } </script>
console.log
does not work since console
is undefined
.
You can, however, use the alert
function to quickly log information.
The following HTA file will open a message box with the content Hello, world!
:
<script> alert("Hello, world!"); close(); <script/>Alternatively, you can use the
LogEvent
method of the
WshShell
object to log events to the Windows Event Log.
<script> var sh = new ActiveXObject("WScript.Shell"); sh.logEvent(0, "This is a SUCCESS event"); sh.logEvent(1, "This is an ERROR event"); sh.logEvent(2, "This is a WARNING event"); sh.logEvent(4, "This is an INFORMATION event"); close(); </script>To inspect the log, open the
Event Viewer
application (eventvwr.msc
).
var localStorage = (function () { var sh = new ActiveXObject("WScript.Shell"); var root = "HKCU\\Software\\localStorage\\"; return { getItem: function (key) { try { return sh.regRead(root + key); } catch (e) { return null; } }, setItem: function (key, value) { sh.regWrite(root + key, value); }, removeItem: function (key) { try { sh.regDelete(root + key); } catch (e) {} }, clear: function () { try { sh.regDelete(root); } catch (e) {} } } })();
var localStorage = (function () { var fs = new ActiveXObject("Scripting.FileSystemObject"); var sh = new ActiveXObject("WScript.Shell"); var root = sh.ExpandEnvironmentStrings("%localappdata%") + "\\localStorage"; return { getItem: function (key) { try { var file = fs.openTextFile(root + "\\" + key, 1); var value = file.readAll(); file.close(); return value; } catch (e) { return null; } }, setItem: function (key, value) { if (!fs.folderExists(root)) { fs.createFolder(root); } var file = fs.createTextFile(root + "\\" + key, true); file.write(value); file.close(); }, removeItem: function (key) { try { fs.deleteFile(root + "\\" + key); } catch (e) {} }, clear: function () { try { fs.deleteFolder(root); } catch (e) {} } } })();
TODO
<script> var document = new ActiveXObject("HTMLFile"); document.open(); document.write("<h1 id=\"hello\">world</h1>"); document.close(); alert(document.getElementById("hello").innerText); close(); </script>
<hta:application icon="#" />Prepend the icon to your HTA file:
C:\> copy /b icon.ico+app.hta app_with_embedded_icon.hta
TODO