Created
December 5, 2024 14:49
-
-
Save 0xatul/e464f4b05dab2e8337d08e830181c2a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// | |
| /// <reference path="../extra/JSProvider.d.ts" /> | |
| /// | |
| /// @ts-check | |
| /// @links | |
| /// - https://aka.ms/JsDbgExt | |
| /// | |
| "use strict"; | |
| // Thanks for the template @hugsy | |
| /** | |
| * When called via `.scriptrun` | |
| */ | |
| function invokeScript() { | |
| var afdIoctlTable = host.getModuleSymbolAddress("afd", "AfdIoctlTable"); | |
| var afdImmIoctlTable = host.getModuleSymbolAddress("afd", "AfdImmediateCallDispatch"); | |
| var afdDispatchTable = host.getModuleSymbolAddress("afd", "AfdIrpCallDispatch"); | |
| var afdDispatchImmIrp = host.getModuleSymbolAddress("afd", "AfdDispatchImmediateIrp"); | |
| for (let i = 0; i < 74; i++) { | |
| let ioctl_address = afdIoctlTable.add(i * 0x04); | |
| let ioctl = read32(ioctl_address); | |
| //log(`AFD IOCTL: ${i} - ${ioctl.toString(16)}`); | |
| let idx = ioctl.bitwiseShiftRight(2).bitwiseAnd(0x3FF); | |
| let dispatchFunc = poi(afdDispatchTable.add(idx.multiply(0x08))); | |
| //log(`AFD IOCTL: ${ioctl.toString(16)} - ${dispatchFunc}`); | |
| if (dispatchFunc.compareTo(afdDispatchImmIrp) == 0 ) { | |
| let immDispatchFunc = poi(afdImmIoctlTable.add(idx.multiply(0x08))); | |
| log(`AFD IOCTL: ${ioctl.toString(16)} -> ${get_symbol( afdDispatchImmIrp).name } -> ${get_symbol(immDispatchFunc).name}`); | |
| } else { | |
| log(`AFD IOCTL: ${ioctl.toString(16)} -> ${get_symbol(dispatchFunc).name}`); | |
| } | |
| } | |
| } | |
| /** | |
| * Always called, whether via `.scriptload` or `.scriptrun` | |
| */ | |
| function initializeScript() { | |
| return [ | |
| new host.apiVersionSupport(1, 9), | |
| ]; | |
| } | |
| /** | |
| * Always called, using `.scriptunload` | |
| */ | |
| function uninitializeScript() { | |
| } | |
| Object.prototype.toString = function () { if (this["__Name"] !== undefined) { return `${this["__Name"]}` }; if (this["__Path"] !== undefined) { return `${this["__Path"]}` }; return ``; }; | |
| /** | |
| * @param {string} x | |
| */ | |
| const log = x => host.diagnostics.debugLog(`${x}\n`); | |
| /** | |
| * | |
| * @param {string} x | |
| */ | |
| const ok = x => log(`[+] ${x}`); | |
| /** | |
| * @param {string} x | |
| */ | |
| const warn = x => log(`[!] ${x}`); | |
| /** | |
| * @param {string} x | |
| */ | |
| const err = x => log(`[-] ${x}`); | |
| /** | |
| * Returns a hex string of the host.Int64 | |
| * @param {host.Int64} x | |
| * @returns {string} | |
| */ | |
| const hex = x => x.toString(16); | |
| /** | |
| * | |
| * @param {string} x | |
| * @returns {host.Int64} | |
| */ | |
| const i64 = x => host.parseInt64(x); | |
| /** | |
| * Execute the WinDbg command | |
| * @param {string} x | |
| * @returns {any} | |
| */ | |
| const system = x => host.namespace.Debugger.Utility.Control.ExecuteCommand(x); | |
| /** | |
| * Return the sizeof the structure `y` in module `x` | |
| * @param {string} x | |
| * @param {string} y | |
| * @returns {host.Int64} | |
| */ | |
| const sizeof = (x, y) => host.getModuleType(x, y).size; | |
| /** | |
| * Return the offset of the field `n` in the structure `t` | |
| * @param {string} t | |
| * @param {string} n | |
| * @returns {host.Int64} | |
| */ | |
| const FIELD_OFFSET = (t, n) => parseInt(system(`?? #FIELD_OFFSET(${t}, ${n})`).First().split(" ")[1].replace("0n", "")); | |
| /** | |
| * Return the base address of the structure with a field at address `a`, of type `n` in the module `t` | |
| * @param {host.Int64} a | |
| * @param {string} t | |
| * @param {string} n | |
| * @returns {host.Int64} | |
| */ | |
| const CONTAINING_RECORD = (a, t, n) => a.add(-FIELD_OFFSET(t, n)); | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function read8(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.readMemoryValues(x, 1, 1)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function read16(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.readMemoryValues(x, 1, 2)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function read32(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.readMemoryValues(x, 1, 4)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function read64(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.readMemoryValues(x, 1, 8)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function write8(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.writeMemoryValues(x, 1, 1)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function write16(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.writeMemoryValues(x, 1, 2)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function write32(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.writeMemoryValues(x, 1, 4)[0]; } | |
| /** | |
| * | |
| * @param {host.Int64} x | |
| * @param {boolean} phy | |
| * @returns {host.Int64} | |
| */ | |
| function write64(x, phy = false) { if (phy) { x = host.memory.physicalAddress(x); } return host.memory.writeMemoryValues(x, 1, 8)[0]; } | |
| /** | |
| * @returns {sessionInterface} | |
| */ | |
| function cursession() { return host.namespace.Debugger.State.DebuggerVariables.cursession; } | |
| /** | |
| * @returns {processInterface} | |
| */ | |
| function curprocess() { return host.namespace.Debugger.State.DebuggerVariables.curprocess; } | |
| /** | |
| * @returns {threadInterface} | |
| */ | |
| function curthread() { return host.namespace.Debugger.State.DebuggerVariables.curthread; } | |
| /** | |
| * @returns {host.Int64} | |
| */ | |
| function ptrsize() { return cursession().Attributes.Machine.PointerSize; } | |
| /** | |
| * @returns {host.Int64} | |
| */ | |
| function pagesize() { return cursession().Attributes.Machine.PageSize; } | |
| /** | |
| * @returns {boolean} | |
| */ | |
| function is64b() { return ptrsize() === 8; } | |
| /** | |
| * @returns {boolean} | |
| */ | |
| function isKd() { return cursession().Attributes.Target.IsKernelTarget === true; } | |
| /** | |
| * @param {string} r | |
| * @returns {any} | |
| */ | |
| function $(r) { return isKd() ? curthread().Registers.User[r] || curthread().Registers.Kernel[r] : curthread().Registers.User[r]; } | |
| /** | |
| * @param {host.Int64} x | |
| * @returns {symbolInformationInterface} | |
| */ | |
| function get_symbol(x) { return host.getModuleContainingSymbolInformation(x); } | |
| /** | |
| * @param {host.Int64} x | |
| * @returns {host.Int64} | |
| */ | |
| function poi(x) { return is64b() ? read64(x) : read32(x); } | |
| /** | |
| * | |
| * @param {boolean} condition | |
| * @param {string} message | |
| */ | |
| function assert(condition, message = "") { if (!condition) { throw new Error(`Assertion failed ${message}`); } } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment