public byte[] GetSmcConfig(NANDReader reader) { if (reader.RawLength == 0x1080000) // 16MB NAND { reader.SeekToLbaEx(0xF7C000 / 0x4000); } else if (!reader.HasSpare) // MMC NAND { reader.Seek(0x2FFC000, SeekOrigin.Begin); } else // BigBlock NAND { reader.SeekToLbaEx(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); }
private static bool GetAsciiKey(NANDReader reader, int offset, out string key) { Debug.SendDebug("Grabbing ASCII Key @ 0x{0:X}", offset); key = null; reader.SeekToLbaEx((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 string GetVirtualFuses(NANDReader reader) { reader.SeekToLbaEx(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.SeekToLbaEx(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.SeekToLbaEx((uint)((Offset / 0x4000) + 1 + i)); } } } else { reader.SeekToLbaEx((Offset + Size) / 0x4000); if ((Offset + Size) % 0x4000 > 0) { reader.Seek((Offset + Size) % 0x4000, SeekOrigin.Current); } } //reader.Seek(Offset + Size, SeekOrigin.Begin); }
public byte[] GetData(ref NANDReader reader) { var ret = new List <byte>(); var left = (int)Size; var baseBlock = reader.MetaType != NANDSpare.MetaType.MetaType2 ? 0 : GetBaseBlockForMeta2(ref reader); foreach (var offset in Blocks) { reader.SeekToLbaEx((ushort)(baseBlock + offset)); ret.AddRange(reader.ReadBytes(BitOperations.GetSmallest(left, 0x4000))); left -= BitOperations.GetSmallest(left, 0x4000); } return(ret.ToArray()); }
public void ExtractToFile(ref NANDReader reader, string filename) { using (var writer = new BinaryWriter(File.OpenWrite(filename))) { var left = (int)Size; var baseBlock = reader.MetaType != NANDSpare.MetaType.MetaType2 ? 0 : GetBaseBlockForMeta2(ref reader); foreach (var offset in Blocks) { reader.SeekToLbaEx((ushort)(baseBlock + offset)); writer.Write(reader.ReadBytes(BitOperations.GetSmallest(left, 0x4000))); left -= BitOperations.GetSmallest(left, 0x4000); } } File.SetCreationTime(filename, DateTime); File.SetLastAccessTime(filename, DateTime); File.SetLastWriteTime(filename, DateTime); }
public byte[] GetKeyVault(NANDReader reader, bool decryptWithKeyInNand = false) { reader.SeekToLbaEx(1); // Seek to the KV Block //reader.Seek(0x4000, SeekOrigin.Begin); if (!decryptWithKeyInNand) { return(reader.ReadBytes(0x4000)); } var kv = GetKeyVault(reader); var cpukey = GetNandCpuKey(reader); _crypto.DecryptKv(ref kv, cpukey); if (_crypto.VerifyKvDecrypted(ref kv, cpukey)) { return(kv); } throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataDecryptionFailed); }
private static bool GetByteKey(NANDReader reader, int offset, out byte[] key) { Debug.SendDebug("Grabbing Byte Key @ 0x{0:X}", offset); reader.SeekToLbaEx((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 Bootloader[] GetBootLoaders(NANDReader reader, bool readToMemory = false) { var bls = new List <Bootloader>(); //reader.Seek(0x8000, SeekOrigin.Begin); reader.SeekToLbaEx(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.SeekToLbaEx(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.SeekToLbaEx((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.SeekToLbaEx((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()); }