コード例 #1
0
        /// <summary>
        /// Tries the get object name from the wrapped handle.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="timeout">The timeout.</param>
        /// <returns></returns>
        /// <remarks>
        /// Since the call to NtQueryObject might hang infinitely, this method uses a separate thread with a timeout to call the API
        /// If the timeout expires the status 'NT_STATUS.STATUS_TIMEOUT' will be returned.
        /// </remarks>
        public NT_STATUS TryGetObjectNameFromHandle(out string fileName, TimeSpan timeout)
        {
            string    name   = null;
            NT_STATUS result = NT_STATUS.STATUS_SUCCESS;

            AutoResetEvent signal       = new AutoResetEvent(false);
            Thread         workerThread = null;

            ThreadPool.QueueUserWorkItem((o) =>
            {
                workerThread = Thread.CurrentThread;
                result       = TryGetObjectNameFromHandle(out name);
                signal.Set();
            });

            bool waitres = signal.WaitOne(timeout);

            fileName = name;
            if (workerThread != null && workerThread.IsAlive && waitres == false)
            {
                workerThread.Abort();
                return(NT_STATUS.STATUS_TIMEOUT);
            }
            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Enumerates all kernel object type-infos available in the operating system.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NtStatusException">NtQueryObject failed</exception>
        public static IEnumerable <ObjectTypeInfo> EnumerateAllObjectTypes()
        {
            int    nLength            = 0x1000;
            IntPtr ipBufferObjectType = IntPtr.Zero;

            ipBufferObjectType = Marshal.AllocHGlobal(nLength);
            while (true)
            {
                NT_STATUS res1 = NativeMethods.NtQueryObject(IntPtr.Zero, OBJECT_INFORMATION_CLASS.ObjectAllTypesInformation, ipBufferObjectType, nLength, out nLength);
                if (res1 == NT_STATUS.STATUS_SUCCESS)
                {
                    break;
                }
                if (res1 != NT_STATUS.STATUS_INFO_LENGTH_MISMATCH)
                {
                    throw new NtStatusException("NtQueryObject failed", res1);
                }
                Marshal.FreeHGlobal(ipBufferObjectType);
                ipBufferObjectType = Marshal.AllocHGlobal(nLength);
            }

            int    typeInfoCount = Marshal.ReadInt32(ipBufferObjectType);          // actually uint! C++: ULONG NumberOfTypes;
            IntPtr ipTypeInfo    = IntPtr.Add(ipBufferObjectType, IntPtr.Size);    // the int that we just read + padding (only in 64bit!)

            for (int nIndex = 0; nIndex < typeInfoCount; nIndex++)
            {
                OBJECT_TYPE_INFORMATION otiTemp = Marshal.PtrToStructure <OBJECT_TYPE_INFORMATION>(ipTypeInfo);
                string strType = Helpers.MarshalUnicodeString(otiTemp.TypeName);
                yield return(new ObjectTypeInfo(otiTemp, strType));

                int currentSize  = Marshal.SizeOf <OBJECT_TYPE_INFORMATION>() + otiTemp.TypeName.MaximumLength;
                int offsetToNext = Helpers.RoundUp(currentSize, IntPtr.Size);                 // padding depends on 32/64bit
                ipTypeInfo = IntPtr.Add(ipTypeInfo, offsetToNext);
            }
        }
コード例 #3
0
        /// <summary>
        /// Gets the type-info for the handle.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NtStatusException">
        /// NtQueryObject failed
        /// </exception>
        public ObjectTypeInfo GetHandleType()
        {
            int       length;
            NT_STATUS res1 = NativeMethods.NtQueryObject(_duplicatedObjectHandle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, IntPtr.Zero, 0, out length);

            if (res1 != NT_STATUS.STATUS_SUCCESS && res1 != NT_STATUS.STATUS_INFO_LENGTH_MISMATCH)
            {
                throw new NtStatusException("NtQueryObject call1 failed", res1);
            }
            IntPtr ptr = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    ptr = Marshal.AllocHGlobal(length);
                }
                NT_STATUS res2 = NativeMethods.NtQueryObject(_duplicatedObjectHandle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, ptr, length, out length);
                if (res2 != NT_STATUS.STATUS_SUCCESS)
                {
                    throw new NtStatusException("NtQueryObject call2 failed", res2);
                }
                OBJECT_TYPE_INFORMATION objectType = Marshal.PtrToStructure <OBJECT_TYPE_INFORMATION>(ptr);
                string typeName = Helpers.MarshalUnicodeString(objectType.TypeName);
                return(new ObjectTypeInfo(objectType, typeName));
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }
コード例 #4
0
        public RowViewModel(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX info)
        {
            _info = info;

            using (DuplicatedObjectHandle dhandle = new DuplicatedObjectHandle(_info.HandleValue, _info.UniqueProcessId))
            {
                if (dhandle.ErrorMessage != null)
                {
                    _name = "<" + dhandle.ErrorMessage + ">";
                    return;
                }
                string    name;
                NT_STATUS status = dhandle.TryGetObjectNameFromHandle(out name, timeout);
                if (status != NT_STATUS.STATUS_SUCCESS)
                {
                    _name = "<" + status.ToString() + ">";
                    return;
                }
                _name = name;
            }

            if (_name != null && !_name.StartsWith("<"))
            {
                if (this.ObjectTypeString == "File")
                {
                    _prettyName = DevicePathConverter.ConvertDevicePathToDosPath(_name);
                }
                if (this.ObjectTypeString == "Key")
                {
                    _prettyName = _name.Replace(@"\REGISTRY\MACHINE", @"HKLM").Replace(@"\REGISTRY\USER\" + cusid, @"HKCU").Replace(@"\REGISTRY\USER", @"HKU");                    // todo: do not use replace, use code similar to DevicePathConverter.IsMatch
                }
            }
        }
コード例 #5
0
        public override NT_STATUS SetAttributes(UserContext UserContext, FileContext FileObject, DirectoryContext data)
        {
            NT_STATUS error = NT_STATUS.OK;

            //FIXME: attributes?  what attributes? The attributes of the file, e.g. archive, hidden ....
            return(error);
        }
コード例 #6
0
        public override NT_STATUS Write(UserContext UserContext, FileContext FileObject, long Offset, ref int Count, ref byte[] Buffer, int Start)
        {
            // All locking issies are handled in the calling class, expect if other application access the files from outside
            // WinFUSE

            // It's possible to write all data to a cache and write it through to the final media after a flush or close. But this
            // write through should not last longer than 20 secounds
            NT_STATUS error = NT_STATUS.OK;

            MyFileContext HE = (MyFileContext)FileObject;

            if (HE.IsDirectory || HE.FS == null)
            {
                Debug.WriteLine("Warning->Cannot write to Directory.");
                Count = 0;
                return(NT_STATUS.INVALID_HANDLE);                                                // ERROR_INVALID_HANDLE
            }

            if (!HE.FS.CanWrite && !HE.FS.CanSeek)
            {
                Debug.WriteLine("Warning->The file can not be written.");
                Count = 0;
                return(NT_STATUS.INVALID_PARAMETER);                                             // ERROR_INVALID_PARAMETER;
            }

            if (Count > 0x0FFFFFFF)
            {
                Debug.WriteLine("Warning->Number of bytes to write is too large.");
                Count = 0;
                return(NT_STATUS.INVALID_PARAMETER);                                             //ERROR_INVALID_PARAMETER
            }

            long NewOffset;

            try
            {
                NewOffset = HE.FS.Seek(Offset, System.IO.SeekOrigin.Begin);
                if (NewOffset != Offset)
                {
                    Debug.WriteLine("Warning->The indicated position can not be written.");
                    Count = 0;
                    return(NT_STATUS.INVALID_PARAMETER);                 //132 ERROR_SEEK_ON_DEVICE
                }

                BinaryWriter Writer = new BinaryWriter(HE.FS);

                Writer.Write(Buffer, Start, Count);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Warning->Exception in Write: " + ex.Message);
                Count = 0;
                //error = 29;					// ERROR_WRITE_FAULT
                error = (NT_STATUS)Marshal.GetHRForException(ex);
            }
            return(error);
        }
コード例 #7
0
ファイル: ProcessHelpers.cs プロジェクト: CloudIDEaaS/hydra
        private static bool GetFileNameFromHandle(IntPtr handle, out string fileName)
        {
            IntPtr ptr = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();

            try
            {
                int length = 0x200;  // 512 bytes
                RuntimeHelpers.PrepareConstrainedRegions();

                try { }
                finally
                {
                    // CER guarantees the assignment of the allocated
                    // memory address to ptr, if an ansynchronous exception
                    // occurs.
                    ptr = Marshal.AllocHGlobal(length);
                }

                NT_STATUS ret = NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);

                if (ret == NT_STATUS.STATUS_BUFFER_OVERFLOW)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();

                    try { }
                    finally
                    {
                        // CER guarantees that the previous allocation is freed,
                        // and that the newly allocated memory address is
                        // assigned to ptr if an asynchronous exception occurs.
                        Marshal.FreeHGlobal(ptr);
                        ptr = Marshal.AllocHGlobal(length);
                    }

                    ret = NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);
                }

                if (ret == NT_STATUS.STATUS_SUCCESS)
                {
                    fileName = Marshal.PtrToStringUni((IntPtr)((int)ptr + 8), (length - 9) / 2);
                    return(fileName.Length != 0);
                }
            }
            finally
            {
                // CER guarantees that the allocated memory is freed,
                // if an asynchronous exception occurs.
                Marshal.FreeHGlobal(ptr);
            }

            fileName = string.Empty;
            return(false);
        }
