Esempio n. 1
0
        /*
         * parseLongFilename - Parses long file name of one or more entries with FileStream and first entry bytes
         */
        private string parseLongFilename(byte[] data, BufferedDiskReader disk)
        {
            string result = "";
            //Parse first entry bytes
            LongFilenameEntry entry = new LongFilenameEntry(data);

            //Add to result
            result += entry.FilenamePart;

            //Sequence number is first entry's sequence number XOR 0x40
            int sequenceNumber = entry.SequenceNumber ^ 0x40;

            //Iterate over following entries
            for (int i = 0; i < sequenceNumber - 1; i++)
            {
                //Read next entry
                disk.Read(data, 0, data.Length);

                //Parse entry bytes
                entry = new LongFilenameEntry(data);

                //Add to result - they are in reverse order
                result = entry.FilenamePart + result;
            }

            return(result);
        }
Esempio n. 2
0
        /*
         * ParseDirectoryEntries - Seeks disk to Directory Table start then begins recursive creation         *
         */
        public void ParseDirectoryEntries(BufferedDiskReader disk)
        {
            disk.SeekAbsolute((ulong)this.clusterBeginLBA * BootSector.BPB.BytesPerSector);

            int error = Marshal.GetLastWin32Error();

            byte[] data = new byte[32];
            disk.Read(data, 0, data.Length);

            rootDirectory = new DirectoryEntry(data, disk, this);
            if (!rootDirectory.IsVolumeID)
            {
                DirectoryEntry entry = rootDirectory;
                rootDirectory = new DirectoryEntry();
                rootDirectory.Children.Add(entry);
                disk.Read(data, 0, data.Length);
                entry = new DirectoryEntry(data, disk, this);
                while (entry.Type != DirectoryEntryType.EndOfDirectory)
                {
                    if (entry.Type != DirectoryEntryType.Unused)
                    {
                        rootDirectory.Children.Add(entry);
                    }
                    disk.Read(data, 0, data.Length);
                    entry = new DirectoryEntry(data, disk, this);
                }
            }
        }
Esempio n. 3
0
        public byte[] OpenFile(BufferedDiskReader disk, DirectoryEntry file)
        {
            if (file.IsDirectory)
            {
                return(null);
            }
            if (FAT == null)
            {
                ReadFAT(disk);
            }
            byte[] data         = ReadCluster(disk, file.FirstCluster);
            uint   nextCluster  = ReadNextFAT(file.FirstCluster);
            uint   clusterCount = 1;

            while (nextCluster < 0x0FFFFFF8)
            {
                clusterCount++;
                byte[] temp     = ReadCluster(disk, nextCluster);
                byte[] tempData = data;
                data = new byte[clusterCount * temp.Length];
                Array.Copy(tempData, 0, data, 0, tempData.Length);
                Array.Copy(temp, 0, data, tempData.Length, temp.Length);
                nextCluster = ReadNextFAT(nextCluster);
            }
            return(data);
        }
Esempio n. 4
0
        /*
         * parseDirectoryTree - Start directory tree parsing from physical disk
         * Return - Enumerates partition's rootDirectory structure
         */
        private void parseDirectoryTree(Partition partition)
        {
            //Create handle
            //SafeFileHandle handle = Exports.CreateFile(partition.Hdd.DeviceId,
            //                (uint)FileAccess.Read,
            //                (uint)FileShare.None,
            //                IntPtr.Zero,
            //                (uint)FileMode.Open,
            //                Exports.FILE_FLAG_NO_BUFFERING,
            //                IntPtr.Zero);

            BufferedDiskReader disk = new BufferedDiskReader(partition.Hdd.DeviceId);

            if (disk.IsInvalid)
            {
                MessageBox.Show(String.Format("Error Opening Partition "));
                return;
            }
            //Wrap handle in extended FileStream
            //PreciseFileStream disk = new PreciseFileStream(handle, FileAccess.Read);

            //Hand off FileStream to workhorse
            partition.ParseDirectoryEntries(disk);

            //Don't forget to close
            disk.Close();
        }
