private static void Iterate(int indent, NtObjectBase item)
        {
            void Write(string str)
            {
                for (int i = 0; i < indent; i++)
                {
                    Console.Write(' ');
                }

                Console.WriteLine(str);
            }

            Write($"{item.Type}: {item.FullName}");

            if (item is PhysicalDriveIdentifier physicalDriveIdentifier)
            {
                Write($"  PhysicalDrive{physicalDriveIdentifier.Identifier} {physicalDriveIdentifier.FileAddress}");
            }
            if (item is HarddiskVolumeIdentifier volumeIdentifier)
            {
                Write($"  Volume{volumeIdentifier.Identifier} {volumeIdentifier.FileAddress}");
            }
            if (item is HarddiskPartitionIdentifier partitionIdentifier)
            {
                Write($"  Partition{partitionIdentifier.Partition}, PhysicalDrive{partitionIdentifier.Harddisk} {partitionIdentifier.FileAddress}");
            }

            if (item.IsSymbolicLink)
            {
                if (item.TryGetSymbolicLinkTarget(out string target))
                {
                    Write($"  => {target}");
                }
                else
                {
                    Write("  => UNABLE TO LOCATE");
                }
            }

            if (item is NtDirectory asDir)
            {
                try
                {
                    foreach (NtObjectBase @base in asDir.ListDirectory())
                    {
                        Iterate(indent + 2, @base);
                    }
                }
                catch (NtObjectException e)
                {
                    Write("  UNABLE TO ENUMERATE DIRECTORY, " + e.StatusCode);
                }

                Console.WriteLine();
            }
        }
        internal NtObjectBase ConvertToSpecificType(NtObjectBase @object)
        {
            if (@object is NtDirectory)
            {
                return(@object);
            }

            Match match;

            if (@object.Type == WellKnownType.SymbolicLink)
            {
                if ((match = PhysicalDriveRegex.Match(@object.Name)).Success)
                {
                    int id = int.Parse(match.Groups[1].Value);
                    return(new PhysicalDriveIdentifier(@object.TypeName, @object.Parent, @object.Name, id));
                }

                if ((match = PartitionRegex.Match(@object.Name)).Success)
                {
                    int partitionIdx = int.Parse(match.Groups[1].Value);

                    match = HarddiskRegex.Match(@object.Parent);
                    if (match.Success)
                    {
                        int harddiskIdx = int.Parse(match.Groups[1].Value);
                        return(new HarddiskPartitionIdentifier(@object.TypeName, @object.Parent, @object.Name, harddiskIdx, partitionIdx));
                    }
                }

                if ((match = HarddiskPartitionRegex.Match(@object.Name)).Success)
                {
                    int harddiskIdx  = int.Parse(match.Groups[1].Value);
                    int partitionIdx = int.Parse(match.Groups[2].Value);

                    return(new HarddiskPartitionIdentifier(@object.TypeName, @object.Parent, @object.Name, harddiskIdx, partitionIdx));
                }

                if ((match = DriveLetterRegex.Match(@object.Name)).Success)
                {
                    string letter = match.Groups[1].Value;

                    return(new DriveLetterIdentifier(@object.TypeName, @object.Parent, @object.Name, letter));
                }
            }

            if (@object.Type == WellKnownType.Device && (match = HarddiskVolumeRegex.Match(@object.Name)).Success)
            {
                int id = int.Parse(match.Groups[1].Value);
                return(new HarddiskVolumeIdentifier(@object.TypeName, @object.Parent, @object.Name, id));
            }

            return(@object);
        }
