/// <summary> /// Swaps bytes in 8 byte blocks, xReverse true if reverse each 8 byte blocks /// </summary> /// <param name="xPiece"></param> /// <param name="xReverse"></param> /// <returns></returns> public static byte[] StockScramble(byte[] xPiece, bool xReverse) { if ((xPiece.Length % 8) != 0) { throw new Exception("Input not divisible by 8"); } var xStream = new DJsIO(xPiece, true); for (var i = 0; i < (xPiece.Length / 2); i += 8) { xStream.Position = i; var xPart1 = xStream.ReadBytes(8); xStream.Position = (xPiece.Length - i - 8); var xPart2 = xStream.ReadBytes(8); xStream.Position = i; xStream.Write(xPart2); xStream.Position = (xPiece.Length - i - 8); xStream.Write(xPart1); xStream.Flush(); } if (!xReverse) { return(xPiece); } for (var i = 0; i < xPiece.Length; i += 8) { Array.Reverse(xPiece, i, 8); } return(xPiece); }
/// <summary> /// Special scramble method /// </summary> /// <param name="xPiece"></param> /// <returns></returns> public static byte[] DJScramble(byte[] xPiece) { if ((xPiece.Length % 8) != 0) { throw new Exception("Input not divisible by 8"); } int xSpot = 5, xCurrent; var xStream = new DJsIO(xPiece, true) { Position = 0 }; var xHalf1 = xStream.ReadBytes((xPiece.Length / 2)); var xHalf2 = xStream.ReadBytes((xPiece.Length / 2)); xStream.Position = 0; xStream.Write(xHalf2); xStream.Write(xHalf1); xStream.Flush(); xStream.Close(); for (var i = 0; i < xPiece.Length; i += xCurrent) { Array.Reverse(xPiece, i, xSpot); xCurrent = xSpot; xSpot = xSpot == 5 ? 3 : 5; } return(xPiece); }
/// <summary> /// Swaps bytes in 8 byte blocks, xReverse true if reverse each 8 byte blocks /// </summary> /// <param name="xPiece"></param> /// <param name="xReverse"></param> /// <returns></returns> public static byte[] StockScramble(byte[] xPiece, bool xReverse) { if ((xPiece.Length % 8) != 0) { throw new Exception("Input not divisible by 8"); } DJsIO xStream = new DJsIO(xPiece, true); for (int i = 0; i < (xPiece.Length / 2); i += 8) { xStream.Position = i; byte[] xPart1 = xStream.ReadBytes(8); xStream.Position = (xPiece.Length - i - 8); byte[] xPart2 = xStream.ReadBytes(8); xStream.Position = i; xStream.Write(xPart2); xStream.Position = (xPiece.Length - i - 8); xStream.Write(xPart1); xStream.Flush(); } xStream.Position = 0; var bs = xStream.GetBytes(); if (xReverse) { for (int i = 0; i < bs.Length; i += 8) { Array.Reverse(bs, i, 8); } } return(bs); //return xPiece; }
/// <summary> /// Initializes a Strong Signed key type of Kit 360's /// </summary> /// <param name="xTypeIn"></param> public RSAParams(StrongSigned xTypeIn) { DJsIO xReader; switch (xTypeIn) { case StrongSigned.LIVE: xReader = new DJsIO(Properties.Resources.XK4, true); break; case StrongSigned.PIRS: xReader = new DJsIO(Properties.Resources.XK5, true); break; default: throw STFSExcepts.NotStrong; } xK.Exponent = new byte[] { 0, 0, 0, 3 }; xK.D = Properties.Resources.XK3; xReader.Position = 0; xK.Modulus = xReader.ReadBytes(0x100); xK.P = xReader.ReadBytes(0x80); xK.Q = xReader.ReadBytes(0x80); xK.DP = xReader.ReadBytes(0x80); xK.DQ = xReader.ReadBytes(0x80); xK.InverseQ = xReader.ReadBytes(0x80); xReader.Dispose(); xM = xTypeIn == StrongSigned.LIVE ? PackageMagic.LIVE : PackageMagic.PIRS; xV = true; }
private void listBox1_DragDrop(object sender, DragEventArgs e) { menuStrip1.Enabled = groupPanel1.Enabled = listBox1.Enabled = false; string[] xfiles = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string x in xfiles) { DJsIO y = null; try { y = new DJsIO(x, DJFileMode.Open, true); } catch { continue; } if (!y.Accessed) { continue; } y.Position = 0; if (y.ReadUInt32() == (uint)AllMagic.CON) { listBox1.Items.Add(x); } y.Dispose(); listBox1.SelectedIndex = listBox1.Items.Count - 1; Application.DoEvents(); if (checkBoxX3.Checked) { fix(listBox1.Items.Count - 1); } } menuStrip1.Enabled = groupPanel1.Enabled = listBox1.Enabled = true; }
/// <summary> /// Grabs the pass code /// </summary> /// <returns></returns> public PassCode[] GetPassCode() { DJsIO xTemp = GetDecrypt(); if (xTemp == null) { return(new PassCode[0]); } xTemp.Position = 0; if (((xTemp.ReadByte() >> 4) & 1) == 1) { List <PassCode> xReturn = new List <PassCode>(); for (int i = 0; i < 4; i++) { xReturn.Add((PassCode)xTemp.ReadByte()); } if (!xReturn.Contains(PassCode.Null)) { return(xReturn.ToArray()); } } xTemp.Position = 0; xTemp.Write((byte)((xIsLive ? 1 : 0) << 5 | 0 << 4)); xTemp.Position = 0x38; xTemp.Write(new byte[4]); xEncrypt(ref xTemp); return(new PassCode[0]); }
bool xEncrypt(ref DJsIO xNewPayload) { try { if (!xSuccess) { return(false); } if (xIsLive) { byte[] xService = (ThisType == AccountType.Stock ? new byte[] { 0x50, 0x52, 0x4F, 0x44 } : // PROD new byte[] { 0x50, 0x41, 0x53, 0x54 }); // PART xNewPayload.Position = 0x34; xNewPayload.Write(xService); xNewPayload.Flush(); } List <byte> xReturn = new List <byte>(); byte[] xConfounder = xRC4.NewConfounder(8); byte[] NewPay = xNewPayload.ReadStream(); xNewPayload.Dispose(); byte[] xHeaderKey = xComputeHeaderKey(xConfounder, NewPay); xRC4.KeyBinary = xComputeRC4Key(xHeaderKey); xReturn.AddRange(xHeaderKey); xReturn.AddRange(xRC4.KerberosEncrypt(ref xConfounder, ref NewPay)); IO.Position = 0; IO.Write(xReturn.ToArray()); IO.Flush(); return(true); } catch { return(false); } }
/// <summary> /// Initializes this object /// </summary> /// <param name="FileLocale"></param> public MusicFile(string FileLocale) { xActive = true; DJsIO xIO = new DJsIO(FileLocale, DJFileMode.Open, true); if (!xIO.Accessed) { throw STFSExcepts.ParseError; } try { xIO.Position = 0; xIO.IsBigEndian = true; if (xIO.ReadUInt32() != 0x464D494D) { throw MusicExcepts.NotMusic; } xIO.Position = 0xC; so = xIO.ReadString(StringForm.Unicode, 0x100); al = xIO.ReadString(StringForm.Unicode, 0x100); ar = xIO.ReadString(StringForm.Unicode, 0x100); xIO.Position += 0x200; ge = xIO.ReadString(StringForm.Unicode, 0x100); IO = xIO; xActive = false; } catch { xIO.Dispose(); throw STFSExcepts.ParseError; } }
private void listView1_DragDrop(object sender, DragEventArgs e) { List <string> xData = new List <string>((string[])e.Data.GetData(DataFormats.FileDrop)); List <DJsIO> xIO = new List <DJsIO>(); for (int i = 0; i < xData.Count; i++) { DJsIO blah = new DJsIO(xData[i], DJFileMode.Open, true); if (blah.Accessed) { xIO.Add(blah); } } if (xIO.Count == 0) { return; } if (MessageBox.Show("Are you sure you want to add " + ((xIO.Count == 1) ? "this accessed file?" : ("these " + xIO.Count.ToString() + " accessed files?")), "Rawr?", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } foreach (DJsIO x in xIO) { xPackage.MakeFile(x.FileNameShort, x, ((FolderEntry)advTree1.SelectedNode.DataKey).EntryID, AddType.NoOverWrite); } xReturn_NodeClick(advTree1.SelectedNode, null); }
/// <summary> /// Initializes an instance /// </summary> /// <param name="xAcc"></param> /// <param name="xType"></param> /// <param name="CreateBackup"></param> public UserAccount(DJsIO xAcc, AccountType xType, bool CreateBackup) { if (xAcc.Length != 404 || !Enum.IsDefined(typeof(AccountType), xType)) { return; } IO = xAcc; xHS = new HMACSHA1(); ThisType = xType; DJsIO xfill; if (xDecrypt(out xfill)) { if (CreateBackup) { xBackup = new DJsIO(true); xBackup.Position = 0; xBackup.Write(IO.ReadStream()); } xfill.Position = 0; if (((xfill.ReadByte() >> 5) & 1) == 1) { xIsLive = true; xfill.Position = 0x28; xXUID = xfill.ReadUInt64(); } xSuccess = true; } }
internal bool xExtract(ref DJsIO xIOOut) { try { xIOOut.Position = 0; uint[] xChain = Partition.xTable.GetBlocks(xStartBlock); uint xct = (uint)(((xSize - 1) / Partition.xBlockSize) + 1); if (xChain.Length < xct) { return(false); } xDrive.GetIO(); for (uint i = 0; i < xct - 1; i++) { xDrive.xIO.Position = Partition.BlockToOffset(xChain[(int)i]); xIOOut.Write(xDrive.xIO.ReadBytes(Partition.xBlockSize)); } int xleft = (int)(((xSize - 1) % Partition.xBlockSize) + 1); xDrive.xIO.Position = Partition.BlockToOffset(xChain[(int)xct - 1]); xIOOut.Write(xDrive.xIO.ReadBytes(xleft)); xIOOut.Flush(); return(true); } catch { return(false); } }
public static Package Load(DJsIO dj, bool readData = false) { Package ret = null; try { STFSPackage pk = null; try { pk = new STFSPackage(dj, null); } catch { if (pk != null) pk.CloseIO(); } if (pk != null) { if (pk.ParseSuccess == true) { ret = new Package(pk, readData, dj); } pk.CloseIO(); } } catch { } return ret; }
internal Package(STFSPackage pk, bool readData = true, DJsIO dj = null) { this.package = pk; this.dj = dj; ReadData(readData, this); }
public static Package Load(string fileName, bool readData = false) { Package ret = null; try { DJsIO dj = new DJsIO(fileName, DJFileMode.Open, true); STFSPackage pk = null; try { pk = new STFSPackage(dj, null); } catch { if (pk != null) pk.CloseIO(); } if (pk != null) { if (pk.ParseSuccess == true) { ret = new Package(pk, readData); } pk.CloseIO(); } } catch { } return ret; }
/* Note: Have plans for safer and better manipulation to prevent * minimal block loss to human error */ /// <summary> /// Adds a folder /// </summary> /// <param name="FolderName"></param> /// <returns></returns> public bool AddFolder(string FolderName) { FolderName.IsValidXboxName(); if (xDrive.ActiveCheck()) { return(false); } try { FATXReadContents xconts = xRead(); foreach (FATXFolderEntry x in xconts.xfolds) { if (x.Name == FolderName) { return(xDrive.xActive = false); } } DJsIO xIOIn = new DJsIO(new byte[Partition.xBlockSize], true); uint xnew = 0; long xpos = GetNewEntryPos(out xnew); if (xpos == -1) { return(xDrive.xActive = false); } uint[] blocks = Partition.xTable.GetNewBlockChain(xIOIn.BlockCountFATX(Partition), xnew + 1); if (blocks.Length == 0) { return(xDrive.xActive = false); } if (!Partition.WriteFile(blocks, ref xIOIn)) { return(xDrive.xActive = false); } FATXEntry y = new FATXEntry(FolderName, blocks[0], (int)xIOIn.Length, xpos, true, ref xDrive); if (!y.xWriteEntry()) { return(xDrive.xActive = false); } if (xnew > 0) { List <uint> fileblocks = new List <uint>(Partition.xTable.GetBlocks(xStartBlock)); fileblocks.Add(xnew); uint[] xtemp = fileblocks.ToArray(); if (!Partition.xTable.WriteChain(ref xtemp)) { return(xDrive.xActive = false); } } if (!Partition.xTable.WriteChain(ref blocks)) { return(xDrive.xActive = false); } if (Partition.WriteAllocTable()) { return(!(xDrive.xActive = false)); } return(xDrive.xActive = false); } catch { return(xDrive.xActive = false); } }
bool xExtract(string xOut, bool Sub) { if (!VariousFunctions.xCheckDirectory(xOut)) { return(false); } FATXReadContents xread = xRead(); if (xread == null) { return(false); } foreach (FATXFileEntry x in xread.Files) { DJsIO xIOOut = new DJsIO(xOut + "/" + x.Name, DJFileMode.Create, true); if (!xIOOut.Accessed) { continue; } x.xExtract(ref xIOOut); xIOOut.Dispose(); } if (!Sub) { return(true); } foreach (FATXFolderEntry x in xread.Folders) { x.xExtract(xOut + "/" + x.Name, Sub); } return(true); }
/// <summary> /// Reads a GPD from the Titles Played index of the User GPD /// </summary> /// <param name="ID"></param> /// <param name="xEntry"></param> /// <returns></returns> public GameGPD ReadGame(uint ID, out FileEntry xEntry) { xEntry = null; if (!ParseCheck()) { return(null); } if (UserGPD == null) { return(null); } FileEntry x = GetFile(ID.ToString("X") + ".gpd"); if (x == null) { return(null); } DJsIO y = x.GetTempIO(true); if (y == null || !y.Accessed) { y.Close(); VariousFunctions.DeleteFile(y.FileNameLong); return(null); } y.Close(); GameGPD z = new GameGPD(y.FileNameLong, ID); if (z.IsValid) { xEntry = x; return(z); } return(null); }
/// <summary> /// Extract the file /// </summary> /// <param name="OutLocation"></param> /// <returns></returns> public bool Extract(string OutLocation) { if (xDrive.ActiveCheck()) { return(false); } bool xReturn = false; DJsIO xIO = new DJsIO(true); try { xReturn = xExtract(ref xIO); xIO.Close(); if (xReturn) { xReturn = VariousFunctions.MoveFile(xIO.FileNameLong, OutLocation); } } catch { xIO.Close(); xReturn = false; } VariousFunctions.DeleteFile(xIO.FileNameLong); xDrive.xActive = false; return(xReturn); }
public void importfromprofile() { OpenFileDialog dialog = new OpenFileDialog(); dialog.Title = "Open a xbox 360 profile"; dialog.Filter = "Xbox 360 profile|*.*"; DialogResult result = dialog.ShowDialog(); if (result == DialogResult.OK) // Test result. { try { DJsIO io = new DJsIO(dialog.FileName, DJFileMode.Open, true); io.Position = 0x371; this.Profileid = io.ReadHexString(8); io.Close(); //xPackage3.STFS.Package sts = new xPackage3.STFS.Package(dialog.FileName); STFSPackage stfs = new STFSPackage(dialog.FileName, null); ProfilePackage xFile = new ProfilePackage(ref stfs); string gamertag = xFile.UserFile.GetGamertag(); this.ProfileName = gamertag; xFile.CloseIO(); stfs.CloseIO(); //this.Profileid = stfs.Header.Title_Package; } catch (Exception e) { } } }
internal void GetIO() { if (IsDriveIO && xType != DriveTypes.USBFlashDrive) { // Close previous handle if (xIO != null) { xIO.Close(); // Make a new handle to a drive xIO.OpenAgain(); } else { xIO = new DriveIO(ref xDrive, true); } } else if (xType == DriveTypes.USBFlashDrive && xIO == null || !xIO.Accessed) { List <string> files = new List <string>(); for (int i = 0; i <= 9999; i++) { string file = xDrive.DeviceName + @"\Xbox360\Data" + i.ToString("000#"); if (File.Exists(file)) { files.Add(file); } else { break; } } xIO = new MultiFileIO(files.ToArray(), true); } }
internal bool LoadDetails() { try { xRef.xIO.Position = Offset + 4; // int32 for Struct size is constant (0x1C) xid = xRef.xIO.ReadInt32(); imageID = xRef.xIO.ReadInt32(); Worth = xRef.xIO.ReadUInt32(); Flg = xRef.xIO.ReadBytes(4); TimeL = xRef.xIO.ReadInt64(); try { DJsIO xStrings = new DJsIO(xRef.xIO.ReadBytes(Size - 0x1C), true); xTitle = xStrings.ReadString(StringForm.Unicode); xDescription1 = xStrings.ReadString(StringForm.Unicode); xDescription2 = xStrings.ReadString(StringForm.Unicode); } catch { xTitle = ""; xDescription1 = ""; xDescription2 = ""; } xLoaded = true; return(true); } catch { return(false); } }
internal bool xExtract(string OutLocation, bool SubItems) { if (OutLocation == null || OutLocation == "") { return(false); } OutLocation = OutLocation.xExtractLegitPath(); if (!VariousFunctions.xCheckDirectory(OutLocation)) { return(false); } GDFContents xConts = xRead(); foreach (GDFFile x in xConts.Files) { DJsIO y = new DJsIO(true); try { if (x.xExtract(y)) { y.Close(); VariousFunctions.MoveFile(y.FileNameLong, OutLocation + "/" + x.Name); } } catch { y.Close(); } VariousFunctions.DeleteFile(y.FileNameLong); } foreach (GDFFolder x in xConts.xFolders) { try { x.xExtract(OutLocation + "/" + x.Name, SubItems); } catch { } } return(true); }
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> /// Overwrite the file /// </summary> /// <param name="FileLocale"></param> /// <returns></returns> public bool Inject(string FileLocale) { if (!xref.ActiveCheck()) { return(false); } DJsIO xIO = null; bool success = false; try { xIO = new DJsIO(FileLocale, DJFileMode.Open, true); if (!xIO.Accessed) { throw new Exception(); } success = xInject(xIO); } catch { success = false; } if (xIO != null) { xIO.Dispose(); } return(success & !(xref.xActive = false)); }
/// <summary> /// Initializes from an IO /// </summary> /// <param name="x"></param> /// <param name="LogIn"></param> public ProfilePackage(ref DJsIO x, LogRecord LogIn) : base(x, LogIn) { if (Header.ThisType == PackageType.Profile) { LoadProfile(true); } }
static STFSPackage LoadSTFS(byte[] data) { DJsIO dj = new DJsIO(data, true); var ret = new STFSPackage(dj, null); if (ret.ParseSuccess == false) ret = null; return ret; }
/// <summary> /// Overwrite the file /// </summary> /// <param name="xIO"></param> /// <returns></returns> public bool Inject(DJsIO xIO) { if (!xref.ActiveCheck()) { return(false); } return(xInject(xIO) & !(xref.xActive = false)); }
/// <summary> /// Extract a binary image of your FATX Drive /// </summary> /// <param name="xIOOut"></param> /// <returns></returns> public bool ExtractImage(DJsIO xIOOut) { if (ActiveCheck()) { return(false); } return(extractimg(xIOOut)); }
/// <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> /// 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; }
/// <summary> /// Special scramble method /// </summary> /// <param name="xPiece"></param> /// <returns></returns> public static byte[] DJScramble(byte[] xPiece) { if ((xPiece.Length % 8) != 0) throw new Exception("Input not divisible by 8"); int xSpot = 5, xCurrent = 5; DJsIO xStream = new DJsIO(xPiece, true); xStream.Position = 0; byte[] xHalf1 = xStream.ReadBytes((xPiece.Length / 2)); byte[] xHalf2 = xStream.ReadBytes((xPiece.Length / 2)); xStream.Position = 0; xStream.Write(xHalf2); xStream.Write(xHalf1); xStream.Flush(); xStream.Close(); for (int i = 0; i < xPiece.Length; i += xCurrent) { Array.Reverse(xPiece, i, xSpot); xCurrent = xSpot; if (xSpot == 5) xSpot = 3; else xSpot = 5; } return xPiece; }
/// <summary> /// Swaps bytes in 8 byte blocks, xReverse true if reverse each 8 byte blocks /// </summary> /// <param name="xPiece"></param> /// <param name="xReverse"></param> /// <returns></returns> public static byte[] StockScramble(byte[] xPiece, bool xReverse) { if ((xPiece.Length % 8) != 0) throw new Exception("Input not divisible by 8"); DJsIO xStream = new DJsIO(xPiece, true); for (int i = 0; i < (xPiece.Length / 2); i += 8) { xStream.Position = i; byte[] xPart1 = xStream.ReadBytes(8); xStream.Position = (xPiece.Length - i - 8); byte[] xPart2 = xStream.ReadBytes(8); xStream.Position = i; xStream.Write(xPart2); xStream.Position = (xPiece.Length - i - 8); xStream.Write(xPart1); xStream.Flush(); } if (xReverse) for (int i = 0; i < xPiece.Length; i += 8) Array.Reverse(xPiece, i, 8); return xPiece; }