コード例 #8
0
        public override NT_STATUS Read(UserContext UserContext, FileContext FileObject, long Offset, ref int Count, ref byte[] Buffer, int Start)
        {
            // All locking issues are handled in the calling class, the only read collision that can occure are when other
            // application access the same file
            NT_STATUS error = NT_STATUS.OK;

            MyFileContext HE = (MyFileContext)FileObject;

            if (HE.IsDirectory || HE.FS == null)
            {
                Debug.WriteLine("Warning->Can not read from a Directory.");
                Count = 0;
                return(NT_STATUS.INVALID_HANDLE);                                                // ERROR_INVALID_HANDLE
            }

            if (!HE.FS.CanRead && !HE.FS.CanSeek)
            {
                Debug.WriteLine("Warning->Can not Read or Seek the file.");
                Count = 0;
                return(NT_STATUS.INVALID_PARAMETER);                                             // ERROR_INVALID_PARAMETER;
            }

            if (Count > 0x0FFFFFFF)
            {
                Debug.WriteLine("Warning->Number of bytes to read is too large.");
                Count = 0;
                return(NT_STATUS.INVALID_PARAMETER);                                             //ERROR_INVALID_PARAMETER
            }

            long NewOffset;

            try
            {
                NewOffset = HE.FS.Seek(Offset, System.IO.SeekOrigin.Begin);
                if (NewOffset != Offset)
                {
                    Debug.WriteLine("Warning->The indicated position can not be read");
                    Count = 0;
                    return(NT_STATUS.INVALID_PARAMETER);                 // 132 = ERROR_SEEK_ON_DEVICE
                }

                BinaryReader Reader = new BinaryReader(HE.FS);

                Count = Reader.Read(Buffer, Start, Count);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Warning->Exception in Read: " + ex.Message);
                Count = 0;
                //error = 30;					// ERROR_READ_FAULT
                error = (NT_STATUS)Marshal.GetHRForException(ex);
            }
            return(error);
        }
