From 6fc7f87b2256b5c0fc0e9bd8488b769386e1d938 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 26 Jan 2018 16:35:59 +0000 Subject: [PATCH] [MSGTRANS] - Add support for NTSTATUS to Win32 error code conversion - Allow codes to be looked up via #define value as well as numeric --- MsgTrans.Library/Command.cs | 8 +- MsgTrans.Library/MsgTrans.Library.csproj | 1 + MsgTrans.Library/MsgTrans.cs | 5 ++ MsgTrans.Library/NtStatusCommand.cs | 53 +++++++---- MsgTrans.Library/NtStatusToWin32.cs | 108 +++++++++++++++++++++++ MsgTrans.Library/WinerrorCommand.cs | 52 +++++++---- 6 files changed, 193 insertions(+), 34 deletions(-) create mode 100644 MsgTrans.Library/NtStatusToWin32.cs diff --git a/MsgTrans.Library/Command.cs b/MsgTrans.Library/Command.cs index 231ed2a..5b92b0e 100644 --- a/MsgTrans.Library/Command.cs +++ b/MsgTrans.Library/Command.cs @@ -52,10 +52,10 @@ public Command(MessageTranslator msgTrans) } protected void AddMessage(MessageType msgType, - long dec, - string hex, - string code, - string msg) + long dec, + string hex, + string code, + string msg) { MsgType = msgType; Number = dec; diff --git a/MsgTrans.Library/MsgTrans.Library.csproj b/MsgTrans.Library/MsgTrans.Library.csproj index d272994..c5253b0 100644 --- a/MsgTrans.Library/MsgTrans.Library.csproj +++ b/MsgTrans.Library/MsgTrans.Library.csproj @@ -65,6 +65,7 @@ + diff --git a/MsgTrans.Library/MsgTrans.cs b/MsgTrans.Library/MsgTrans.cs index 081dbec..14a6a5e 100644 --- a/MsgTrans.Library/MsgTrans.cs +++ b/MsgTrans.Library/MsgTrans.cs @@ -36,6 +36,10 @@ public enum MessageType BugUrl = 5, // // Summary: + // NTSTATUS to Win32 code conversion + NtStatusToDos = 5, + // + // Summary: // a custom Check code Custom = 6 } @@ -81,6 +85,7 @@ public MessageTranslator(IMsgOutput msgOutput, bugcheckXml)); commands.Add(new WMCommand(this, wmXml)); commands.Add(new BugCommand(this, bugUrl)); + commands.Add(new NtStatusToWin32(this, ntstatusXml, winerrorXml)); } public bool ParseCommandMessage(MessageContext context, diff --git a/MsgTrans.Library/NtStatusCommand.cs b/MsgTrans.Library/NtStatusCommand.cs index c4c169d..ee78307 100644 --- a/MsgTrans.Library/NtStatusCommand.cs +++ b/MsgTrans.Library/NtStatusCommand.cs @@ -26,31 +26,35 @@ public override bool Handle(MessageContext context, return false; } + long dec; + string hex; NumberParser np = new NumberParser(); - if (!np.Parse(ntstatusText)) + if (np.Parse(ntstatusText)) { - return false; + dec = np.Decimal; + hex = np.Hex; } - - string description = GetNtstatusDescription(np.Decimal); + else + { + dec = GetNtStatusNumber(ntstatusText); + if (dec == -1) + { + return false; + } + hex = dec.ToString("X"); + } + + string description = GetNtstatusDescription(dec); if (description != null) { AddMessage(MessageType.NTSTATUS, - np.Decimal, - np.Hex, + dec, + hex, description, null); return true; - }/* - else - { - MsgTrans.MsgOutput.MsgOut(context, - String.Format("I don't know about NTSTATUS {0}.", - ntstatusText)); - - return false; - }*/ + } return false; } @@ -75,5 +79,24 @@ public string GetNtstatusDescription(long ntstatus) else return null; } + + private long GetNtStatusNumber(string ntstatus) + { + XmlElement root = base.m_XmlDocument.DocumentElement; + XmlNode node = root.SelectSingleNode(String.Format("Ntstatus[@text='{0}']", + ntstatus)); + if (node != null) + { + XmlAttribute value = node.Attributes["value"]; + if (value == null) + throw new Exception("Node has no value attribute."); + + string hex = value.Value; + + return Convert.ToInt64(hex, 16); + } + else + return -1; + } } } diff --git a/MsgTrans.Library/NtStatusToWin32.cs b/MsgTrans.Library/NtStatusToWin32.cs new file mode 100644 index 0000000..911e503 --- /dev/null +++ b/MsgTrans.Library/NtStatusToWin32.cs @@ -0,0 +1,108 @@ +using System; +using System.Xml; +using System.Runtime.InteropServices; + +namespace MsgTrans.Library +{ + public class NtStatusToWin32 : Command + { + NtStatusCommand NtstatusCodes = null; + WinerrorCommand WinerrorCodes = null; + + [DllImport("kernel32.dll")] + public static extern IntPtr LoadLibrary(string FileName); + + [DllImport("kernel32.dll")] + public static extern IntPtr GetProcAddress(IntPtr hModule, string ProcName); + + [DllImport("kernel32.dll")] + public static extern bool FreeLibrary(IntPtr hModule); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate ulong fRtlNtStatusToDosError(ulong NtStatusCode); + + + public NtStatusToWin32(MessageTranslator msgTrans, + string ntstatusXml, + string winerrorXml) : + base(msgTrans) + { + NtstatusCodes = new NtStatusCommand(msgTrans, ntstatusXml); + WinerrorCodes = new WinerrorCommand(msgTrans, winerrorXml); + } + + public override string[] AvailableCommands + { + get { return new string[] { "ntstat2dos" }; } + } + + public override bool Handle(MessageContext context, + string commandName, + string parameters) + { + string ntstatusText = parameters; + if (ntstatusText.Equals(String.Empty)) + { + return false; + } + + if (!NtstatusCodes.Handle(context, commandName, parameters)) + { + return false; + } + + long DosCode = GetDosCodeFromNtstatus(NtstatusCodes.Number); + if (DosCode == 0xFFFFFFFF) + { + return false; + } + + if (!WinerrorCodes.Handle(context, commandName, DosCode.ToString())) + { + return false; + } + + return true; + } + + public override string Help() + { + return "blurgh "; + } + + private long GetDosCodeFromNtstatus(long ntstatus) + { + ulong DosCode = 0xFFFFFFFF; + IntPtr hModule = LoadLibrary(@"ntdll.dll"); + if (hModule != null) + { + IntPtr Address = GetProcAddress(hModule, "RtlNtStatusToDosError"); + + fRtlNtStatusToDosError RtlNtStatusToDosError = + (fRtlNtStatusToDosError)Marshal.GetDelegateForFunctionPointer(Address, + typeof(fRtlNtStatusToDosError)); + + DosCode = RtlNtStatusToDosError((ulong)ntstatus); + + FreeLibrary(hModule); + + } + return (long)DosCode; + } + } +} + + +/* + DWORD Status; + RTL_NTSTATUS_TO_DOS_ERROR pRtlNtStatusToDosError; + HMODULE hModule = LoadLibraryW(L"ntdll.dll"); + if (hModule) + { + pRtlNtStatusToDosError = (RTL_NTSTATUS_TO_DOS_ERROR)GetProcAddress(hModule, "RtlNtStatusToDosError"); + +#define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS)0xC0000712L) + Status = pRtlNtStatusToDosError(STATUS_PROCESS_IS_PROTECTED); + } + + */ \ No newline at end of file diff --git a/MsgTrans.Library/WinerrorCommand.cs b/MsgTrans.Library/WinerrorCommand.cs index 9c5bf99..1b00da1 100644 --- a/MsgTrans.Library/WinerrorCommand.cs +++ b/MsgTrans.Library/WinerrorCommand.cs @@ -27,32 +27,37 @@ public override bool Handle(MessageContext context, return false; } + long dec; + string hex; NumberParser np = new NumberParser(); - if (!np.Parse(winerrorText)) + if (np.Parse(winerrorText)) { - return false; + dec = np.Decimal; + hex = np.Hex; } - - string description = GetWinerrorDescription(np.Decimal); + else + { + dec = GetNtStatusNumber(winerrorText); + if (dec == -1) + { + return false; + } + hex = dec.ToString("X"); + } + + string description = GetWinerrorDescription(dec); if (description != null) { - string message = new System.ComponentModel.Win32Exception(Convert.ToInt32(np.Decimal)).Message; + string message = new System.ComponentModel.Win32Exception(Convert.ToInt32(dec)).Message; AddMessage(MessageType.WinError, - np.Decimal, - np.Hex, + dec, + hex, description, message); return true; - }/* - else - { - MsgTrans.MsgOutput.MsgOut(context, - String.Format("I don't know about System Error Code {0}.", - winerrorText)); - return false; - }*/ + } return false; } @@ -77,5 +82,22 @@ public string GetWinerrorDescription(long winerror) else return null; } + + private long GetNtStatusNumber(string winerrorName) + { + XmlElement root = base.m_XmlDocument.DocumentElement; + XmlNode node = root.SelectSingleNode(String.Format("Winerror[@text='{0}']", + winerrorName)); + if (node != null) + { + XmlAttribute value = node.Attributes["value"]; + if (value == null) + throw new Exception("Node has no value attribute."); + + return Convert.ToInt64(value.Value); + } + else + return -1; + } } }