/// <summary> /// Gets the message associated with the given <see cref="NTSTATUS"/>. /// </summary> /// <param name="status">The <see cref="NTSTATUS"/> for the error.</param> /// <returns>The description of the error.</returns> private static string GetMessage(NTSTATUS status) { string hexCode = $"0x{(int)status:X8}"; string namedCode = Enum.GetName(typeof(NTSTATUS.Code), status.AsUInt32); string statusAsString = namedCode != null ? $"{namedCode} ({hexCode})" : hexCode; string insert = $"NT_STATUS {GetSeverityString(status)}: {statusAsString}"; string message = null; #if DESKTOP message = status.GetMessage(); #endif return message != null ? $"{message} ({insert})" : insert; }
public static byte[] GcmDecrypt(byte[] pbData, byte[] pbKey, byte[] pbNonce, byte[] pbTag, byte[] pbAuthData = null) { pbAuthData = pbAuthData ?? new byte[0]; NTSTATUS status = 0; using (var provider = BCryptOpenAlgorithmProvider(AlgorithmIdentifiers.BCRYPT_AES_ALGORITHM)) { BCryptSetProperty(provider, PropertyNames.BCRYPT_CHAINING_MODE, ChainingModes.Gcm); var tagLengths = BCryptGetProperty <BCRYPT_AUTH_TAG_LENGTHS_STRUCT>(provider, PropertyNames.BCRYPT_AUTH_TAG_LENGTH); if (pbTag.Length < tagLengths.dwMinLength || pbTag.Length > tagLengths.dwMaxLength || (pbTag.Length - tagLengths.dwMinLength) % tagLengths.dwIncrement != 0) { throw new ArgumentException("Invalid tag length"); } using (var key = BCryptGenerateSymmetricKey(provider, pbKey)) { var authInfo = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.Create(); fixed(byte *pTagBuffer = pbTag) fixed(byte *pNonce = pbNonce) fixed(byte *pAuthData = pbAuthData) { authInfo.pbNonce = pNonce; authInfo.cbNonce = pbNonce.Length; authInfo.pbTag = pTagBuffer; authInfo.cbTag = pbTag.Length; authInfo.pbAuthData = pAuthData; authInfo.cbAuthData = pbAuthData.Length; //Initialize Cipher Text Byte Count int pcbPlaintext = pbData.Length; //Allocate Plaintext Buffer byte[] pbPlaintext = new byte[pcbPlaintext]; fixed(byte *ciphertext = pbData) fixed(byte *plaintext = pbPlaintext) { //Decrypt The Data status = BCryptDecrypt( key, ciphertext, pbData.Length, &authInfo, null, 0, plaintext, pbPlaintext.Length, out pcbPlaintext, 0); } if (status == NTSTATUS.Code.STATUS_AUTH_TAG_MISMATCH) { throw new CryptographicException("BCryptDecrypt auth tag mismatch"); } else if (status != NTSTATUS.Code.STATUS_SUCCESS) { throw new CryptographicException($"BCryptDecrypt failed result {status:X} "); } return(pbPlaintext); } } } }
public unsafe static void main(TcpClient K, object[] Param_Tab) { Packet_Subject TypeSub = (Packet_Subject)Param_Tab[0]; switch (TypeSub) { case Packet_Subject.GET_PRIV: try { Native.NtDll.Enumerations._PRIVILEGES ToGet = (Native.NtDll.Enumerations._PRIVILEGES)Param_Tab[1]; bool t1; NTSTATUS GetPriv = Native.NtDll.Functions.RtlAdjustPrivilege(ToGet, true, false, out t1); P.Type_Packet = PacketType.PLUGIN_CS_RES; P.Misc = new object[] { Packet_Subject.GET_PRIV, GetPriv, ToGet }; Send.Packet = P; lock (K) { Send.Send(K.GetStream()); } } catch (Exception ex) { // MessageBox.Show(ex.ToString()); } break; case Packet_Subject.GET_PRIO: IntPtr SizeOfData = (IntPtr)0x002; int nLsength = 0; void * DataPointer = (void *)0; NTSTATUS Stat = Functions.NtQueryInformationProcess(System.Diagnostics.Process.GetCurrentProcess().Handle, Enumerations._PROCESS_INFO_CLASS.ProcessPriorityClass, ref DataPointer, SizeOfData, out nLsength); P.Type_Packet = PacketType.PLUGIN_CS_RES; P.Misc = new object[] { Packet_Subject.GET_PRIO, (Enumerations._PRIORITY_CLASS)((uint)DataPointer) }; Send.Packet = P; { Send.Send(K.GetStream()); } break; case Packet_Subject.SET_PRIO: Native.NtDll.Enumerations._PRIORITY_CLASS ToSet = (Native.NtDll.Enumerations._PRIORITY_CLASS)Param_Tab[1]; NTSTATUS SetPrio = Functions.NtSetInformationProcess(System.Diagnostics.Process.GetCurrentProcess().Handle, Enumerations._PROCESS_INFO_CLASS.ProcessPriorityClass, (IntPtr)ToSet, (IntPtr)0x002); P.Type_Packet = PacketType.PLUGIN_CS_RES; P.Misc = new object[] { Packet_Subject.SET_PRIO, SetPrio }; Send.Packet = P; lock (K) { Send.Send(K.GetStream()); } break; case Packet_Subject.CHECK_UAC: uint p = 0; NTSTATUS ChckUAC = Functions.RtlQueryElevationFlags(&p); Enumerations.RtlQueryElevation_Flags Flags = (Enumerations.RtlQueryElevation_Flags)p; P.Type_Packet = PacketType.PLUGIN_CS_RES; P.Misc = new object[] { Packet_Subject.CHECK_UAC, Flags, p }; Send.Packet = P; lock (K) { Send.Send(K.GetStream()); } break; } }
public static extern Win32ErrorCode RtlNtStatusToDosError(NTSTATUS Status);
private static unsafe Exception ThrowInvokeNtQueryDirectoryFileError(string path, NTSTATUS status) { uint win32ErrorCode = NativeMethods.RtlNtStatusToDosError(status); throw new LastWin32ErrorException((int)win32ErrorCode, string.Format("Error during enumeration of files at \"{0}\".", path)); }
internal static Exception CreateCryptographicException(NTSTATUS ntStatus) { int hr = unchecked ((int)ntStatus) | 0x01000000; return(hr.ToCryptographicException()); }
public static unsafe void Decrypt( SafeKeyHandle keyHandle, byte[] nonce, byte[] associatedData, byte[] ciphertext, byte[] tag, byte[] plaintext, bool clearPlaintextOnFailure) { fixed(byte *plaintextBytes = plaintext) fixed(byte *nonceBytes = nonce) fixed(byte *ciphertextBytes = ciphertext) fixed(byte *tagBytes = tag) fixed(byte *associatedDataBytes = associatedData) { BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.Create(); authInfo.pbNonce = nonceBytes; authInfo.cbNonce = nonce.Length; authInfo.pbTag = tagBytes; authInfo.cbTag = tag.Length; authInfo.pbAuthData = associatedDataBytes; if (associatedData == null) { authInfo.cbAuthData = 0; } else { authInfo.cbAuthData = associatedData.Length; } NTSTATUS ntStatus = Interop.BCrypt.BCryptDecrypt( keyHandle, ciphertextBytes, ciphertext.Length, new IntPtr(&authInfo), null, 0, plaintextBytes, plaintext.Length, out int plaintextBytesWritten, 0); Debug.Assert(ciphertext.Length == plaintextBytesWritten); switch (ntStatus) { case NTSTATUS.STATUS_SUCCESS: return; case NTSTATUS.STATUS_AUTH_TAG_MISMATCH: if (clearPlaintextOnFailure) { CryptographicOperations.ZeroMemory(plaintext); } throw LogHelper.LogExceptionMessage(new CryptographicException(LogHelper.FormatInvariant(LogMessages.IDX10714))); default: throw LogHelper.LogExceptionMessage(Interop.BCrypt.CreateCryptographicException(ntStatus)); } } }
/// <param name="ntstatus"></param> /// <returns></returns> internal static CryptographicException CreateCryptographicException(NTSTATUS ntstatus) { return(CreateCryptographicException((int)ntstatus)); }
static void Main(string[] args) { // NtOpenProcess IntPtr stub = Generic.GetSyscallStub("NtOpenProcess"); NtOpenProcess ntOpenProcess = (NtOpenProcess)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtOpenProcess)); IntPtr hProcess = IntPtr.Zero; OBJECT_ATTRIBUTES oa = new OBJECT_ATTRIBUTES(); CLIENT_ID ci = new CLIENT_ID { UniqueProcess = (IntPtr)uint.Parse(args[0]) }; NTSTATUS result = ntOpenProcess( ref hProcess, 0x001F0FFF, ref oa, ref ci); // NtAllocateVirtualMemory stub = Generic.GetSyscallStub("NtAllocateVirtualMemory"); NtAllocateVirtualMemory ntAllocateVirtualMemory = (NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtAllocateVirtualMemory)); IntPtr baseAddress = IntPtr.Zero; IntPtr regionSize = (IntPtr)_shellcode.Length; result = ntAllocateVirtualMemory( hProcess, ref baseAddress, IntPtr.Zero, ref regionSize, 0x1000 | 0x2000, 0x04); // NtWriteVirtualMemory stub = Generic.GetSyscallStub("NtWriteVirtualMemory"); NtWriteVirtualMemory ntWriteVirtualMemory = (NtWriteVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtWriteVirtualMemory)); var buffer = Marshal.AllocHGlobal(_shellcode.Length); Marshal.Copy(_shellcode, 0, buffer, _shellcode.Length); uint bytesWritten = 0; result = ntWriteVirtualMemory( hProcess, baseAddress, buffer, (uint)_shellcode.Length, ref bytesWritten); // NtProtectVirtualMemory stub = Generic.GetSyscallStub("NtProtectVirtualMemory"); NtProtectVirtualMemory ntProtectVirtualMemory = (NtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtProtectVirtualMemory)); uint oldProtect = 0; result = ntProtectVirtualMemory( hProcess, ref baseAddress, ref regionSize, 0x20, ref oldProtect); // NtCreateThreadEx stub = Generic.GetSyscallStub("NtCreateThreadEx"); NtCreateThreadEx ntCreateThreadEx = (NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtCreateThreadEx)); IntPtr hThread = IntPtr.Zero; result = ntCreateThreadEx( out hThread, ACCESS_MASK.MAXIMUM_ALLOWED, IntPtr.Zero, hProcess, baseAddress, IntPtr.Zero, false, 0, 0, 0, IntPtr.Zero); }
public static bool IsInformation(this NTSTATUS status) { return(status >= (NTSTATUS)0x40000000 && status <= (NTSTATUS)0x7FFFFFFF); }
public static bool IsSuccess(this NTSTATUS status) { return((status >= 0 && status <= (NTSTATUS)0x3FFFFFFF) || IsInformation(status)); }
public static bool IsError(this NTSTATUS status) { return(status >= (NTSTATUS)0xC0000000 && status <= (NTSTATUS)0xFFFFFFFF); }
public static bool IsWarning(this NTSTATUS status) { return(status >= (NTSTATUS)0x80000000 && status <= (NTSTATUS)0xBFFFFFFF); }
public static extern uint LsaNtStatusToWinError(NTSTATUS Status);
public static WindowsError NtStatusToWinError(NTSTATUS status) { return((WindowsError)Direct.LsaNtStatusToWinError(status)); }
public void ToHResult_FromNTStatus() { NTSTATUS duplicate = NTSTATUS.Code.STATUS_DUPLICATE_OBJECTID; Assert.Equal(0xD000022A, duplicate.ToHResult()); }
public static IntPtr GetSystemInformation(SYSTEM_INFORMATION_CLASS infoClass, out NTSTATUS result, uint infoLength = 0) { if (infoLength == 0) { infoLength = 0x10000; } IntPtr infoPtr = Marshal.AllocHGlobal((int)infoLength); int tries = 0; while (true) { result = NtQuerySystemInformation(infoClass, infoPtr, infoLength, out infoLength); if (result == NTSTATUS.SUCCESS) { return(infoPtr); } Marshal.FreeHGlobal(infoPtr); //free pointer when not Successful if (result != NTSTATUS.INFO_LENGTH_MISMATCH && result != NTSTATUS.BUFFER_OVERFLOW && result != NTSTATUS.BUFFER_TOO_SMALL) { return(IntPtr.Zero); } else if (++tries > 5) { return(IntPtr.Zero); } else { infoPtr = Marshal.AllocHGlobal((int)infoLength); } } }
/// <summary> /// Initializes a new instance of the <see cref="NTStatusException"/> class. /// </summary> /// <param name="statusCode">The status code identifying the error.</param> public NTStatusException(NTSTATUS statusCode) : this(statusCode, null, null) { }
public static extern Win32ErrorCode LsaNtStatusToWinError(NTSTATUS Status);
/// <summary> /// Initializes a new instance of the <see cref="NTStatusException"/> class. /// </summary> /// <param name="statusCode">The status code identifying the error.</param> /// <param name="message">The exception message (which may be null to use the default).</param> public NTStatusException(NTSTATUS statusCode, string message) : this(statusCode, message, null) { }
public DriveLockedException(NTSTATUS status) : base(status) { }
/// <summary> /// Initializes a new instance of the <see cref="NTStatusException"/> class. /// </summary> /// <param name="statusCode">The status code identifying the error.</param> /// <param name="message">The exception message (which may be null to use the default).</param> /// <param name="inner">The inner exception.</param> public NTStatusException(NTSTATUS statusCode, string message, Exception inner) : base(message ?? GetMessage(statusCode), inner) { this.NativeErrorCode = statusCode; }
private static Exception CreateCryptographicException(NTSTATUS ntStatus) { int hr = ((int)ntStatus) | 0x01000000; return(new CryptographicException(hr)); }
private static string GetSeverityString(NTSTATUS status) { switch (status.Severity) { case NTSTATUS.SeverityCode.STATUS_SEVERITY_SUCCESS: return "success"; case NTSTATUS.SeverityCode.STATUS_SEVERITY_INFORMATIONAL: return "information"; case NTSTATUS.SeverityCode.STATUS_SEVERITY_WARNING: return "warning"; case NTSTATUS.SeverityCode.STATUS_SEVERITY_ERROR: return "error"; default: return string.Empty; } }
/// <summary> /// Note: For testability, this function should be called through <see cref="IFileSystem"/>. /// </summary> public static unsafe List <DirectoryEntry> GetDirectoryEntries(string path) { var directoryEntries = new List <DirectoryEntry>(); // Open the file with the special FILE_LIST_DIRECTORY access to enable reading // the contents of the directory file (i.e. the list of directory entries). // Note that the FILE_FLAG_BACKUP_SEMANTICS is also important to ensure this // call succeeds. var fileHandle = NativeMethods.CreateFile(path, NativeAccessFlags.FILE_LIST_DIRECTORY, FileShare.Read | FileShare.Write | FileShare.Delete, IntPtr.Zero, FileMode.Open, NativeMethods.FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (fileHandle.IsInvalid) { var lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != (int)Win32Errors.ERROR_FILE_NOT_FOUND && lastWin32Error != (int)Win32Errors.ERROR_PATH_NOT_FOUND && lastWin32Error != (int)Win32Errors.ERROR_ACCESS_DENIED) { throw new LastWin32ErrorException(lastWin32Error, string.Format("Error enumerating files at \"{0}\".", path)); } // Skip this directory return(directoryEntries); } using (fileHandle) { // 8KB is large enough to hold about 80 entries of average size (the size depends on the // length of the filename), which is a reasonable compromise in terms of stack usages // vs # of calls to the API. const int bufferSize = 8192; byte * bufferAddress = stackalloc byte[bufferSize]; // Invoke NtQueryDirectoryFile to fill the initial buffer NTSTATUS status = InvokeNtQueryDirectoryFile(fileHandle, bufferAddress, bufferSize); if (!NativeMethods.NT_SUCCESS(status)) { // On the first invokcation, NtQueryDirectoryFile returns STATUS_INVALID_PARAMETER when // asked to enumerate an invalid directory (ie it is a file // instead of a directory). Verify that is the actual cause // of the error. if (status == NTSTATUS.STATUS_INVALID_PARAMETER) { FileAttributes attributes = NativeMethods.GetFileAttributes(path); if ((attributes & FileAttributes.Directory) == 0) { status = NTSTATUS.STATUS_NOT_A_DIRECTORY; } } throw ThrowInvokeNtQueryDirectoryFileError(path, status); } // Process entries from the buffer, and invoke NtQueryDirectoryFile as long as there are // more entries to enumerate. while (true) { ProcessFileInformationBuffer(directoryEntries, bufferAddress, bufferSize); status = InvokeNtQueryDirectoryFile(fileHandle, bufferAddress, bufferSize); if (!NativeMethods.NT_SUCCESS(status)) { if (status == NTSTATUS.STATUS_NO_MORE_FILES) { // Success, enumeration finished break; } else { throw ThrowInvokeNtQueryDirectoryFileError(path, status); } } } } // using fileHandle return(directoryEntries); }
public static HRESULT HRESULT_FROM_NT(NTSTATUS status) { return((HRESULT)((int)status | FACILITY_NT_BIT)); }
private static Exception CreateCryptographicException(NTSTATUS ntStatus) { int hr = ((int)ntStatus) | 0x01000000; return new CryptographicException(hr); }
public void ConvertNtStatus(NTSTATUS status, WindowsError expected) { ErrorMethods.NtStatusToWinError(status).Should().Be(expected); }