Example #3
0
        public bool TryGetVolume(out HarddiskVolumeIdentifier volumeIdentifier)
        {
            volumeIdentifier = null;

            if (!TryGetSymbolicLinkTarget(out string target))
            {
                return(false);
            }

            NtObjectBase obj = NtObjects.Instance.GetSingleObject(target);

            volumeIdentifier = obj as HarddiskVolumeIdentifier;

            return(volumeIdentifier != null);
        }
        public IEnumerable <NtObjectBase> ListDirectory(string path, bool recurse = false, WellKnownType filterType = WellKnownType.Unknown)
        {
            OBJECT_ATTRIBUTES objectAttributes = new OBJECT_ATTRIBUTES(path, 0);
            NtStatus          retVal           = Win32.NtOpenDirectoryObject(out var directoryHandle, DirectoryAccessEnum.DIRECTORY_QUERY, ref objectAttributes);

            if (retVal != NtStatus.STATUS_SUCCESS)
            {
                ErrorHelper.Throw(retVal, $"NtOpenDirectoryObject, parentPath: {path}");
            }

            uint singleDirInfo = (uint)Marshal.SizeOf <OBJECT_DIRECTORY_INFORMATION>();

            using (directoryHandle)
                using (UnmanagedMemory mem = new UnmanagedMemory((int)(256 * singleDirInfo)))
                {
                    bool     restart = true;
                    NtStatus status;
                    uint     context = 0;

                    do
                    {
                        mem.Clear();

                        status = Win32.NtQueryDirectoryObject(directoryHandle, mem.Handle, mem.Bytes, false, restart,
                                                              ref context, out _);
                        restart = false;

                        IntPtr ptr = mem.Handle;

                        while (true)
                        {
                            OBJECT_DIRECTORY_INFORMATION dir = Marshal.PtrToStructure <OBJECT_DIRECTORY_INFORMATION>(ptr);
                            ptr = new IntPtr(ptr.ToInt64() + (int)singleDirInfo);

                            if (dir.Name.Length == 0)
                            {
                                break;
                            }

                            string        typeName      = dir.TypeName.ToString();
                            string        name          = dir.Name.ToString();
                            WellKnownType wellKnownType = StaticStrings.ToWellKnownType(typeName);

                            if (filterType != WellKnownType.Unknown && filterType != wellKnownType)
                            {
                                continue;
                            }

                            if (wellKnownType == WellKnownType.Directory)
                            {
                                NtDirectory directory = new NtDirectory(typeName, path, name);
                                yield return(directory);

                                if (recurse)
                                {
                                    foreach (NtObjectBase subObject in ListDirectory(directory.FullName, true, filterType))
                                    {
                                        yield return(subObject);
                                    }
                                }

                                continue;
                            }

                            NtObjectBase result = new NtObjectBase(typeName, path, name);

                            result = ConvertToSpecificType(result);

                            yield return(result);
                        }
                    } while (status == NtStatus.STATUS_MORE_ENTRIES);
                }
        }
        public static void Main(string[] args)
        {
            //var pp = NtObjects.Instance.GetSingleObject(@"\Device\Csc");
            //var pp1 = pp.GetSymbolicLinkObject();

            var objects = ListAll()
                          //.Where(s => s.FullName.StartsWith(@"\Device"))
                          .OrderBy(s => s.FullName)
                          .Select(s =>
            {
                Dictionary <string, object> item = new Dictionary <string, object>();

                foreach (PropertyInfo property in s.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    if (!property.CanRead)
                    {
                        continue;
                    }

                    object value = property.GetValue(s);
                    if (value is bool bl && !bl)
                    {
                        continue;
                    }

                    item[property.Name] = value;
                }

                if (s is NtDirectory dir)
                {
                    try
                    {
                        item["Children"] = dir.ListDirectory().Select(x => x.FullName).ToArray();
                    }
                    catch (Exception)
                    {
                    }
                }

                if (s.GetType() != typeof(NtObjectBase))
                {
                    item["Interpreted"] = s.GetType().Name;
                }

                if (s.IsSymbolicLink)
                {
                    List <Dictionary <string, object> > symlinks = new List <Dictionary <string, object> >();

                    item["IsSymbolicLink"]    = true;
                    item["SymbolicLinkChain"] = symlinks;

                    NtObjectBase linkItem = s;
                    while (linkItem.IsSymbolicLink && linkItem.TryGetSymbolicLinkObject(out NtObjectBase target))
                    {
                        symlinks.Add(new Dictionary <string, object>
                        {
                            { "SymlinkTarget", target.FullName },
                            { "SymlinkTargetType", target.Type }
                        });

                        linkItem = target;
                    }
                }

                return(item);
            });

            string json = JsonConvert.SerializeObject(objects, Formatting.Indented, new StringEnumConverter());

            Console.WriteLine(json);
        }