private static bool GetAsciiKey(NANDReader reader, int offset, out string key) { Debug.SendDebug("Grabbing ASCII Key @ 0x{0:X}", offset); key = null; reader.Lba = (uint)(offset / 0x4000); if (offset % 0x4000 > 0) { reader.Seek(offset % 0x4000, SeekOrigin.Current); } //reader.Seek(offset, SeekOrigin.Begin); var tmp = reader.ReadBytes(0x10); try { key = Encoding.ASCII.GetString(tmp); try { CpukeyUtils.VerifyCpuKey(key); return(true); } catch (X360UtilsException ex) { Debug.SendDebug(ex.ToString()); return(false); } } catch { return(false); } }
public byte[] GetSmcConfig(NANDReader reader) { if (reader.RawLength == 0x1080000) // 16MB NAND { reader.Lba = 0xF7C000 / 0x4000; } else if (!reader.HasSpare) // MMC NAND { reader.Seek(0x2FFC000, SeekOrigin.Begin); } else // BigBlock NAND { reader.Lba = 0x3BE0000 / 0x4000; } var data = reader.ReadBytes(0x400); try { var cfg = new SmcConfig(); cfg.VerifySMCConfigChecksum(data); } catch (X360UtilsException ex) { if (ex.ErrorCode == X360UtilsException.X360UtilsErrors.BadChecksum) { throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataNotFound); } throw; } return(data); }
public string GetVirtualFuses(NANDReader reader) { reader.Lba = 0x95000 / 0x4000; reader.Seek(0x95000 % 0x4000, SeekOrigin.Current); //reader.Seek(0x95000, SeekOrigin.Begin); var data = reader.ReadBytes(0x60); var tmp = new byte[] { 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xF0 }; if (!BitOperations.CompareByteArrays(ref data, ref tmp, false)) { throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataInvalid); } var ret = new StringBuilder(); for (var index = 0; index < data.Length; index++) { if (index % 0x8 == 0 || index == 0) { ret.AppendFormat("\nfuseset {0:D2}: ", index / 0x5); } ret.Append(data[index].ToString("X2")); } return(ret.ToString().Trim()); }
public Bootloader(NANDReader reader, int count = 0, bool readitin = false) { Offset = (uint)(reader.Lba * 0x4000 + reader.Position % 0x4000); StartLba = reader.Lba; var header = reader.ReadBytes(0x10); Type = GetTypeFromHeader(ref header, count); Size = GetBootloaderSize(ref header); Build = GetBootloaderVersion(ref header); if (readitin) { reader.Lba = Offset / 0x4000; if (Offset % 0x4000 > 0) { reader.Seek(Offset % 0x4000, SeekOrigin.Current); } Data = new byte[Size]; var left = Size; var dOffset = 0; for (var i = 0; left > 0; i++) { var toread = (int)BitOperations.GetSmallest(0x4000, left); if (left == Size && reader.Position % 0x4000 > 0) { toread = (int)BitOperations.GetSmallest((0x4000 - (reader.Position % 0x4000)), left); } var tmp = reader.ReadBytes(toread); Buffer.BlockCopy(tmp, 0, Data, dOffset, toread); left -= (uint)toread; dOffset += toread; if (left > 0) // We want to seek to the next block! { reader.Lba = (uint)((Offset / 0x4000) + 1 + i); } } } else { reader.Lba = (Offset + Size) / 0x4000; if ((Offset + Size) % 0x4000 > 0) { reader.Seek((Offset + Size) % 0x4000, SeekOrigin.Current); } } //reader.Seek(Offset + Size, SeekOrigin.Begin); }
public FileSystemEntry[] ParseFileSystem(ref NANDReader reader, FsRootEntry fsRoot) { var ret = new List <FileSystemEntry>(); reader.Seek(fsRoot.Offset, SeekOrigin.Begin); var bitmap = new byte[0x2000]; var fsinfo = new byte[0x2000]; for (var i = 0; i < bitmap.Length / 0x200; i++) { var buf = reader.ReadBytes(0x200); Buffer.BlockCopy(buf, 0, bitmap, i * 0x200, buf.Length); buf = reader.ReadBytes(0x200); Buffer.BlockCopy(buf, 0, fsinfo, i * 0x200, buf.Length); } if (reader.MetaType == NANDSpare.MetaType.MetaType0 || reader.MetaType == NANDSpare.MetaType.MetaType1 || reader.MetaType == NANDSpare.MetaType.MetaType2 || reader.MetaType == NANDSpare.MetaType.MetaTypeNone) { for (var i = 0; i < fsinfo.Length / 0x20; i++) { var blocks = new List <long>(); var name = Encoding.ASCII.GetString(fsinfo, i * 0x20, 0x16); var start = BitOperations.Swap(BitConverter.ToUInt16(fsinfo, i * 0x20 + 0x16)); var size = BitOperations.Swap(BitConverter.ToUInt32(fsinfo, i * 0x20 + 0x18)); var timestamp = BitOperations.Swap(BitConverter.ToUInt32(fsinfo, i * 0x20 + 0x1C)); blocks.Add(start); // Always add the first block! while (true) { start = BitOperations.Swap(BitConverter.ToUInt16(bitmap, start * 2)); //if(start == 0x1FFF || start == 0x1FFE) if (start * 2 > bitmap.Length + 2) { break; } blocks.Add(start); } if (name.StartsWith("\0") || name.StartsWith("\x5")) { continue; // Ignore empty and/or deleted entries } if (blocks.Count > 0) { if (blocks[0] == 0 || size == 0) // ignore entries with no offset / size { continue; } } ret.Add(new FileSystemEntry(name.Substring(0, name.IndexOf('\0')), size, timestamp, blocks.ToArray())); } } else { throw new NotSupportedException(); } return(ret.ToArray()); }
public byte[] GetSmc(NANDReader reader, bool decrypted = false) { reader.Seek(0x78, SeekOrigin.Begin); var tmp = reader.ReadBytes(4); var size = BitOperations.Swap(BitConverter.ToUInt32(tmp, 0)); reader.Seek(0x7C, SeekOrigin.Begin); tmp = reader.ReadBytes(4); reader.Seek(BitOperations.Swap(BitConverter.ToUInt32(tmp, 0)), SeekOrigin.Begin); if (!decrypted) { return(reader.ReadBytes((int)size)); } tmp = reader.ReadBytes((int)size); _crypto.DecryptSmc(ref tmp); if (!Cryptography.VerifySmcDecrypted(ref tmp)) { throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataDecryptionFailed); } return(tmp); }
private static bool GetByteKey(NANDReader reader, int offset, out byte[] key) { Debug.SendDebug("Grabbing Byte Key @ 0x{0:X}", offset); reader.Lba = (uint)(offset / 0x4000); if (offset % 0x4000 > 0) { reader.Seek(offset % 0x4000, SeekOrigin.Current); } //reader.Seek(offset, SeekOrigin.Begin); key = reader.ReadBytes(0x10); try { CpukeyUtils.VerifyCpuKey(ref key); return(true); } catch (X360UtilsException ex) { Debug.SendDebug(ex.ToString()); return(false); } }
public byte[] GetData(ref NANDReader reader) { reader.Seek(Offset, SeekOrigin.Begin); return(reader.ReadBytes(Size)); }
public byte[] GetBlock(ref NANDReader reader) { reader.Seek(Offset, SeekOrigin.Begin); return(reader.ReadBytes(0x4000)); }
public Bootloader[] GetBootLoaders(NANDReader reader, bool readToMemory = false) { var bls = new List <Bootloader>(); //reader.Seek(0x8000, SeekOrigin.Begin); reader.Lba = 2; // Seek to offset 0x8000, where the start of the bootloaders bls.Add(new Bootloader(reader, readitin: readToMemory)); try { for (var i = 1; i < 4; i++) { bls.Add(new Bootloader(reader, i, readToMemory)); } } catch (X360UtilsException ex) { if (ex.ErrorCode != X360UtilsException.X360UtilsErrors.DataInvalid) { throw; } } try { reader.Seek(0x70, SeekOrigin.Begin); var size = BitOperations.Swap(BitConverter.ToUInt32(reader.ReadBytes(4), 0)); reader.Seek(0x64, SeekOrigin.Begin); var offset = BitOperations.Swap(BitConverter.ToUInt32(reader.ReadBytes(4), 0)); reader.Lba = offset / 0x4000; if (offset % 0x4000 > 0) { reader.Seek(offset % 0x4000, SeekOrigin.Current); } //reader.Seek(offset, SeekOrigin.Begin); bls.Add(new Bootloader(reader, readitin: readToMemory)); bls.Add(new Bootloader(reader, readitin: readToMemory)); try { if (size == 0) { reader.Lba = (offset + 0x10000) / 0x4000; if ((offset + 0x10000) % 0x4000 > 0) { reader.Seek((offset + 0x10000) % 0x4000, SeekOrigin.Current); } //reader.Seek(offset + 0x10000, SeekOrigin.Begin); bls.Add(new Bootloader(reader, readitin: readToMemory)); bls.Add(new Bootloader(reader, readitin: readToMemory)); } } catch (X360UtilsException ex) { if (ex.ErrorCode != X360UtilsException.X360UtilsErrors.DataInvalid) { throw; } if (size == 0) { reader.Lba = (offset + 0x20000) / 0x4000; if ((offset + 0x20000) % 0x4000 > 0) { reader.Seek((offset + 0x20000) % 0x4000, SeekOrigin.Current); } //reader.Seek(offset + 0x20000, SeekOrigin.Begin); bls.Add(new Bootloader(reader, readitin: readToMemory)); bls.Add(new Bootloader(reader, readitin: readToMemory)); } } } catch (X360UtilsException ex) { if (ex.ErrorCode != X360UtilsException.X360UtilsErrors.DataInvalid) { throw; } } return(bls.ToArray()); }