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 GetNandCpuKey(NANDReader reader)
 {
     byte[] key;
     if (!GetByteKey(reader, 0x100, out key))                   // Blakcat XeLL
     {
         if (!GetByteKey(reader, 0x6d0, out key))               // Blakcat Freeboot storage (Spare type offset)
         {
             if (!GetByteKey(reader, 0x700, out key))           // Blakcat Freeboot storage (MMC type offset)
             {
                 if (!GetByteKey(reader, 0x600, out key))       // xeBuild GUI Offset
                 {
                     if (!GetByteKey(reader, 0x95020, out key)) // Virtual Fuses
                     {
                         string keys;
                         if (!GetAsciiKey(reader, 0x600, out keys)) // xeBuild GUI ASCII Method
                         {
                             throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataNotFound);
                         }
                         return(keys);
                     }
                 }
             }
         }
     }
     return(StringUtils.ArrayToHex(key));
 }
Example #4
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 #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
        private static long GetBaseBlockForMeta2(ref NANDReader reader)
        {
            reader.RawSeek(reader.FsRoot.Offset / 0x200 * 0x210 + 0x200, SeekOrigin.Begin);
            var meta     = NANDSpare.GetMetaData(reader.RawReadBytes(0x10));
            var reserved = 0x1E0;

            reserved -= meta.Meta2.FsPageCount;
            reserved -= meta.Meta2.FsSize0 << 2;
            return(reserved * 8);
        }
Example #7
0
        public byte[] GetKeyVault(NANDReader reader, byte[] cpukey)
        {
            var kv = GetKeyVault(reader);

            _crypto.DecryptKv(ref kv, cpukey);
            if (_crypto.VerifyKvDecrypted(ref kv, cpukey))
            {
                return(kv);
            }
            throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataDecryptionFailed);
        }
Example #8
0
            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.Lba = (ushort)(baseBlock + offset);
                    ret.AddRange(reader.ReadBytes(BitOperations.GetSmallest(left, 0x4000)));
                    left -= BitOperations.GetSmallest(left, 0x4000);
                }
                return(ret.ToArray());
            }
Example #9
0
 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.Lba = (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);
 }
Example #10
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 #11
0
        public byte[] GetKeyVault(NANDReader reader, bool decryptWithKeyInNand = false)
        {
            reader.Lba = 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);
        }
Example #12
0
        public string GetLaunchIni(NANDReader reader)
        {
            if (reader.FsRoot == null)
            {
                reader.ScanForFsRootAndMobiles();
            }
            var nandfs = new NANDFileSystem();
            var fs     = nandfs.ParseFileSystem(ref reader);

            foreach (var fileSystemEntry in fs)
            {
                if (fileSystemEntry.Filename.Equals("launch.ini", StringComparison.CurrentCultureIgnoreCase))
                {
                    return(Encoding.ASCII.GetString(fileSystemEntry.GetData(ref reader)));
                }
            }
            throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataNotFound, "Launch.ini");
        }
Example #13
0
        public byte[] GetFcrt(NANDReader reader)
        {
            if (reader.FsRoot == null)
            {
                reader.ScanForFsRootAndMobiles();
            }
            var nandfs = new NANDFileSystem();
            var fs     = nandfs.ParseFileSystem(ref reader);

            foreach (var fileSystemEntry in fs)
            {
                if (fileSystemEntry.Filename.Equals("fcrt.bin", StringComparison.CurrentCultureIgnoreCase))
                {
                    return(fileSystemEntry.GetData(ref reader));
                }
            }
            throw new X360UtilsException(X360UtilsException.X360UtilsErrors.DataNotFound, "FCRT");
        }
Example #14
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 #15
0
        public static void TestMetaUtils(string file)
        {
            var reader   = new NANDReader(file);
            var metaType = reader.MetaType;

            for (long i = 0; i < reader.RawLength; i += 0x4200)
            {
                Debug.SendDebug("Seeking to page 0 of block 0x{0:X}", i / 0x4200);
                reader.RawSeek(i + 0x200, SeekOrigin.Begin);
                var meta = GetMetaData(reader.RawReadBytes(0x10));
                Main.SendInfo("Block 0x{0:X} Page 0 Information:\r\n", i / 0x4200);
                Main.SendInfo("LBA: 0x{0:X}\r\n", GetLba(ref meta));
                Main.SendInfo("Block Type: 0x{0:X}\r\n", GetBlockType(ref meta));
                Main.SendInfo("FSSize: 0x{0:X}\r\n", GetFsSize(ref meta));
                Main.SendInfo("FsFreePages: 0x{0:X}\r\n", GetFsFreePages(ref meta));
                Main.SendInfo("FsSequence: 0x{0:X}\r\n", GetFsSequence(ref meta));
                Main.SendInfo("BadBlock Marker: 0x{0:X}\r\n", GetBadBlockMarker(ref meta));
            }
        }
Example #16
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 #17
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());
        }
Example #18
0
 public FileSystemEntry[] ParseFileSystem(ref NANDReader reader)
 {
     return(ParseFileSystem(ref reader, reader.FsRoot));
 }
Example #19
0
        internal static MetaType DetectSpareType(NANDReader reader, bool firsttry = true)
        {
            if (!reader.HasSpare)
            {
                return(MetaType.MetaTypeNone);
            }
            if (firsttry)
            {
                reader.RawSeek(0x4400, SeekOrigin.Begin);
            }
            else
            {
                reader.RawSeek(reader.RawLength - 0x4000, SeekOrigin.Begin);
            }
            var tmp   = reader.RawReadBytes(0x10);
            var mdata = GetMetaData(tmp);

            if (!CheckIsBadBlockSpare(ref tmp, MetaType.MetaType0))
            {
                if (GetLbaRaw0(ref mdata) == 1)
                {
                    return(MetaType.MetaType0);
                }
                if (GetLbaRaw1(ref mdata) == 1)
                {
                    return(MetaType.MetaType1);
                }
            }
            if (!CheckIsBadBlockSpare(ref tmp, MetaType.MetaType2))
            {
                if (firsttry)
                {
                    reader.RawSeek(0x21200, SeekOrigin.Begin);
                }
                else if (reader.RawLength <= 0x4200000)
                {
                    reader.RawSeek(reader.RawLength - 0x4000, SeekOrigin.Begin);
                }
                else
                {
                    reader.RawSeek(0x4200000 - 0x4000, SeekOrigin.Begin);
                }
                tmp = reader.RawReadBytes(0x10);
                if (!CheckIsBadBlockSpare(ref tmp, MetaType.MetaType2))
                {
                    if (BlockIdFromSpare(ref tmp, MetaType.MetaType2) == 1)
                    {
                        return(MetaType.MetaType2);
                    }
                }
            }
            else if (Main.VerifyVerbosityLevel(1))
            {
                Main.SendInfo(firsttry ? "\r\nBlock 1 is bad!" : "\r\nThe last system block is bad!");
            }
            if (firsttry)
            {
                return(DetectSpareType(reader, false));
            }
            throw new X360UtilsException(X360UtilsException.X360UtilsErrors.UnkownMetaType);
        }
Example #20
0
 public byte[] GetData(ref NANDReader reader)
 {
     reader.Seek(Offset, SeekOrigin.Begin);
     return(reader.ReadBytes(Size));
 }
Example #21
0
 public byte[] GetBlock(ref NANDReader reader)
 {
     reader.Seek(Offset, SeekOrigin.Begin);
     return(reader.ReadBytes(0x4000));
 }