コード例 #9
0
        /// <summary>
        /// Gets the object name from the wrapped handle.
        /// </summary>
        /// <returns>
        /// For object-type 'File': the device path (serial-ports also have the type 'file') - starts always with '\Device\', if it doesn't the handle is invalid.
        /// For object-type 'Key': the registry Path - starts always with '\REGISTRY\', if it doesn't the handle is invalid.
        /// </returns>
        /// <exception cref="System.Exception"></exception>
        public string GetObjectNameFromHandle()
        {
            string    name;
            NT_STATUS status = TryGetObjectNameFromHandle(out name);

            if (status != NT_STATUS.STATUS_SUCCESS)
            {
                throw new NtStatusException("TryGetObjectNameFromHandle failed", status);
            }
            return(name);
        }
コード例 #10
0
        public static SystemHandleEntry[] GetSystemHandles()
        {
            // Attempt to retrieve the handle information
            int    length = 0x10000;
            IntPtr ptr    = IntPtr.Zero;

            try
            {
                while (true)
                {
                    ptr = Marshal.AllocHGlobal(length);
                    int       wantedLength;
                    NT_STATUS result = NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, ptr, length, out wantedLength);
                    if (result == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH)
                    {
                        length = Math.Max(length, wantedLength);
                        Marshal.FreeHGlobal(ptr);
                        ptr = IntPtr.Zero;
                    }
                    else if (result == NT_STATUS.STATUS_SUCCESS)
                    {
                        break;
                    }
                    else
                    {
                        throw new Exception("Failed to retrieve system handle information.", new System.ComponentModel.Win32Exception());
                    }
                }

                int handleCount = IntPtr.Size == 4 ? Marshal.ReadInt32(ptr) : (int)Marshal.ReadInt64(ptr);
                int offset      = IntPtr.Size;
                int size        = Marshal.SizeOf(typeof(SystemHandleEntry));

                SystemHandleEntry[] systemHandleEntries = new SystemHandleEntry[handleCount];
                for (int i = 0; i < handleCount; i++)
                {
                    SystemHandleEntry struc = (SystemHandleEntry)Marshal.PtrToStructure((IntPtr)((long)ptr + offset), typeof(SystemHandleEntry));
                    systemHandleEntries[i] = struc;

                    offset += size;
                }

                return(systemHandleEntries);
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }
コード例 #11
0
        public override NT_STATUS Rename(UserContext UserContext, string OldName, string NewName)
        {
            NT_STATUS error = NT_STATUS.OK;

            if (phone.Exists(root + OldName) && phone.IsDirectory(root + OldName))
            {
                // We are in Directory case
                if (phone.Exists(root + NewName))
                {
                    return(NT_STATUS.OBJECT_NAME_COLLISION);
                }
                try
                {
                    //FIXME: We don't have a way to move directories
                    //DirectoryBroker.Move(phone,root + OldName, root + NewName);
                    phone.Rename(root + OldName, root + NewName);
                    return(NT_STATUS.OBJECT_NAME_COLLISION);
                }
                catch (Exception e)
                {
                    Trace.WriteLine("Warning->Exception when renaming directory: " + e.Message);
                    error = (NT_STATUS)Marshal.GetHRForException(e);
                    //error = 3;					// ListingError
                }
            }
            else
            {   // We are in File case
                if (!phone.Exists(root + OldName))
                {
                    return(NT_STATUS.OBJECT_NAME_NOT_FOUND);             // Orginalname nicht da
                }
                if (phone.Exists(root + NewName))
                {
                    return(NT_STATUS.OBJECT_NAME_COLLISION);
                }
                try
                {
                    phone.Rename(root + OldName, root + NewName);
                }
                catch (Exception e)
                {
                    Trace.WriteLine("Warning->Exception when renaming file: " + e.Message);
                    error = (NT_STATUS)Marshal.GetHRForException(e);
                }
            }
            return(error);
        }
