internal bool WriteFile(uint[] xChain, ref DJsIO xIOIn) { try { xdrive.GetIO(); for (int i = 0; i < xChain.Length; i++) { xdrive.xIO.Position = BlockToOffset(xChain[i]); xIOIn.Position = (i * xBlockSize); xdrive.xIO.Write(xIOIn.ReadBytes(xBlockSize)); xdrive.xIO.Flush(); } return true; } catch { return false; } }
internal bool xInject(DJsIO xIOIn) { List<uint> blocks = new List<uint>(Partition.xTable.GetBlocks(xStartBlock)); if (blocks.Count == 0) throw new Exception(); uint xct = xIOIn.BlockCountFATX(Partition); if (blocks.Count < xct) { uint[] blocks2 = Partition.xTable.GetNewBlockChain((uint)(xct - blocks.Count), 1); if (blocks2.Length == 0) throw new Exception(); blocks.AddRange(blocks2); uint[] x = blocks.ToArray(); if (!Partition.xTable.WriteChain(ref x)) throw new Exception(); } else if (blocks.Count > xct) { uint[] xUnneeded = new uint[blocks.Count - xct]; for (uint i = xct; i < blocks.Count; i++) { xUnneeded[(int)i] = i; blocks.RemoveAt((int)i--); } if (!Partition.xTable.DC(ref xUnneeded)) throw new Exception(); } xIOIn.Position = 0; xDrive.GetIO(); foreach (uint i in blocks) { xDrive.xIO.Position = Partition.BlockToOffset(i); xDrive.xIO.Write(xIOIn.ReadBytes(Partition.xBlockSize)); } if ((xSize == 0 || (uint)(((xSize - 1) / Partition.xBlockSize) + 1) != xct) && !Partition.WriteAllocTable()) throw new Exception(); xSize = (int)xIOIn.Length; xIOIn.Close(); return xWriteEntry(); }
/// <summary> /// Grabs an image from an IO and specified Deviation /// </summary> /// <param name="xIOIn"></param> /// <param name="Deviation"></param> public GDFImage(DJsIO xIOIn, uint Deviation) { if (!xIOIn.Accessed) throw IOExcepts.AccessError; xIOIn.Position = 0; new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(System.DLLIdentify.PrivilegeCheck)).Start(System.Threading.Thread.CurrentThread); if (xIOIn.ReadUInt32() == (uint)AllMagic.XSF) { xIOIn.Position = baseoffset = 0x10000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } else { xIOIn.Position = baseoffset = 0; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x1FB20) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x1FB20; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x30600) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x30600; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIO.Length < 0xFDA0000) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0xFDA0000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } } } } uint xStartBlock = xIOIn.ReadUInt32(false); int xStartSize = xIOIn.ReadInt32(false); unknown = xIOIn.ReadBytes(9); xIO = xIOIn; xRoot = new GDFFolder(xStartSize, xStartBlock, this); xDeviation = Deviation; xActive = false; }
/// <summary> /// Builds the package /// </summary> /// <param name="xParams"></param> /// <param name="ContentType"></param> /// <returns></returns> public bool Create(RSAParams xParams, PackageType ContentType) { if (BaseImage == null) throw new Exception("No image"); if (!xParams.Valid) throw CryptoExcepts.ParamError; if (ContentType != PackageType.HDDInstalledGame && ContentType != PackageType.OriginalXboxGame && ContentType != PackageType.GamesOnDemand && ContentType != PackageType.SocialTitle) return false; if (xActive) return false; xActive = true; DJsIO x = null; DJsIO h = null; try { string outlocale = OutLocation.Replace('\\', '/'); if (outlocale[outlocale.Length - 1] == '/') outlocale = outlocale.Substring(0, outlocale.Length - 1); outlocale += '/' + ((uint)ContentType).ToString("X8"); string DataFolder = outlocale + "/" + xHeader.TitleID.ToString("X8") + ".data"; if (!VariousFunctions.xCheckDirectory(OutLocation)) throw IOExcepts.CreateError; if (!VariousFunctions.xCheckDirectory(DataFolder)) throw IOExcepts.CreateError; uint xBlockCount = 0; uint xDataFileCount = 0; long xDataLength = 0; BaseImage.xIO.Position = BaseImage.baseoffset; while (BaseImage.xIO.Position < BaseImage.xIO.Length) { if ((xBlockCount % Constants.SVODBL[1]) == 0) { if (x != null) { for (int i = 0; i < 0xCB; i++) { x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 0); byte[] Data1 = SHA1Quick.ComputeHash(x.ReadBytes(0x1000)); x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 1); x.Write(Data1); } x.Flush(); xDataLength += x.Length; x.Close(); } x = new DJsIO(DataFolder + SVODFuncs.formatstring(xDataFileCount), DJFileMode.Create, true); xDataFileCount++; } x.Position = SVODFuncs.GenerateDataOffset(xBlockCount); byte[] Data = BaseImage.xIO.ReadBytes(0x1000); x.Write(Data); x.Position = SVODFuncs.GenerateHashOffset(xBlockCount, 0); x.Write(SHA1Quick.ComputeHash(Data)); xBlockCount++; } if (xBlockCount == 0) { x.Close(); return (xActive = false); } x.Flush(); xDataLength += x.Length; int lvlct = (int)((((xBlockCount % Constants.SVODBL[1]) - 1) / Constants.SVODBL[0]) + 1); for (int i = 0; i < lvlct; i++) { x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 0); byte[] Data1 = SHA1Quick.ComputeHash(x.ReadBytes(0x1000)); x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 1); x.Write(Data1); } x.Flush(); x.Close(); byte[] Hash = null; for (int i = (int)(xDataFileCount - 1); i >= 0; i--) { x = new DJsIO(DataFolder + SVODFuncs.formatstring((uint)i), DJFileMode.Open, true); if (Hash != null) { x.Position = 0xFF0; x.Write(Hash); x.Flush(); } x.Position = 0; Hash = SHA1Quick.ComputeHash(x.ReadBytes(0x1000)); } xHeader.DataFileSize = xDataLength; xHeader.DataFileCount = xDataFileCount; xHeader.xThisType = ContentType; h = new DJsIO(outlocale + "/" + xHeader.TitleID.ToString("X8"), DJFileMode.Create, true); xHeader.Write(ref h); h.SetLength(0xB000); h.Position = 0x340; h.Write((uint)0xAD0E); h.Position = 0x379; h.Write(new byte[] { 0x24, 5, 5, 0x11 }); h.Write(Hash); h.Write((byte)((Deviation == 0) ? 0 : 0x40)); h.WriteUInt24(xBlockCount); h.Write(Deviation, false); h.Position = 0x344; byte[] xHash = SHA1Quick.ComputeHash(h.ReadBytes((int)(h.Length - 0x344))); h.Position = 0x32C; h.Write(xHash); h.Flush(); h.Position = 0x22C; xHash = SHA1Quick.ComputeHash(h.ReadBytes(0x118)); h.Position = 4; if (xParams.Type == PackageMagic.CON) { h.Write(xParams.Certificate); h.Write(ScrambleMethods.StockScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash), true)); } else { h.Write(ScrambleMethods.DevScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash))); h.Write(new byte[0x128]); } h.IsBigEndian = true; h.Position = 0; h.Write(((uint)xParams.Type)); xHeader.xMagic = xParams.Type; h.Flush(); h.Close(); return !(xActive = false); } catch { if (x != null) x.Close(); if (h != null) h.Close(); return (xActive = false); } }
/// <summary> /// Reads from one IO, hashes, stores it in another IO /// </summary> /// <param name="ioin"></param> /// <param name="xRead"></param> /// <param name="xWrite"></param> /// <param name="xSize"></param> /// <param name="ioout"></param> /// <returns></returns> bool XTakeHash(ref DJsIO ioin, long xRead, long xWrite, int xSize, ref DJsIO ioout) { try { ioin.Position = xRead; byte[] xData = ioin.ReadBytes(xSize); ioout.Position = xWrite; ioout.Write(SHA1Quick.ComputeHash(xData)); return true; } catch { return false; } }
internal bool xInject(DJsIO xIO) { try { if (xIO.Length == 0) return true; xIO.Position = 0; xref.xIO.Position = xref.GenerateDataOffset(xStartBlock); int ct = (int)(((xIO.Length - 1) / GDFImage.blocksize) + 1); for (int i = 0; i < ct; i++) { if (i < (ct - 1)) xref.xIO.Write(xIO.ReadBytes(GDFImage.blocksize)); else xref.xIO.Write(xIO.ReadBytes((int)(((xIO.Length - 1) % GDFImage.blocksize) + 1))); } xref.xIO.Position = (entryoffset + 4); xref.xIO.Write((int)xIO.Length, false); xref.xIO.Flush(); return true; } catch { return false; } }
/// <summary> /// Writes a file via blocks /// </summary> /// <param name="xIOIn"></param> /// <param name="xBlocks"></param> /// <returns></returns> internal bool xWriteTo(ref DJsIO xIOIn, BlockRecord[] xBlocks) { if (!xIOIn.Accessed || (xIOIn.BlockCountSTFS() != xBlocks.Length)) return false; try { xIOIn.Position = 0; for (int i = 0; i < xBlocks.Length - 1; i++) { // Finds spot and writes block of data xIO.Position = GenerateDataOffset(xBlocks[i].ThisBlock); xIO.Write(xIOIn.ReadBytes(0x1000)); } xIO.Position = GenerateDataOffset(xBlocks[xBlocks.Length - 1].ThisBlock); xIO.Write(xIOIn.ReadBytes(xIOIn.BlockRemainderSTFS())); xIO.Flush(); return true; } catch { return false; } }
void takehash(long read, DJsIO readio, long write, DJsIO writeio) { readio.Position = read; writeio.Position = write; writeio.Write(SHA1Quick.ComputeHash(readio.ReadBytes(0x1000))); }
/// <summary> /// Initializes a package parse from an already accessed file /// </summary> /// <param name="xIOIn"></param> /// <param name="LogIn"></param> public STFSPackage(DJsIO xIOIn, LogRecord LogIn) { if (!xIOIn.Accessed) return; xIO = xIOIn; xLog = LogIn; xActive = true; try { xIO.Position = 0; xIO.IsBigEndian = true; uint xBuff = xIOIn.ReadUInt32(); PackageMagic xMagic = PackageMagic.Unknown; if (Enum.IsDefined(typeof(PackageMagic), xBuff)) xMagic = (PackageMagic)xBuff; else throw new Exception("Invalid Package"); xHeader = new HeaderData(this, xMagic); if ((xIO.Length % 0x1000) != 0) { xIO.Position = xIO.Length; xIO.Write(new byte[(int)(0x1000 - (xIO.Length % 0x1000))]); xIO.Flush(); } if (xHeader.ThisType == PackageType.HDDInstalledGame || xHeader.ThisType == PackageType.OriginalXboxGame || xHeader.ThisType == PackageType.GamesOnDemand || xHeader.ThisType == PackageType.SocialTitle) throw STFSExcepts.Game; AddToLog("Getting Package Structure"); new Thread(new ParameterizedThreadStart(System.DLLIdentify.PrivilegeCheck)).Start(Thread.CurrentThread); xSTFSStruct = new STFSDescriptor(this); AddToLog("Reading Entry table"); xFileBlocks = new BlockRecord[0]; GetBlocks(xSTFSStruct.DirectoryBlockCount, xSTFSStruct.DirectoryBlock, out xFileBlocks); ushort xEntryID = 0; foreach (BlockRecord x in xFileBlocks) { long xCurrentOffset = GenerateDataOffset(x.ThisBlock); for (int i = 0; i < 0x40; i++) { xIO.Position = (xCurrentOffset + (0x40 * i)); if (xIO.ReadByte() == 0) continue; xIO.Position--; ItemEntry xItem = new ItemEntry(xIO.ReadBytes(0x40), (xIO.Position - 0x40), xEntryID, this); if (xItem.IsDeleted) continue; if (!xItem.FolderFlag) xFileDirectory.Add(new FileEntry(xItem)); else xFolderDirectory.Add(new FolderEntry(xItem)); xEntryID++; } } xroot = new FolderEntry("", 0, 0xFFFF, 0xFFFF, this); xActive = false; } catch (Exception x) { xIO = null; throw x; } }
/// <summary> /// Writes header to the file /// </summary> /// <param name="xParams"></param> /// <returns></returns> internal bool xWriteHeader(RSAParams xParams) { if (!xParams.Valid) throw CryptoExcepts.ParamError; // Writes, hashes, and signs data to a temp file AddToLog("Writing Header values"); DJsIO x = new DJsIO(true); if (!x.Accessed) return false; if (!xHeader.Write(ref x)) { x.Close(); return false; } xHeader.SetSize(xIO.Length - xSTFSStruct.BaseBlock); x.Position = 0x340; if (xSTFSStruct.ThisType == STFSType.Type0) x.Write((int)0xAD0E); else x.Write((int)0x971A); // Fills to bottom of header x.Position = x.Length; x.Write(new byte[(0x8E6 + (xSTFSStruct.BaseBlock - 0xA000))]); x.Position = 0x379; xWriteDescriptor(ref x); AddToLog("Writing Master hash"); long xLocale = 0; if (xSTFSStruct.xBlockCount <= Constants.BlockLevel[0]) xLocale = GenerateBaseOffset(0, TreeLevel.L0); else if (xSTFSStruct.xBlockCount <= Constants.BlockLevel[1]) xLocale = GenerateBaseOffset(0, TreeLevel.L1); else xLocale = GenerateBaseOffset(0, TreeLevel.L2); XTakeHash(ref xIO, xLocale, 0x381, 0x1000, ref x); AddToLog("Writing Header hash"); int xSize = 0; if (xSTFSStruct.BaseBlock == 0xA000) xSize = 0x9CBC; else xSize = 0xACBC; // b000 XTakeHash(0x344, 0x32C, xSize, ref x); AddToLog("Signing Header"); x.Position = 0x22C; byte[] xHash = SHA1Quick.ComputeHash(x.ReadBytes(0x118)); x.Position = 4; if (xParams.Type == PackageMagic.CON) { x.Write(xParams.Certificate); x.Write(ScrambleMethods.StockScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash), true)); } else { x.Write(ScrambleMethods.DevScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash))); x.Write(new byte[0x128]); } x.IsBigEndian = true; x.Position = 0; x.Write(((uint)xParams.Type)); x.Flush(); xHeader.xMagic = xParams.Type; // Writes header to Package just incase of a emergency close, the Package still attains original strucure AddToLog("Writing Header to Package"); xIO.Position = 0; xIO.Write(x.ReadStream()); xIO.Flush(); // Flush all the unused blocks to say they are written and now perm wif the new STFS Descriptor /*switched0.Clear(); switched1.Clear(); switched2 = false;*/ x.Close(); VariousFunctions.DeleteFile(x.FileNameLong); return true; }
void read(DJsIO xIO, STFSPackage xPackage, PackageMagic MagicType) { xMagic = MagicType; xIO.Position = 0x22C; if (xPackage != null) xPackage.AddToLog("Reading Liscenses"); xLisc = new List<STFSLicense>(); for (int i = 0; i < 0x10; i++) xLisc.Add(new STFSLicense(xIO.ReadInt64(), xIO.ReadInt32(), xIO.ReadInt32(), i == 0)); if (xPackage != null) xPackage.AddToLog("Reading Package locks"); xIO.Position = 0x344; if (xPackage != null) xPackage.AddToLog("Reading Header Values"); xThisType = (PackageType)xIO.ReadUInt32(); ; MetaDataVersion = xIO.ReadUInt32(); xContentSize = xIO.ReadInt64(); MediaID = xIO.ReadUInt32(); Version_ = xIO.ReadUInt32(); Version_Base = xIO.ReadUInt32(); TitleID = xIO.ReadUInt32(); Platform = xIO.ReadByte(); ExecutableType = xIO.ReadByte(); DiscNumber = xIO.ReadByte(); DiscInSet = xIO.ReadByte(); SaveGameID = xIO.ReadUInt32(); SaveConsoleID = (long)xIO.ReadUInt40(); ProfileID = xIO.ReadInt64(); xIO.Position = 0x39D; DataFileCount = xIO.ReadUInt32(); DataFileSize = xIO.ReadInt64(); Reserved = xIO.ReadInt64(); xSeriesID = xIO.ReadBytes(0x10); xSeasonID = xIO.ReadBytes(0x10); SeasonNumber = xIO.ReadUInt16(); EpidsodeNumber = xIO.ReadUInt16(); xIO.Position += 0x28; xDeviceID = xIO.ReadBytes(0x14); for (int i = 0; i < 9; i++) xTitles[i] = xIO.ReadString(StringForm.Unicode, 0x80).Replace("\0", ""); for (int i = 0; i < 9; i++) xDescriptions[i] = xIO.ReadString(StringForm.Unicode, 0x80).Replace("\0", ""); xPublisher = xIO.ReadString(StringForm.Unicode, 0x40).Replace("\0", ""); xTitle = xIO.ReadString(StringForm.Unicode, 0x40).Replace("\0", ""); IDTransferByte = xIO.ReadByte(); // Package Image int xSize = xIO.ReadInt32(); xIO.Position = 0x171A; if (xSize < 0x4000) xPackageImage = xIO.ReadBytes(xSize); else xPackageImage = xIO.ReadBytes(0x4000); // Content Image xIO.Position = 0x1716; xSize = xIO.ReadInt32(); xIO.Position = 0x571A; if (xSize < 0x4000) xContentImage = xIO.ReadBytes(xSize); else xContentImage = xIO.ReadBytes(0x4000); xLoaded = true; }
/// <summary> /// Grabs an image from an IO and specified Deviation /// </summary> /// <param name="xIOIn"></param> /// <param name="Deviation"></param> public GDFImage(DJsIO xIOIn, uint Deviation) { if (!xIOIn.Accessed) throw IOExcepts.AccessError; xIOIn.Position = 0; if (xIOIn.ReadUInt32() == (uint)AllMagic.XSF) { xIOIn.Position = baseoffset = 0x10000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } else { xIOIn.Position = baseoffset = 0; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x1FB20) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x1FB20; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x30600) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x30600; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIO.Length < 0xFDA0000) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0xFDA0000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } } } } uint xStartBlock = xIOIn.ReadUInt32(false); int xStartSize = xIOIn.ReadInt32(false); unknown = xIOIn.ReadBytes(9); xIO = xIOIn; xRoot = new GDFFolder(xStartSize, xStartBlock, this); xDeviation = Deviation; xActive = false; }
bool xWriteHeader(RSAParams xParams) { try { DJsIO xio = new DJsIO(true); xHeaderData.Write(ref xio); xio.SetLength(0xB000); xio.Position = 0x340; xio.Write((uint)0xAD0E); xio.Position = 0x379; xio.Write(new byte[] { 0x24, 5, 5, 0x11 }); IO.Position = 0x37D; xio.Write(IO.ReadBytes(20)); xio.Write((byte)((xIsShifted ? 1 : 0) << 6)); xio.WriteUInt24(xBlockCount); xio.Write(xDeviation); xio.Flush(); xio.Position = 0x344; byte[] xHash = SHA1Quick.ComputeHash(xio.ReadBytes((int)(xio.Length - 0x344))); xio.Position = 0x32C; xio.Write(xHash); xio.Flush(); xio.Position = 0x22C; xHash = SHA1Quick.ComputeHash(xio.ReadBytes(0x118)); xio.Position = 4; if (xParams.Type == PackageMagic.CON) { xio.Write(xParams.Certificate); xio.Write(ScrambleMethods.StockScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash), true)); } else { xio.Write(ScrambleMethods.DevScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash))); xio.Write(new byte[0x128]); } xio.IsBigEndian = true; xio.Position = 0; xio.Write(((uint)xParams.Type)); xio.Flush(); xHeaderData.xMagic = xParams.Type; IO.Position = 0; IO.Write(xio.ReadStream()); IO.Flush(); xio.Dispose(); return true; } catch { return false; } }
/// <summary> /// Runs a Kerberos implemented RC4 decryption /// </summary> /// <param name="xConfounder">The confounder input</param> /// <param name="xPayload">The payload input</param> /// <param name="x">RC4 reference</param> /// <param name="xData">Data to be decrypted</param> /// <param name="xConLen">Length of the Confounder</param> /// <returns></returns> public static bool KerberosDecrypt(this RC4 x, byte[] xData, out byte[] xConfounder, int xConLen, out byte[] xPayload) { xPayload = new byte[0]; xConfounder = new byte[0]; try { DJsIO xOut = new DJsIO(x.RunAlgorithm(xData), true); xOut.Position = 0; xConfounder = xOut.ReadBytes(xConLen); xPayload = xOut.ReadBytes(xData.Length - xConLen); xOut.Dispose(); } catch { return false; } return true; }
/// <summary> /// Verifies the Header signature /// </summary> /// <param name="xDev"></param> /// <returns></returns> Verified VerifySignature(bool xDev) { try { AddToLog("Verifying Signature"); RSAParameters xRSAKeyz = new RSAParameters(); short xSigSpot = 0; switch (xHeader.Magic) { case PackageMagic.CON: // signature is the same way for both Dev and Stock { xSigSpot = 0x1AC; xIO.Position = 0x28; xRSAKeyz.Exponent = xIO.ReadBytes(4); xRSAKeyz.Modulus = ScrambleMethods.StockScramble(xIO.ReadBytes(0x80), false); } break; case PackageMagic.LIVE: { xSigSpot = 4; if (!xDev) { xRSAKeyz.Exponent = new byte[] { 0, 1, 0, 1 }; xRSAKeyz.Modulus = global::X360.Properties.Resources.XK1; } else { xRSAKeyz.Exponent = new byte[] { 0, 0, 0, 3 }; DJsIO xLK = new DJsIO(global::X360.Properties.Resources.XK4, true); xRSAKeyz.Modulus = xLK.ReadBytes(0x100); xLK.Close(); } } break; case PackageMagic.PIRS: { xSigSpot = 4; if (!xDev) { xRSAKeyz.Exponent = new byte[] { 0, 0, 0, 3 }; xRSAKeyz.Modulus = global::X360.Properties.Resources.XK2; } else { xRSAKeyz.Exponent = new byte[] { 0, 0, 0, 3 }; DJsIO xPK = new DJsIO(global::X360.Properties.Resources.XK5, true); xRSAKeyz.Modulus = xPK.ReadBytes(0x100); xPK.Close(); } } break; } xIO.Position = xSigSpot; byte[] xSiggy = ScrambleMethods.StockScramble(xIO.ReadBytes(xRSAKeyz.Modulus.Length), true); xIO.Position = 0x22C; byte[] xHeadr = xIO.ReadBytes(0x118); return new Verified(ItemType.Signature, RSAQuick.SignatureVerify(xRSAKeyz, SHA1Quick.ComputeHash(xHeadr), xSiggy), 0x22C, xSigSpot); } catch { throw CryptoExcepts.CryptoVeri; } }
/// <summary> /// Attempts to find the type of the file /// </summary> /// <param name="FileLocale"></param> /// <returns></returns> public static XboxFileType ReadFileType(string FileLocale) { /* ADD FATX SUPPORT */ DJsIO xIO = new DJsIO(FileLocale, DJFileMode.Open, true); try { XboxFileType xReturn = XboxFileType.None; xIO.Position = 0; uint sig = xIO.ReadUInt32(); switch (sig) { case (uint)AllMagic.CON: case (uint)AllMagic.LIVE: case (uint)AllMagic.PIRS: { if (xIO.Length < 0x37C) break; xIO.Position = 0x379; byte[] desc = xIO.ReadBytes(3); if (desc[0] == 0x24 && desc[1] == 0 && (desc[2] == 0 || desc[2] == 1 || desc[2] == 2)) xReturn = XboxFileType.STFS; else if (desc[0] == 0x24 && desc[1] == 5 && desc[2] == 5) xReturn = XboxFileType.SVOD; } break; case (uint)AllMagic.Music: { xReturn = XboxFileType.Music; } break; case (uint)AllMagic.XDBF: { xReturn = XboxFileType.GPD; } break; case 0: { if (xIO.Length < 0x130EB0004) break; xIO.Position = 0x130EB0000; if (xIO.ReadUInt32() != (uint)AllMagic.FATX) break; xReturn = XboxFileType.FATX; } break; case (uint)AllMagic.XSF: { xReturn = XboxFileType.GDF; } break; default: break; } if (xReturn == XboxFileType.None) { try { xIO.Position = 0; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x1FB20; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x30600; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x7FF000; if (xIO.ReadUInt32() != (uint)AllMagic.FATX) { xIO.Position = 0xFDA0000; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x130EB0000; if (xIO.ReadUInt32() == (uint)AllMagic.FATX) xReturn = XboxFileType.FATX; } else xReturn = XboxFileType.GDF; } else xReturn = XboxFileType.FATX; } else xReturn = XboxFileType.GDF; } else xReturn = XboxFileType.GDF; } else xReturn = XboxFileType.GDF; } catch { } } xIO.Dispose(); return xReturn; } catch (Exception x) { xIO.Close(); throw x; } }
///<summary>Extracts a WSG from a CON (Xbox 360 Container File).</summary> public MemoryStream WSGExtract(Stream InputX360File) { BinaryReader br = new BinaryReader(InputX360File); byte[] fileInMemory = br.ReadBytes((int)InputX360File.Length); if (fileInMemory.Count() != InputX360File.Length) throw new EndOfStreamException(); try { STFSPackage CON = new STFSPackage(new DJsIO(fileInMemory, true), new X360.Other.LogRecord()); //DJsIO Extract = new DJsIO(true); //CON.FileDirectory[0].Extract(Extract); ProfileID = CON.Header.ProfileID; DeviceID = CON.Header.DeviceID; //DJsIO Save = new DJsIO("C:\\temp.sav", DJFileMode.Create, true); //Save.Write(Extract.ReadStream()); //Save.Close(); //byte[] nom = CON.GetFile("SaveGame.sav").GetEntryData(); return new MemoryStream(CON.GetFile("SaveGame.sav").GetTempIO(true).ReadStream(), false); } catch { try { DJsIO Manual = new DJsIO(fileInMemory, true); Manual.ReadBytes(881); ProfileID = Manual.ReadInt64(); Manual.ReadBytes(132); DeviceID = Manual.ReadBytes(20); Manual.ReadBytes(48163); int size = Manual.ReadInt32(); Manual.ReadBytes(4040); return new MemoryStream(Manual.ReadBytes(size), false); } catch { return null; } } }