{"size": 2383, "ext": "js", "max_stars_repo_path": "GetSsdtTable.js", "max_stars_repo_name": "ionescu007/windbg_js_scripts", "max_stars_repo_stars_event_min_datetime": "2020-03-19T00:40:13.000Z", "max_stars_repo_stars_event_max_datetime": "2021-08-04T06:24:23.000Z", "max_issues_repo_path": "GetSsdtTable.js", "max_issues_repo_name": "msuiche/windbg_js_scripts", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "GetSsdtTable.js", "max_forks_repo_name": "msuiche/windbg_js_scripts", "max_forks_repo_forks_event_min_datetime": "2019-11-12T06:39:24.000Z", "max_forks_repo_forks_event_max_datetime": "2019-11-12T06:39:24.000Z"}
{"max_stars_count": 3, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 27.3908045977, "max_line_length": 108, "alphanum_fraction": 0.619806966}
/**
 *
 * Get the SSDT (nt) as WinDBG convience array
 *
 *
 * Usage:
 * kd> .scriptload \path\to\GetSsdtTable.js
 * kd> dx @$ServiceTable()
 *
 * Example:
 * kd> dx @$ServiceTable().Where( s => s.Name.Contains("nt") ).Count()
 *
 */
"use strict";

const log = x => host.diagnostics.debugLog(x + "\n");
const system = x => host.namespace.Debugger.Utility.Control.ExecuteCommand(x);
const Dereference = addr => host.evaluateExpression("(unsigned int*)0x" + addr.toString(16)).dereference();

function IsX64(){return host.namespace.Debugger.State.PseudoRegisters.General.ptrsize == 8;}
function GetSymbolFromAddress(x){ return system('.printf "%y", ' + x.toString(16)).First(); }


class SsdtEntry
{
    constructor(addr, name)
    {
        this.Address = addr
        this.Name = name;
    }

    toString()
    {
        return `(${this.Address.toString(16)}) ${this.Name}`;
    }
}


/**
 * Retrieve the SSDT offsets from nt!KeServiceDescriptorTable
 */
function FetchSsdtOffsets()
{
    var SsdtTable = host.getModuleSymbolAddress("nt", "KeServiceDescriptorTable");
    var NumberOfSyscalls = Dereference( host.getModuleSymbolAddress("nt", "KiServiceLimit") );
    var SsdtOffsetTable = [];
    var expr = "**(unsigned int(**)[" + NumberOfSyscalls.toString() + "])0x" + SsdtTable.toString(16);
    SsdtOffsetTable["Offsets"] = host.evaluateExpression(expr);
    SsdtOffsetTable["Base"] = host.getModuleSymbolAddress("nt", "KiServiceTable");
    return SsdtOffsetTable;
}


/**
 * Build a generator function from the SSDT table offsets, that returns the symbol
 * associated to the address.
 */
function *ShowSsdtTable()
{
    let OffsetTable = FetchSsdtOffsets();
    for (var i = 0 ; i < OffsetTable.Offsets.Count(); i++)
    {
        var Address;

        if (IsX64())
        {
            Address = OffsetTable.Base.add(OffsetTable.Offsets[i] >> 4);
        }
        else
        {
            Address = OffsetTable.Base.add(OffsetTable.Offsets[i]);
        }
        var Symbol = GetSymbolFromAddress(Address);
        yield new SsdtEntry(Address, Symbol) ;
    }
}


function initializeScript()
{
    //
    // Alias the function to WinDBG
    //
    log("[+] Creating the variable `ServiceTable` for the SSDT...");
    return [new host.functionAlias(ShowSsdtTable, "ServiceTable")];
}