コード例 #12
0
        //Implements the search for listings by means of identification FindFirst and FindNext
        public override NT_STATUS ReadDirectory(UserContext UserContext, FileContext FileObject)
        {
            NT_STATUS error = NT_STATUS.OK;

            MyFileContext HE = (MyFileContext)FileObject;

            if (!HE.IsDirectory)
            {
                Debug.WriteLine("Warning->Handle is not a directory, can not get a listing");
                return(NT_STATUS.INVALID_HANDLE);
            }

            if (!phone.Exists(root + HE.Name) || !phone.IsDirectory(root + HE.Name))
            {
                return(NT_STATUS.OBJECT_PATH_NOT_FOUND);   // Directroy not found, should never happen
            }
            HE.Items.Add(new DirectoryContext(".", FileAttributes.Directory));
            HE.Items.Add(new DirectoryContext("..", FileAttributes.Directory));

            DirectoryContext Item = null;

            foreach (string DirName in phone.GetDirectories(root + HE.Name))
            {
                error = GetAttributes(UserContext, root + HE.Name + DirName, out Item);
                if (error != 0)
                {
                    Trace.WriteLine("Warning->Error: '" + error + "' during listing directories: " + HE.Name + DirName);
                }
                HE.Items.Add(Item);
            }

            foreach (string FileName in phone.GetFiles(root + HE.Name))
            {
                error = GetAttributes(UserContext, root + HE.Name + FileName, out Item);
                if (error != 0)
                {
                    Trace.WriteLine("Warning->Error: '" + error + "' during listing files: " + FileName);
                }
                else
                {
                    HE.Items.Add(Item);
                }
            }

            return(NT_STATUS.OK);
        }
