microsoft / WinDbg-Samples

Sample extensions, scripts, and API uses for WinDbg.
MIT License
702 stars 118 forks source link

multiple JavaScript scripts that reference each other? #95

Closed nblog closed 1 week ago

nblog commented 8 months ago

console.js

class console{
    static log(...args) {
        host.diagnostics.debugLog(`${args}\n`);
    }
}
module.exports = console;

test.js

import {console} from "./console";
console.log("hello???");

How can multiple JavaScript scripts be used in combination, or is there a similar compiler (merge)?

Something like frida-compile?

wmessmer-msft commented 5 months ago

At the moment, import/export is not supported. Two JavaScript scripts cannot directly reference each other. That said, they can reference each other through the data model either indirectly (preferred) or directly (less preferred).

Take the following script example (executed as a saved "console.js"):

"use strict";

function log(...args)
{
    host.diagnostics.debugLog(`${args}\n`);
}

class __Console
{
    log(...args)
    {
        host.diagnostics.debugLog(`${args}\n`);
    }
}

class __ScriptUtility
{
    get Console()
    {
        return new __Console();
    }
}

function initializeScript()
{
    return [new host.apiVersionSupport(1, 9),
            new host.namespacePropertyParent(__ScriptUtility, "Debugger.Models.Utility", "Debugger.Models.Utility.Script", "Script")];
}

This exposes the functionality of log in two ways:

  1. It's just in the script. That means it's directly referencable from host.namespace.Debugger.State.Scripts..Contents
  2. It adds a new namespace to Debugger.Utility via extending "Debugger.Models.Utility" with a "Script" namespace that has a new "Console" object in it. This is via the host.namespacePropertyParent registration in initializeScript

Now it's usage from another script:

"use strict";

function getConsole1()
{
    return host.namespace.Debugger.State.Scripts.console.Contents;
}

function getConsole2()
{
    return host.namespace.Debugger.Utility.Script.Console;
}

function invokeScript()
{
    getConsole1().log("Hello World #1");
    getConsole2().log("Hello World #2");
}

function initializeScript()
{
    return [new host.apiVersionSupport(1, 9)];
}

You can see both ways that the underlying functionality of the other script is used.

There are other similar mechanisms that can be used:

Hope that clarifies a bit...