mirror of
https://github.com/yardenshafir/WinDbg_Scripts
synced 2026-06-08 18:28:57 +00:00
176 lines
7.2 KiB
JavaScript
176 lines
7.2 KiB
JavaScript
"use strict";
|
|
|
|
//
|
|
// To use the script:
|
|
// 1. Load SymbolBuilderComposition (clone and build from: https://github.com/microsoft/WinDbg-Samples/blob/master/TargetComposition/SymBuilder/Readme.txt)
|
|
// 2. Fix function offset and size as needed in DefineNtDeviceIoControlFileSignature (current offset and size match 24H2 Preview build 10.026080.1)
|
|
// 3. Call DefineNtDeviceIoControlFileSignature with: dx @$DefineNtDeviceIoControlFileSignature()
|
|
// 4. Reload symbols: .reload
|
|
// 5. Define breakpoint on NtDeviceIoControlFile: bp nt!NtDeviceIoControlFile "dx @$LogIoctlArgs(); g"
|
|
// 6. Define breakpoint on end of NtDeviceIoControlFile: bp nt!NtDeviceIoControlFile+0x62 "dx @$LogIoctlOutput(); g"
|
|
// 7. Let the machine run with "g"
|
|
// 8. When you'd like to stop the trace and flush data to the file, call CloseLogFile: dx @$CloseLogFile()
|
|
//
|
|
|
|
function initializeScript()
|
|
{
|
|
return [new host.apiVersionSupport(1, 9),
|
|
new host.functionAlias(CreateTextWriter, "CreateTextWriter"),
|
|
new host.functionAlias(CloseLogFile, "CloseLogFile"),
|
|
new host.functionAlias(DefineNtDeviceIoControlFileSignature, "DefineNtDeviceIoControlFileSignature"),
|
|
new host.functionAlias(LogIoctlArgs, "LogIoctlArgs"),
|
|
new host.functionAlias(LogIoctlOutput, "LogIoctlOutput")];
|
|
}
|
|
|
|
function invokeScript()
|
|
{
|
|
}
|
|
|
|
let sym = 0;
|
|
let lastOutputBuffer = 0;
|
|
let lastOutputBufferLength = 0;
|
|
let logFile = 0;
|
|
let txtWriter = 0;
|
|
|
|
|
|
function CreateTextWriter(f)
|
|
{
|
|
return host.namespace.Debugger.Utility.FileSystem.CreateTextWriter(f);
|
|
}
|
|
|
|
function CloseLogFile()
|
|
{
|
|
if (logFile != 0)
|
|
{
|
|
logFile.Close();
|
|
logFile = 0;
|
|
txtWriter = 0;
|
|
}
|
|
}
|
|
|
|
let filename = "c:\\temp\\ioctl_args.txt";
|
|
|
|
function LogIoctlOutput()
|
|
{
|
|
let dbgOutput = host.diagnostics.debugLog;
|
|
|
|
if ((logFile === 0) || (txtWriter === 0))
|
|
{
|
|
if (host.namespace.Debugger.Utility.FileSystem.FileExists(filename))
|
|
{
|
|
logFile = host.namespace.Debugger.Utility.FileSystem.OpenFile(filename);
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
txtWriter = CreateTextWriter(logFile);
|
|
}
|
|
|
|
let outputBuffer = lastOutputBuffer
|
|
let outputBufferLen = lastOutputBufferLength
|
|
|
|
if (outputBuffer.address != 0)
|
|
{
|
|
try
|
|
{
|
|
let outputData = host.memory.readMemoryValues(outputBuffer, outputBufferLen, 1);
|
|
txtWriter.WriteLine("\tOutput data @0x" + outputBuffer.toString(16) + ": " + outputData);
|
|
}
|
|
catch (e) {}
|
|
}
|
|
}
|
|
|
|
function LogIoctlArgs()
|
|
{
|
|
let dbgOutput = host.diagnostics.debugLog;
|
|
|
|
if ((logFile === 0) || (txtWriter === 0))
|
|
{
|
|
if (host.namespace.Debugger.Utility.FileSystem.FileExists(filename))
|
|
{
|
|
logFile = host.namespace.Debugger.Utility.FileSystem.CreateFile(filename, "OpenExisting");
|
|
}
|
|
else
|
|
{
|
|
dbgOutput("Creating new log file\n");
|
|
logFile = host.namespace.Debugger.Utility.FileSystem.CreateFile(filename);
|
|
}
|
|
txtWriter = CreateTextWriter(logFile);
|
|
}
|
|
|
|
txtWriter.WriteLine("\nNtDeviceIoControlFile arguments:");
|
|
|
|
let callingProcessName = host.currentProcess.Name;
|
|
let callingProcessId = host.currentProcess.Id;
|
|
txtWriter.WriteLine("\tProcess: " + callingProcessName + " (" + callingProcessId + ")");
|
|
|
|
let fileHandle = host.currentThread.Stack.Frames[0].Parameters.FileHandle;
|
|
let targetDeviceName = host.currentProcess.Io.Handles[fileHandle].Object.UnderlyingObject.FileName;
|
|
let targetDriverName = host.currentProcess.Io.Handles[fileHandle].Object.UnderlyingObject.Device.Driver.DriverName;
|
|
|
|
txtWriter.WriteLine("\tDevice: " + targetDeviceName + " (Driver: " + targetDriverName + ")");
|
|
|
|
let ioctlCode = host.currentThread.Stack.Frames[0].Parameters.IoControlCode;
|
|
txtWriter.WriteLine("\tIOCTL code: 0x" + ioctlCode.toString(16));
|
|
|
|
let inputBuffer = host.currentThread.Stack.Frames[0].Parameters.InputBuffer;
|
|
txtWriter.WriteLine("\tInput Buffer address: 0x" + inputBuffer.address.toString(16));
|
|
let inputBufferLen = host.currentThread.Stack.Frames[0].Parameters.InputBufferLength;
|
|
txtWriter.WriteLine("\tInput Buffer length: 0x" + inputBufferLen.toString(16));
|
|
|
|
// read input buffer
|
|
if (inputBuffer.address != 0)
|
|
{
|
|
try
|
|
{
|
|
let inputData = host.memory.readMemoryValues(inputBuffer.address, inputBufferLen, 1);
|
|
txtWriter.WriteLine("\tInput data: " + inputData);
|
|
}
|
|
catch (e) {}
|
|
}
|
|
|
|
let outputBuffer = host.currentThread.Stack.Frames[0].Parameters.OutputBuffer;
|
|
txtWriter.WriteLine("\tOutput Buffer address: 0x" + outputBuffer.address.toString(16));
|
|
let outputBufferLen = host.currentThread.Stack.Frames[0].Parameters.OutputBufferLength;
|
|
txtWriter.WriteLine("\tOutput Buffer length: 0x" + outputBufferLen.toString(16));
|
|
|
|
// save the output buffer and output buffer length so we can use them on function exit (best effort, this won't always be accurate)
|
|
lastOutputBuffer = outputBuffer.address;
|
|
lastOutputBufferLength = outputBufferLen;
|
|
}
|
|
|
|
function DefineNtDeviceIoControlFileSignature()
|
|
{
|
|
if (sym === 0)
|
|
{
|
|
sym = host.namespace.Debugger.Utility.SymbolBuilder.CreateSymbols("nt", {AutoImportSymbols: true});
|
|
}
|
|
// hardcode function size because I'm lazy
|
|
let NtDeviceIoControlFileSize = 0x62;
|
|
let psNtosBase = host.getModuleSymbolAddress("nt", "PsNtosImageBase");
|
|
let ntosBase = host.memory.readMemoryValues(psNtosBase, 1, 8);
|
|
let pNtDeviceIoControlFile = host.getModuleSymbolAddress("nt", "NtDeviceIoControlFile");
|
|
let ntDeviceIoControlSym = sym.Functions.Create("NtDeviceIoControlFile", "int", host.parseInt64(pNtDeviceIoControlFile, 16).subtract(ntosBase[0]), NtDeviceIoControlFileSize);
|
|
let fileHandle = ntDeviceIoControlSym.Parameters.Add("FileHandle", "__int64");
|
|
fileHandle.LiveRanges.Add(0, 8, "@rcx");
|
|
let event = ntDeviceIoControlSym.Parameters.Add("Event", "__int64");
|
|
event.LiveRanges.Add(0, 8, "@rdx");
|
|
let apcRoutine = ntDeviceIoControlSym.Parameters.Add("ApcRoutine", "void*");
|
|
apcRoutine.LiveRanges.Add(0, 8, "@r8");
|
|
let apcContext = ntDeviceIoControlSym.Parameters.Add("ApcContext", "void*");
|
|
apcContext.LiveRanges.Add(0, 8, "@r9");
|
|
let ioStarusBlock = ntDeviceIoControlSym.Parameters.Add("IoStatusBlock", "_IO_STATUS_BLOCK*");
|
|
ioStarusBlock.LiveRanges.Add(0, 8, "[@rsp + 28]");
|
|
let ioctl = ntDeviceIoControlSym.Parameters.Add("IoControlCode", "int");
|
|
ioctl.LiveRanges.Add(0, 4, "[@rsp + 30]");
|
|
let inputBuffer = ntDeviceIoControlSym.Parameters.Add("InputBuffer", "void*");
|
|
inputBuffer.LiveRanges.Add(0, 4, "[@rsp + 38]");
|
|
let inputBufferLength = ntDeviceIoControlSym.Parameters.Add("InputBufferLength", "int");
|
|
inputBufferLength.LiveRanges.Add(0, 4, "[@rsp + 40]");
|
|
let outputBuffer = ntDeviceIoControlSym.Parameters.Add("OutputBuffer", "void*");
|
|
outputBuffer.LiveRanges.Add(0, 4, "[@rsp + 48]");
|
|
let outputBufferLength = ntDeviceIoControlSym.Parameters.Add("OutputBufferLength", "int");
|
|
outputBufferLength.LiveRanges.Add(0, 4, "[@rsp + 50]");
|
|
}
|