コード例 #13
0
        public override NT_STATUS Create(UserContext UserContext, string Name, SearchFlag SearchFlags, FileMode Mode, FileAccess Access, FileShare Share, FileAttributes Attributes, out FileContext fileContext)
        {
            lock (this)
            {
                FSItem item = _topItem.GetItem(Name);

                if (item != null)
                {
                    MTPFileContext mtpFileContext;
                    NT_STATUS      status = item.Create(UserContext, Name, SearchFlags, Mode, Access, Share, Attributes, out mtpFileContext);
                    fileContext = mtpFileContext;
                    return(status);
                }

                fileContext = null;
                return(NT_STATUS.NO_SUCH_FILE);
            }
        }
コード例 #14
0
        /// <summary>
        /// Tries the get object name from the wrapped handle.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        /// <remarks>
        /// This method might hang infinitely in NtQueryObject, so it is safer to use the overload with the timeout parameter.
        /// The hangs have been observed for handles with GrantedAccess == 0x00120189 and 0x0012019f all of them were for type 'file'
        /// and process explorer showed that the handle names all were '\Device\NamedPipe'
        /// This was tested on win10 64bit 1511 and 1607.
        /// The problem seems only to appear when 'Prefer 32bit' is disabled
        /// </remarks>
        public NT_STATUS TryGetObjectNameFromHandle(out string name)
        {
            name = null;
            IntPtr ptr = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                int length = 0x200;                  // 512 bytes
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    // CER guarantees the assignment of the allocated memory address to ptr, if an asynchronous exception occurs.
                    ptr = Marshal.AllocHGlobal(length);
                }
                NT_STATUS ret = NativeMethods.NtQueryObject(_duplicatedObjectHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);
                if (ret == NT_STATUS.STATUS_BUFFER_OVERFLOW)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { }
                    finally
                    {
                        // CER guarantees that the previous allocation is freed, and that the newly allocated memory address is
                        // assigned to ptr if an asynchronous exception occurs.
                        Marshal.FreeHGlobal(ptr);
                        ptr = Marshal.AllocHGlobal(length);
                    }
                    ret = NativeMethods.NtQueryObject(_duplicatedObjectHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);
                }
                if (ret == NT_STATUS.STATUS_SUCCESS)
                {
                    OBJECT_NAME_INFORMATION nameInfo = Marshal.PtrToStructure <OBJECT_NAME_INFORMATION>(ptr);
                    name = Helpers.MarshalUnicodeString(nameInfo.Name);
                }
                return(ret);
            }
            finally
            {
                // CER guarantees that the allocated memory is freed, if an asynchronous exception occurs.
                Marshal.FreeHGlobal(ptr);
            }
        }
