static public string GetFATXPath(string PackagePath) { // Check the header... Streams.Reader io = new Streams.Reader(new System.IO.FileStream(PackagePath, System.IO.FileMode.Open)); if (io.BaseStream.Length > 4) { uint header = io.ReadUInt32(); if (header == 0x434F4E20 || header == 0x4C495645 || header == 0x50495253) { // Get the type io.BaseStream.Position = 0x344; byte[] Type = io.ReadBytes(0x4); // Get the profile ID io.BaseStream.Position = 0x371; byte[] ID = io.ReadBytes(0x8); // Get the title ID io.BaseStream.Position = 0x360; byte[] TitleID = io.ReadBytes(0x4); // NOW LET'S DO THIS SHIT return(string.Format("Content\\{0}\\{1}\\{2}", ID.ToHexString(), TitleID.ToHexString(), Type.ToHexString())); } } throw new Exception(PackagePath + " is not a valid package!"); }
List <DevPartitionRegions> dP;/*enetration*/ DevPartitionRegions[] DevPartitions() { if (dP == null) { dP = new List <DevPartitionRegions>(); // Load the regions Streams.Reader r = Reader(); r.BaseStream.Position = 0; byte[] Buffer = r.ReadBytes(0x200); r = new CLKsFATXLib.Streams.Reader(new System.IO.MemoryStream(Buffer)); r.BaseStream.Position = 0x8; // data dP.Add(new DevPartitionRegions() { RegionName = "Content", Sector = r.ReadUInt32(), PartitionSize = r.ReadUInt32() * 0x200, }); dP.Add(new DevPartitionRegions() { RegionName = "Xbox 360 Dashboard Volume", Sector = r.ReadUInt32(), PartitionSize = r.ReadUInt32() * 0x200, }); } return(dP.ToArray()); }
public static byte[] ConsoleCertificate() { Streams.Reader r = Drive.Reader(); r.BaseStream.Position = 0x804; byte[] Value = r.ReadBytes(0x1A8); return(Value); }
/// <summary> /// Used for quickly reading bytes for a length that is not a multiple of 0x200 /// </summary> static public byte[] ReadBytes(ref Streams.Reader br, long length) { byte[] buffer = br.ReadBytes((int)VariousFunctions.UpToNearest200(length)); List <byte> b = buffer.ToList <byte>(); b.RemoveRange((int)length, buffer.Length - (int)length); buffer = b.ToArray(); return(buffer); }
/// <summary> /// Partition ID /// </summary> public uint PartitionID() { uint rVal = 0; //Open our binary reader Streams.Reader br = FATXDrive.Reader(); //Seek to the data partition offset br.BaseStream.Position = Partition.Offset; //Read our buffer Streams.Reader mem = new Streams.Reader(new System.IO.MemoryStream(br.ReadBytes(0x200))); mem.BaseStream.Position = 0x4; rVal = mem.ReadUInt32(); mem.Close(); return(rVal); }
/// <summary> /// Number of File Allocation Tables /// </summary> public uint FATCopies() { uint rVal = 0; //Open our binary reader Streams.Reader br = FATXDrive.Reader(); //Seek to the data partition offset + 0xC (where the FATCopies int is) br.BaseStream.Position = Partition.Offset; //Create our mem reader / buffer Streams.Reader mem = new Streams.Reader(new System.IO.MemoryStream(br.ReadBytes(0x200))); mem.BaseStream.Position = 0xC; //Get our value (uses outside class for bigendian) rVal = mem.ReadUInt32(); mem.Close(); return(rVal); }
public void ClearFATChain(uint[] Chain) { Streams.Reader r = Parent.Drive.Reader(); Streams.Writer w = new CLKsFATXLib.Streams.Writer(r.BaseStream); long buffersize = 0x1000; long lastoffset = 0;//VariousFunctions.BlockToFATOffset(Chain[0], Parent).DownToNearestCluster(buffersize); byte[] Buffer = new byte[buffersize]; for (int i = 0; i < Chain.Length; i++) { // Read the chain buffer if (lastoffset != VariousFunctions.BlockToFATOffset(Chain[i], Parent).DownToNearestCluster(0x1000)) { if (i != 0) { w.BaseStream.Position = lastoffset; w.Write(Buffer); } lastoffset = VariousFunctions.BlockToFATOffset(Chain[i], Parent).DownToNearestCluster(0x1000); r.BaseStream.Position = lastoffset; Buffer = r.ReadBytes((int)buffersize); } // Write the chain Streams.Writer mem = new CLKsFATXLib.Streams.Writer(new System.IO.MemoryStream(Buffer)); mem.BaseStream.Position = VariousFunctions.BlockToFATOffset(Chain[i], Parent) - VariousFunctions.BlockToFATOffset(Chain[i], Parent).DownToNearestCluster(0x1000); byte[] writing = new byte[0]; switch (Parent.PartitionInfo.EntrySize) { case 2: writing = BitConverter.GetBytes((ushort)0); break; case 4: writing = BitConverter.GetBytes(0); break; } mem.Write(writing); mem.Close(); if (i == Chain.Length - 1) { w.BaseStream.Position = lastoffset; w.Write(Buffer); } } }
public uint RootDirectoryCluster() { // Open our IO Streams.Reader io = FATXDrive.Reader(); // Set the IO position... io.BaseStream.Position = Partition.Offset; // Read our buffer byte[] buffer = io.ReadBytes(0x200); // Re-open the IO in to a memory stream io = new Streams.Reader(new System.IO.MemoryStream(buffer)); // Go to the offset that the root dir is located; 0xC io.BaseStream.Position = 0xC; // Read and return the int there uint rVal = io.ReadUInt32(); io.Close(); return(rVal); }
/// <summary> /// Returns an array of free blocks based off of the number of blocks needed /// </summary> public uint[] GetFreeBlocks(Folder Partition, int blocksNeeded, uint StartBlock, long end, bool SecondLoop) { int Clustersize = 0x10000; uint Block = StartBlock; if (end == 0) { end = Partition.PartitionInfo.FATOffset + Partition.PartitionInfo.FATSize; } List<uint> BlockList = new List<uint>(); // Create our reader for the drive Streams.Reader br = Reader(); // Create our reader for the memory stream Streams.Reader mr = null; for (long i = VariousFunctions.DownToNearest200(VariousFunctions.BlockToFATOffset(StartBlock, Partition)); i < end; i += Clustersize) { //Set our position to i br.BaseStream.Position = i; byte[] buffer = new byte[0]; if ((end - i) < Clustersize) { buffer = VariousFunctions.ReadBytes(ref br, end - i); } else { //Read our buffer buffer = br.ReadBytes(Clustersize); } try { mr.Close(); } catch { } mr = new Streams.Reader(new System.IO.MemoryStream(buffer)); //Re-open our binary reader using the buffer/memory stream for (int j = 0; j < buffer.Length; j += (int)Partition.PartitionInfo.EntrySize, Block += (uint)Partition.PartitionInfo.EntrySize) { mr.BaseStream.Position = j; //If we've gotten all of our requested blocks... if (BlockList.Count == blocksNeeded) { //Close our reader -> break the loop mr.Close(); break; } //Read the next block entry byte[] reading = mr.ReadBytes((int)Partition.PartitionInfo.EntrySize); //For each byte in our reading for (int k = 0; k < reading.Length; k++) { //If the byte isn't null (if the block isn't open) if (reading[k] != 0x00) { //Break break; } //If we've reached the end of the array, and the last byte //is 0x00, then the block is free if (k == reading.Length - 1 && reading[k] == 0x00) { //Do some maths to get the block numbah long fOff = Partition.PartitionInfo.FATOffset; long blockPosition = (long)i + j; uint block = (uint)(blockPosition - fOff) / (uint)Partition.PartitionInfo.EntrySize; BlockList.Add(block); } } } //We're putting in one last check so that we don't loop more than we need to if (BlockList.Count == blocksNeeded) { break; } } //If we found the required amount of free blocks - return our list if (BlockList.Count == blocksNeeded) { return BlockList.ToArray(); } //If we didn't find the amount of blocks required, but we started from a //block other than the first one... if (BlockList.Count < blocksNeeded && SecondLoop == false) { BlockList.AddRange(GetFreeBlocks(Partition, blocksNeeded - BlockList.Count, 1, VariousFunctions.DownToNearest200(VariousFunctions.BlockToFATOffset(StartBlock, Partition)), true)); return BlockList.ToArray(); } //We didn't find the amount of free blocks required, meaning we're ref of //disk space if (BlockList.Count != blocksNeeded) { throw new Exception("Out of Xbox 360 hard disk space"); } return BlockList.ToArray(); }
public static string GetFATXPath(string PackagePath) { // Check the header... Streams.Reader io = new Streams.Reader(new System.IO.FileStream(PackagePath, System.IO.FileMode.Open)); if (io.BaseStream.Length > 4) { uint header = io.ReadUInt32(); if (header == 0x434F4E20 || header == 0x4C495645 || header == 0x50495253) { // Get the type io.BaseStream.Position = 0x344; byte[] Type = io.ReadBytes(0x4); // Get the profile ID io.BaseStream.Position = 0x371; byte[] ID = io.ReadBytes(0x8); // Get the title ID io.BaseStream.Position = 0x360; byte[] TitleID = io.ReadBytes(0x4); // NOW LET'S DO THIS SHIT return string.Format("Content\\{0}\\{1}\\{2}", ID.ToHexString(), TitleID.ToHexString(), Type.ToHexString()); } } throw new Exception(PackagePath + " is not a valid package!"); }
public static System.Drawing.Image MicrosoftLogo() { Streams.Reader r = Drive.Reader(); r.BaseStream.Position = 0x2200; uint Length = r.ReadUInt32(); System.Drawing.Image Value = System.Drawing.Image.FromStream(new System.IO.MemoryStream(r.ReadBytes((int)Length))); return(Value); }
/// <summary> /// Returns an array of free blocks based off of the number of blocks needed /// </summary> public uint[] GetFreeBlocks(Folder Partition, int blocksNeeded, uint StartBlock, long end, bool SecondLoop) { int Clustersize = 0x10000; uint Block = StartBlock; if (end == 0) { end = Partition.PartitionInfo.FATOffset + Partition.PartitionInfo.FATSize; } List <uint> BlockList = new List <uint>(); // Create our reader for the drive Streams.Reader br = Reader(); // Create our reader for the memory stream Streams.Reader mr = null; for (long i = VariousFunctions.DownToNearest200(VariousFunctions.BlockToFATOffset(StartBlock, Partition)); i < end; i += Clustersize) { //Set our position to i br.BaseStream.Position = i; byte[] buffer = new byte[0]; if ((end - i) < Clustersize) { buffer = VariousFunctions.ReadBytes(ref br, end - i); } else { //Read our buffer buffer = br.ReadBytes(Clustersize); } try { mr.Close(); } catch { } mr = new Streams.Reader(new System.IO.MemoryStream(buffer)); //Re-open our binary reader using the buffer/memory stream for (int j = 0; j < buffer.Length; j += (int)Partition.PartitionInfo.EntrySize, Block += (uint)Partition.PartitionInfo.EntrySize) { mr.BaseStream.Position = j; //If we've gotten all of our requested blocks... if (BlockList.Count == blocksNeeded) { //Close our reader -> break the loop mr.Close(); break; } //Read the next block entry byte[] reading = mr.ReadBytes((int)Partition.PartitionInfo.EntrySize); //For each byte in our reading for (int k = 0; k < reading.Length; k++) { //If the byte isn't null (if the block isn't open) if (reading[k] != 0x00) { //Break break; } //If we've reached the end of the array, and the last byte //is 0x00, then the block is free if (k == reading.Length - 1 && reading[k] == 0x00) { //Do some maths to get the block numbah long fOff = Partition.PartitionInfo.FATOffset; long blockPosition = (long)i + j; uint block = (uint)(blockPosition - fOff) / (uint)Partition.PartitionInfo.EntrySize; BlockList.Add(block); } } } //We're putting in one last check so that we don't loop more than we need to if (BlockList.Count == blocksNeeded) { break; } } //If we found the required amount of free blocks - return our list if (BlockList.Count == blocksNeeded) { return(BlockList.ToArray()); } //If we didn't find the amount of blocks required, but we started from a //block other than the first one... if (BlockList.Count < blocksNeeded && SecondLoop == false) { BlockList.AddRange(GetFreeBlocks(Partition, blocksNeeded - BlockList.Count, 1, VariousFunctions.DownToNearest200(VariousFunctions.BlockToFATOffset(StartBlock, Partition)), true)); return(BlockList.ToArray()); } //We didn't find the amount of free blocks required, meaning we're ref of //disk space if (BlockList.Count != blocksNeeded) { throw new Exception("Out of Xbox 360 hard disk space"); } return(BlockList.ToArray()); }
public uint[] GetBlocksOccupied() { List <uint> Blocks = new List <uint>(); Streams.Reader r = Parent.Drive.Reader(); Blocks.Add(Parent.StartingCluster); byte[] Buffer = new byte[0x1000]; int buffersize = 0x1000; long lastoffset = 0; for (int i = 0; i < Blocks.Count; i++) { r.BaseStream.Position = VariousFunctions.BlockToFATOffset(Blocks[i], Parent).DownToNearestCluster(0x1000); // We use this so that we aren't reading the same buffer // a zillion times if (r.BaseStream.Position != lastoffset) { lastoffset = r.BaseStream.Position; Buffer = r.ReadBytes(buffersize); } Streams.Reader r1 = new CLKsFATXLib.Streams.Reader(new System.IO.MemoryStream(Buffer)); int OffsetInBuffer = (int)(VariousFunctions.BlockToFATOffset(Blocks[i], Parent) - VariousFunctions.BlockToFATOffset(Blocks[i], Parent).DownToNearestCluster(0x1000)); r1.BaseStream.Position = OffsetInBuffer; switch (Parent.PartitionInfo.EntrySize) { case 2: ushort Value = r1.ReadUInt16(); if (Value != 0xFFFF && Value != 0xFFF8) { if (Value == 0) { EntryData ed = Parent.EntryData; ed.NameSize = 0xE5; CreateNewEntry(ed); if (Blocks.Count > 0) { ClearFATChain(Blocks.ToArray()); } throw new Exception(string.Format("Bad FAT chain in file or folder {0}\r\nEntry Offset: 0x{1}\r\nLast block in FAT: 0x{2}\r\nEntry marked as deleted to avoid further errors! Please reload this device", Parent.FullPath, Parent.EntryOffset.ToString("X"), Blocks.Last().ToString("X"))); } Blocks.Add(Value); } break; case 4: uint Value2 = r1.ReadUInt32(); if (Value2 != 0xFFFFFFFF && Value2 != 0xFFFFFFF8) { if (Value2 == 0) { EntryData ed = Parent.EntryData; ed.NameSize = 0xE5; CreateNewEntry(ed); if (Blocks.Count > 0) { ClearFATChain(Blocks.ToArray()); } throw new Exception(string.Format("Bad FAT chain in file or folder {0}\r\nEntry Offset: 0x{1}\r\nLast block in FAT: 0x{2}\r\nEntry marked as deleted to avoid further errors! Please reload this device", Parent.FullPath, Parent.EntryOffset.ToString("X"), Blocks.Last().ToString("X"))); } Blocks.Add(Value2); } break; } r1.Close(); } return(Blocks.ToArray()); }
public EntryData[] EntryDataFromBlock(uint Block) { bool Break = false; List <EntryData> eList = new List <EntryData>(); // Get our binary reader Streams.Reader r1 = Parent.Drive.Reader(); r1.BaseStream.Position = VariousFunctions.GetBlockOffset(Block, Parent); /* Parent.PartitionInfo.Clusters / 0x40 / 0x8 because if each * entry is 0x40 in length and the cluster is filled to the * max with cluster entries, then we can do division to get * the number of entries that would be in that cluster * the 0x8 part is because on drives we have to read in intervals * of 0x200 right? So if Parent.PartitionInfo.Clusters / 0x40 = 0x100, * then that means that there are 0x100 entries per cluster... * divide that by 8 (the number of clusters within a 0x200 interval) and * that's how many shits we have to go forward */ for (int j = 0; j < Parent.PartitionInfo.ClusterSize / 0x1000; j++) { // Increment our position // Open another reader using a memory stream long r1Position = r1.BaseStream.Position; Streams.Reader r = new CLKsFATXLib.Streams.Reader(new System.IO.MemoryStream(r1.ReadBytes(0x1000))); for (int k = 0; k < (0x1000 / 0x40); k++) { // Check to see if we've passed the last entry... uint val = r.ReadUInt32(); if (val == 0x0 || val == 0xFFFFFFFF) { Break = true; break; } // Go back four bytes because we just checked the next four... r.BaseStream.Position -= 4; long StartOffset = r.BaseStream.Position; EntryData e = new EntryData(); e.EntryOffset = r.BaseStream.Position + r1Position; e.NameSize = r.ReadByte(); e.Flags = r.ReadByte(); /* Because some f*****g smart guy decided to put the * deleted flag in the name size field, we have to check * if it's deleted or not...*/ if (e.NameSize == 0xE5) { // Fuckers e.Name = Encoding.ASCII.GetString(r.ReadBytes(0x2A)); } else { e.Name = Encoding.ASCII.GetString(r.ReadBytes(e.NameSize)); } r.BaseStream.Position = StartOffset + 0x2C; e.StartingCluster = r.ReadUInt32(); e.Size = r.ReadUInt32(); e.CreationDate = r.ReadUInt16(); e.CreationTime = r.ReadUInt16(); e.AccessDate = r.ReadUInt16(); e.AccessTime = r.ReadUInt16(); e.ModifiedDate = r.ReadUInt16(); e.ModifiedTime = r.ReadUInt16(); eList.Add(e); } r.Close(); if (Break) { break; } } return(eList.ToArray()); }
//uint dicks(ref uint r3, ref uint r4, ref uint r6, ref uint r7, ref uint r8, ref uint r9, ref uint r10) //{ //} public ulong GetFreeSpace() { // Our return ulong Return = 0; ulong ClusterSize = (ulong)this.ClusterSize(); // Get our position long positionya = FATOffset; // Get our end point long toBeLessThan = FATOffset + RealFATSize(); // Get our IO Streams.Reader io = FATXDrive.Reader(); // Set the position io.BaseStream.Position = positionya; // Start reading! for (long dick = io.BaseStream.Position; dick < toBeLessThan; dick += 0x200) { bool BreakAndShit = false; // Set the position io.BaseStream.Position = dick; // Read our buffer byte[] Buffer = null; if ((dick - FATOffset).DownToNearest200() == (toBeLessThan - FATOffset).DownToNearest200()) { byte[] Temp = io.ReadBytes(0x200); Buffer = new byte[(toBeLessThan - FATOffset) - (dick - FATOffset).DownToNearest200()]; Array.Copy(Temp, 0, Buffer, 0, Buffer.Length); } else { Buffer = io.ReadBytes(0x200); } // Length to loop for (used for the end so we can read ONLY usable partitions) long Length = Buffer.Length; if (dick == VariousFunctions.DownToNearest200(toBeLessThan)) { Length = toBeLessThan - VariousFunctions.DownToNearest200(toBeLessThan); BreakAndShit = true; } // Check the values Streams.Reader ioya = new Streams.Reader(new System.IO.MemoryStream(Buffer)); for (int i = 0; i < Length; i += EntrySize) { // This size will be off by a few megabytes, no big deal in my opinion if (EntrySize == 2) { ushort Value = ioya.ReadUInt16(); if (Value == 0) { Return += ClusterSize; } } else { if (ioya.ReadUInt32() == 0) { Return += ClusterSize; } } } ioya.Close(); if (BreakAndShit) { break; } } return(Return); }
// Do not feel like recoding this function. public void CreateNewEntry(EntryData Edata) { Streams.Reader br = Parent.Drive.Reader(); //Set our position so that we can read the entry location br.BaseStream.Position = VariousFunctions.DownToNearest200(Edata.EntryOffset); byte[] buffer = br.ReadBytes(0x200); //Create our binary writer Streams.Writer bw = new Streams.Writer(new System.IO.MemoryStream(buffer)); //Set our position to where the entry is long EntryOffset = Edata.EntryOffset - VariousFunctions.DownToNearest200(Edata.EntryOffset); bw.BaseStream.Position = EntryOffset; //Write our entry bw.Write(Edata.NameSize); bw.Write(Edata.Flags); bw.Write(Encoding.ASCII.GetBytes(Edata.Name)); if (Edata.NameSize != 0xE5) { int FFLength = 0x2A - Edata.NameSize; byte[] FF = new byte[FFLength]; for (int i = 0; i < FFLength; i++) { FF[i] = 0xFF; } bw.Write(FF); } else { bw.BaseStream.Position += 0x2A - Edata.Name.Length; } //Right here, we need to make everything a byte array, as it feels like writing //everything in little endian for some reason... byte[] StartingCluster = BitConverter.GetBytes(Edata.StartingCluster); Array.Reverse(StartingCluster); bw.Write(StartingCluster); byte[] Size = BitConverter.GetBytes(Edata.Size); Array.Reverse(Size); bw.Write(Size); //Write ref the creation date/time 3 times byte[] CreationDate = BitConverter.GetBytes(Edata.CreationDate); byte[] CreationTime = BitConverter.GetBytes(Edata.CreationTime); byte[] AccessDate = BitConverter.GetBytes(Edata.AccessDate); byte[] AccessTime = BitConverter.GetBytes(Edata.AccessTime); byte[] ModifiedDate = BitConverter.GetBytes(Edata.ModifiedDate); byte[] ModifiedTime = BitConverter.GetBytes(Edata.ModifiedTime); Array.Reverse(CreationDate); Array.Reverse(CreationTime); Array.Reverse(AccessDate); Array.Reverse(AccessTime); Array.Reverse(ModifiedDate); Array.Reverse(ModifiedTime); bw.Write(CreationDate); bw.Write(CreationTime); bw.Write(AccessDate); bw.Write(AccessTime); bw.Write(ModifiedDate); bw.Write(ModifiedTime); //Close our writer bw.Close(); //Get our IO bw = Parent.Drive.Writer(); bw.BaseStream.Position = VariousFunctions.DownToNearest200(Edata.EntryOffset); //Write ref our buffer bw.Write(buffer); }