Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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());
        }
Example #4
0
        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);
        }
Example #5
0
        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());
        }
Example #6
0
        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);
        }
Example #7
0
 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);
     }
 }
Example #8
0
 public byte[] GetData(ref NANDReader reader)
 {
     reader.Seek(Offset, SeekOrigin.Begin);
     return(reader.ReadBytes(Size));
 }
Example #9
0
 public byte[] GetBlock(ref NANDReader reader)
 {
     reader.Seek(Offset, SeekOrigin.Begin);
     return(reader.ReadBytes(0x4000));
 }
Example #10
0
        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());
        }