コード例 #15
0
        public override NT_STATUS Delete(UserContext UserContext, string FileName)
        {
            NT_STATUS error = NT_STATUS.OK;

            string OriginalName = root + FileName;

            Debug.WriteLine("Info->File '" + FileName + "' with full path '" + OriginalName + "' is being deleted.");

            try
            {
                if (!phone.Exists(OriginalName) || phone.IsDirectory(OriginalName))
                {
                    return(NT_STATUS.OBJECT_NAME_NOT_FOUND);
                }
                phone.DeleteFile(OriginalName);
            }
            catch (Exception e)
            {
                Trace.WriteLine("Warning->Exception in Delete:" + e.Message);
                error = (NT_STATUS)Marshal.GetHRForException(e);                                        // ERROR_READ_FAULT
            }

            return(error);
        }
コード例 #16
0
 static bool NT_SUCCESS(NT_STATUS status)
 {
     return(((uint)status & 0x80000000) == 0);
 }
コード例 #17
0
 /// <summary>
 /// Constructs a new NtStatusException.
 /// </summary>
 /// <param name="message">The exception message.</param>
 /// <param name="status">The value for the Status property.</param>
 /// <param name="innerException">The inner exception.</param>
 public NtStatusException(string message, NT_STATUS status, Exception innerException) : base(message, innerException)
 {
     this.status = status;
 }
コード例 #18
0
 /// <summary>
 /// Serialization constructor.
 /// </summary>
 protected NtStatusException(SerializationInfo info, StreamingContext context) : base(info, context)
 {
     this.status = (NT_STATUS)info.GetValue("Status", typeof(NT_STATUS));
 }