Esempio n. 5
0
        public void enumerateFATDevices()
        {
            disks = new List <HardDrive>();

            ManagementObjectSearcher search = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");

            //Iterate over each search result - list of HD's from WMI
            foreach (ManagementObject wmi_HD in search.Get())
            {
                HardDrive hdd = new HardDrive();
                hdd.Model    = wmi_HD["Model"].ToString();
                hdd.Type     = wmi_HD["InterfaceType"] == null ? "" : wmi_HD["InterfaceType"].ToString();
                hdd.DeviceId = wmi_HD["DeviceId"].ToString();

                BufferedDiskReader disk = new BufferedDiskReader(hdd.DeviceId);

                //Occurs when in use or insufficient privileges
                if (disk.IsInvalid)
                {
                    int error = Marshal.GetLastWin32Error();
                    MessageBox.Show(this, "Please verify you have Administrator Privileges and disks are not in use.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    continue;
                }

                //HDD is valid, add to our list
                disks.Add(hdd);

                //Sector buffer
                byte[] data = new byte[512];

                //Fill Buffer
                disk.Read(data, 0, 512);

                //Deserialize data into MasterBootRecord
                hdd.MBR = new MasterBootRecord(data);

                //Iterate over partitions in MBR
                foreach (PartitionTableEntry entry in hdd.MBR.PartitionTable.Partitions)
                {
                    //Clear data buffer
                    data = new byte[512];

                    //Seek to Partition start (FAT32 boot sector, location given in Partition table entry in Sectors)
                    disk.SeekAbsolute((ulong)entry.LBA_Begin1 * BYTES_PER_SECTOR);

                    //Read FAT32 BootSector - Volume Info
                    disk.Read(data, 0, data.Length);

                    //Deserialize data into Partition object
                    hdd.Partitions.Add(new Partition(data, hdd, entry));
                }

                //Got to remember to close the disk
                disk.Close();
            }
        }
Esempio n. 6
0
        /*
         * ReadFAT - Read FAT table 1 into memory
         */
        public void ReadFAT(BufferedDiskReader disk)
        {
            byte[] fatBytes = new byte[(bootSector.BPB.SectorsPerFAT32 * bootSector.BPB.BytesPerSector)];
            FAT = new uint[fatBytes.Length / 4];

            disk.SeekAbsolute((ulong)(bootSector.BPB.BytesPerSector * fatBeginLBA));
            disk.Read(fatBytes, 0, fatBytes.Length);


            for (int i = 0; i < FAT.Length; i++)
            {
                FAT[i] = (uint)(fatBytes[i * 4 + 3] << 24 | fatBytes[i * 4 + 2] << 16 | fatBytes[i * 4 + 1] << 8 | fatBytes[i * 4 + 0]);
            }
        }
Esempio n. 7
0
 private void treeViewDirectory_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
 {
     if (e.Node.Tag is DirectoryEntry)
     {
         DirectoryEntry entry = e.Node.Tag as DirectoryEntry;
         if (entry.IsDirectory || entry.IsVolumeID)
         {
             return;
         }
         Partition          partition = (comboBoxPartitions.SelectedItem as ComboBoxItem).Value as Partition;
         BufferedDiskReader disk      = new BufferedDiskReader(partition.Hdd.DeviceId);
         byte[]             fileBytes = partition.OpenFile(disk, entry);
         disk.Close();
         string output = Encoding.UTF8.GetString(fileBytes);
         Editor editor = new Editor(output);
         editor.Show();
     }
 }
Esempio n. 8
0
        private byte[] ReadCluster(BufferedDiskReader disk, uint cluster)
        {
            byte[] clusterBytes = new byte[(ulong)bootSector.BPB.BytesPerSector * (ulong)bootSector.BPB.SectorsPerCluster];

            //Calculate LBA for first cluster
            uint clusterLBA = (uint)(ClusterBeginLBA + (cluster - 2) * BootSector.BPB.SectorsPerCluster);

            ulong clusterStartByte = (ulong)bootSector.BPB.BytesPerSector * (ulong)clusterLBA;

            disk.SeekAbsolute(clusterStartByte);

            //for (int i = 0; i < bootSector.BPB.SectorsPerCluster; i++)
            //{
            //    byte[] data = new byte[bootSector.BPB.BytesPerSector];
            //    disk.Read(data, 0, data.Length);
            //    Array.Copy(data, 0, clusterBytes, i * bootSector.BPB.BytesPerSector, bootSector.BPB.BytesPerSector);
            //}
            disk.Read(clusterBytes, 0, clusterBytes.Length);
            return(clusterBytes);
        }
Esempio n. 9
0
        /*
         * CTOR - Creates current entry data's node then attaches any children, recurses into children directories
         * **NOTE** Individual values are Little-Endian on disk, except strings **NOTE**
         */
        public DirectoryEntry(byte[] data, BufferedDiskReader disk, Partition partition)
        {
            //Attribute byte
            attributeByte = data[0x0B];

            //0xE5 is unused - 0x2E is . or .. (need to figure out how to handle)
            if (data[0] == 0xE5 || data[0] == 0x2E)
            {
                type = DirectoryEntryType.Unused;
                return;
            }

            //0x00 is end of directory entry
            if (data[0] == 0x00)
            {
                type = DirectoryEntryType.EndOfDirectory;
                return;
            }

            //Four least significant bits set means long file name
            if ((attributeByte & 0x0F) == 0x0F)
            {
                //Set type
                type = DirectoryEntryType.LongFileName;

                //Type parse long file name
                longFilename = parseLongFilename(data, disk);

                //Read next entry after long file name
                disk.Read(data, 0, data.Length);

                //Get new attribute byte
                attributeByte = data[0x0B];

                //Normal entry always follows long filename entry
                type = DirectoryEntryType.Normal;
            }
            else
            {
                type = DirectoryEntryType.Normal;
            }

            //Bit 4 is directory flag
            isDirectory = (attributeByte & 16) != 0;

            //Bit 3 alone is VolumeId flag
            isVolumeID = (attributeByte ^ 8) == 0;

            //Get short name
            byte[] shortNameBytes = new byte[11];
            Array.Copy(data, 0, shortNameBytes, 0, shortNameBytes.Length);

            //Convert to string
            shortFilename = Encoding.ASCII.GetString(shortNameBytes);

            //First cluster of entry - Little-Endian
            firstCluster = (uint)(data[0x15] << 24 | data[0x14] << 16 | data[0x1B] << 8 | data[0x1A]);

            //Calculate LBA for first cluster
            firstClusterLBA = (uint)(partition.ClusterBeginLBA + (firstCluster - 2) * partition.BootSector.BPB.SectorsPerCluster);

            //If directory or volume we need to attach children
            if (isDirectory || isVolumeID)
            {
                children = new List <DirectoryEntry>();

                //Save old position for recursion
                ulong oldPos = disk.Position;

                //If this is directory seek to directory entry location
                if (isDirectory)
                {
                    ulong firstClusterAddress = ((ulong)firstClusterLBA * (ulong)partition.BootSector.BPB.BytesPerSector);
                    disk.SeekAbsolute(firstClusterAddress);
                }
                //Read next entry
                disk.Read(data, 0, data.Length);

                //Recurse on next entry bytes
                DirectoryEntry entry = new DirectoryEntry(data, disk, partition);

                //Iterate until end of directory entry is found
                while (entry.Type != DirectoryEntryType.EndOfDirectory)
                {
                    //Attach child unless unused
                    if (entry.Type != DirectoryEntryType.Unused)
                    {
                        children.Add(entry);
                    }
                    //Read new bytes
                    disk.Read(data, 0, data.Length);

                    //Recurse on next entry bytes
                    entry = new DirectoryEntry(data, disk, partition);
                    if (entry.ShortFilename != null && entry.ShortFilename.Contains("2014"))
                    {
                        entry = entry;
                    }
                }
                //Seek to start Pos since we're going back up a level
                disk.SeekAbsolute(oldPos);
            }
        }