コード例 #19
0
        public static Dictionary <int, string> GetHandleNames(int targetPid)
        {
            Dictionary <int, string> fileHandles = new Dictionary <int, string>();

            int    length = 0x10000;
            IntPtr ptr    = IntPtr.Zero;

            try
            {
                while (true)
                {
                    ptr = Marshal.AllocHGlobal(length);
                    int wantedLength;

                    // query for system handles we can read
                    var result = Ntdll.NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, ptr, length, out wantedLength);
                    if (result == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH)
                    {
                        length = Math.Max(length, wantedLength);
                        Marshal.FreeHGlobal(ptr);
                        ptr = IntPtr.Zero;
                    }
                    else if (result == NT_STATUS.STATUS_SUCCESS)
                    {
                        break;
                    }
                    else
                    {
                        throw new Exception("Failed to retrieve system handle information.");
                    }
                }

                var offset = ptr.ToInt64();
                offset += IntPtr.Size;
                int size = Marshal.SizeOf(typeof(SYSTEM_HANDLE_INFORMATION));

                int handleCount = IntPtr.Size == 4 ? Marshal.ReadInt32(ptr) : (int)Marshal.ReadInt64(ptr);

                // open the target process for handle duplication
                IntPtr processHandle        = Kernel32.OpenProcess(ProcessAccessFlags.DuplicateHandle, true, (uint)targetPid);
                IntPtr currentProcessHandle = Kernel32.GetCurrentProcess();

                for (int i = 0; i < handleCount; i++)
                {
                    if (Marshal.ReadInt32((IntPtr)offset) == targetPid)
                    {
                        SYSTEM_HANDLE_INFORMATION info = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(new IntPtr(offset), typeof(SYSTEM_HANDLE_INFORMATION));

                        // actually duplicate the handle so we can get its name
                        int    dummy            = 0;
                        IntPtr duplicatedHandle = new IntPtr();
                        bool   success          = Kernel32.DuplicateHandle(processHandle, new IntPtr(info.HandleValue), currentProcessHandle, out duplicatedHandle, 0, false, DuplicateOptions.DUPLICATE_SAME_ACCESS);

                        // check if this handle is on disk (a file) so things don't hang
                        if (Kernel32.GetFileType(duplicatedHandle) == FileType.Disk)
                        {
                            if (success)
                            {
                                int    length2 = 0x200;
                                IntPtr buffer  = Marshal.AllocHGlobal(length2);

                                // use NtQueryObject so we can get this object's name
                                NT_STATUS status = Ntdll.NtQueryObject(duplicatedHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, buffer, length2, out dummy);

                                if (status == NT_STATUS.STATUS_SUCCESS)
                                {
                                    OBJECT_NAME_INFORMATION temp = (OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(buffer, typeof(OBJECT_NAME_INFORMATION));
                                    if (!String.IsNullOrEmpty(temp.Name.ToString()) && !String.IsNullOrEmpty(temp.Name.ToString().Trim()))
                                    {
                                        // only add the file/object to the results if it ends with our target file search pattern
                                        fileHandles.Add(info.HandleValue, temp.Name.ToString().Trim());
                                    }
                                }
                                else
                                {
                                    // Console.WriteLine("[X] NtQueryObject status: {0}", status);
                                }

                                Marshal.FreeHGlobal(buffer);
                            }
                        }
                        Kernel32.CloseHandle(duplicatedHandle);
                    }

                    offset += size;
                }

                Kernel32.CloseHandle(processHandle);
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }

            // convert all the paths to readable formats
            return(ConvertDevicePathsToDosPaths(fileHandles));
        }
コード例 #20
0
        private static bool GetFileNameOfLocalHandle(IntPtr handle, out string fileName)
        {
            if (handle.ToInt32() == 0)
            {
                throw new Exception("Handle is null");
            }

            IntPtr ptr = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                int length = 0x200;  // 512 bytes
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    // CER guarantees the assignment of the allocated
                    // memory address to ptr, if an ansynchronous exception
                    // occurs.
                    ptr = Marshal.AllocHGlobal(length);
                }
                NT_STATUS ret = NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);

                if (ret == NT_STATUS.STATUS_BUFFER_OVERFLOW)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { }
                    finally
                    {
                        // CER guarantees that the previous allocation is freed,
                        // and that the newly allocated memory address is
                        // assigned to ptr if an asynchronous exception occurs.
                        Marshal.FreeHGlobal(ptr);
                        ptr = Marshal.AllocHGlobal(length);
                    }
                    ret = NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);
                }
                if (ret == NT_STATUS.STATUS_SUCCESS)
                {
                    // fileName = Marshal.PtrToStringUni((IntPtr)((int)ptr + 16), (length - 9) / 2);
                    OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure <OBJECT_NAME_INFORMATION>(ptr);

                    if (objObjectName.Name.Buffer != IntPtr.Zero)
                    {
                        string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer);
                        fileName = GetRegularFileNameFromDevice(strObjectName);
                        //return strObjectName;
                    }
                    else
                    {
                        fileName = string.Empty;
                    }
                    return(fileName.Length != 0);
                }
            }
            finally
            {
                // CER guarantees that the allocated memory is freed,
                // if an asynchronous exception occurs.
                Marshal.FreeHGlobal(ptr);
            }

            fileName = string.Empty;
            return(false);
        }
コード例 #21
0
 /// <summary>
 /// Constructs a new NtStatusException.
 /// </summary>
 /// <param name="message">The exception message</param>
 /// <param name="status">The value for the Status property.</param>
 public NtStatusException(string message, NT_STATUS status) : base(message)
 {
     this.status = status;
 }