public bool WriteAccount(int index, API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account) { int max = MaxAccounts; if (max == 0 || (index > (max - 1))) { return(false); } if (!API.XOnline.SignOnlineUserSignature(ref account)) { return(false); } if (Win32.SetFilePointer(handle, 0, IntPtr.Zero, Win32.MoveMethod.FILE_BEGIN) != Win32.INVALID_SET_FILE_POINTER) { byte[] sectors = new byte[0x400]; //2 sectors (1 sector = 512 bytes (0x200)) uint read = 0; if (Win32.ReadFile(handle, sectors, 0x400, ref read, IntPtr.Zero) && read == 0x400) //read the FATX header out { if (Win32.SetFilePointer(handle, 0, IntPtr.Zero, Win32.MoveMethod.FILE_BEGIN) != Win32.INVALID_SET_FILE_POINTER) { byte[] buffer = account.Serialize(); Array.Copy(buffer, 0, sectors, (0x50 + (index * 0x6C)), 0x6C); //copy the account data into the header uint written = 0; if (Win32.WriteFile(handle, sectors, 0x400, ref written, IntPtr.Zero)) //write the FATX header back { return(written == 0x400); } } } } return(false); }
private void LoadAccountToUI(API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account) { textBox1.Text = BitConverter.GetBytes(account.XUID).ToHex(); textBox2.Text = new string(account.Gamertag).TrimEnd('\0'); textBox3.Text = new string(account.Domain).TrimEnd('\0'); textBox4.Text = new string(account.Realm).TrimEnd('\0'); if (GetBit(account.Flags, 0)) { checkBox1.Checked = true; comboBox1.SelectedIndex = PasscodeButtonValueToIndex(account.Passcode[0]); comboBox2.SelectedIndex = PasscodeButtonValueToIndex(account.Passcode[1]); comboBox3.SelectedIndex = PasscodeButtonValueToIndex(account.Passcode[2]); comboBox4.SelectedIndex = PasscodeButtonValueToIndex(account.Passcode[3]); } else { checkBox1.Checked = false; comboBox1.SelectedIndex = 0; comboBox2.SelectedIndex = 0; comboBox3.SelectedIndex = 0; comboBox4.SelectedIndex = 0; } textBox1.Update(); textBox2.Update(); textBox3.Update(); textBox4.Update(); checkBox1.Update(); comboBox1.Update(); comboBox2.Update(); comboBox3.Update(); comboBox4.Update(); }
private API.XOnline.ONLINE_USER_ACCOUNT_STRUCT UnloadAccountFromUI() { var account = new API.XOnline.ONLINE_USER_ACCOUNT_STRUCT(); account.XUID = BitConverter.ToUInt64(textBox1.Text.ToBytes(), 0); account.unknown = 0; //must be zero to be considered a valid account account.Gamertag = new char[0x10]; char[] gamertag = Encoding.ASCII.GetChars(Encoding.ASCII.GetBytes(textBox2.Text)); Array.Copy(gamertag, account.Gamertag, gamertag.Length); uint flags = 0; byte[] passcode = new byte[4]; if (checkBox1.Checked) { flags = SetBit(flags, 0); passcode[0] = IndexToPasscodeButtonValue(comboBox1.SelectedIndex); passcode[1] = IndexToPasscodeButtonValue(comboBox2.SelectedIndex); passcode[2] = IndexToPasscodeButtonValue(comboBox3.SelectedIndex); passcode[3] = IndexToPasscodeButtonValue(comboBox4.SelectedIndex); } account.Flags = flags; account.Passcode = passcode; account.Domain = new char[0x14]; if (!string.IsNullOrEmpty(textBox3.Text)) { char[] domain = Encoding.ASCII.GetChars(Encoding.ASCII.GetBytes(textBox3.Text)); Array.Copy(domain, account.Domain, domain.Length); } account.Realm = new char[0x18]; if (!string.IsNullOrEmpty(textBox4.Text)) { char[] realm = Encoding.ASCII.GetChars(Encoding.ASCII.GetBytes(textBox4.Text)); Array.Copy(realm, account.Realm, realm.Length); } var confounder = new byte[0x14]; new Random().NextBytes(confounder); account.Confounder = confounder; account.Verification = new byte[8]; return(account); }
public bool WriteAccount(int index, API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account) { int max = MaxAccounts; if (max == 0 || (index > (max - 1))) { return(false); } if (!API.XOnline.SignOnlineUserSignature(ref account)) { return(false); } byte[] buffer = account.Serialize(); try { stream.Seek((0x50 + (index * 0x6C)), SeekOrigin.Begin); stream.Write(buffer, 0, 0x6C); stream.Flush(); } catch { return(false); } return(true); }
public bool ReadAccount(int index, out API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account) { account = default(API.XOnline.ONLINE_USER_ACCOUNT_STRUCT); int max = MaxAccounts; if (max == 0 || (index > (max - 1))) { return(false); } if (Win32.SetFilePointer(handle, 0, IntPtr.Zero, Win32.MoveMethod.FILE_BEGIN) != Win32.INVALID_SET_FILE_POINTER) { byte[] sectors = new byte[0x400]; //2 sectors (1 sector = 512 bytes (0x200)) uint read = 0; if (Win32.ReadFile(handle, sectors, 0x400, ref read, IntPtr.Zero) && read == 0x400) { byte[] buffer = new byte[0x6C]; Array.Copy(sectors, (0x50 + (index * 0x6C)), buffer, 0, 0x6C); account = buffer.Deserialize <API.XOnline.ONLINE_USER_ACCOUNT_STRUCT>(); return(API.XOnline.VerifyOnlineUserSignature(account)); } } return(false); }
public bool ReadAccount(int index, out API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account) { account = default(API.XOnline.ONLINE_USER_ACCOUNT_STRUCT); int max = MaxAccounts; if (max == 0 || (index > (max - 1))) { return(false); } //no need to seek or read/write on sector bounds with a file, we can go directly to the offset we want and read/write exactly what's needed byte[] buffer = new byte[0x6C]; try { stream.Seek((0x50 + (index * 0x6C)), SeekOrigin.Begin); if (stream.Read(buffer, 0, 0x6C) == 0x6C) { account = buffer.Deserialize <API.XOnline.ONLINE_USER_ACCOUNT_STRUCT>(); return(API.XOnline.VerifyOnlineUserSignature(account)); } } catch { } return(false); }
public AccountDialog(ref IDrive drive, bool saving) { InitializeComponent(); DialogResult = DialogResult.Cancel; Shown += (s, e) => { if (saving) { selectButton.Text = "Save"; } else { selectButton.Text = "Load"; } selectButton.Update(); ListAccounts(); }; slotsList.SelectedIndexChanged += (s, e) => { if (slotsList.SelectedIndices != null && slotsList.SelectedIndices.Count > 0) { API.XOnline.ONLINE_USER_ACCOUNT_STRUCT temp; int index = slotsList.SelectedIndices[0]; if (currentDrive.ReadAccount(index, out temp)) { selectButton.Enabled = true; deleteButton.Enabled = true; selectButton.Update(); deleteButton.Update(); } else { if (!saving) { selectButton.Enabled = false; selectButton.Update(); } else { selectButton.Enabled = true; selectButton.Update(); } deleteButton.Enabled = false; deleteButton.Update(); } } else { selectButton.Enabled = false; deleteButton.Enabled = false; selectButton.Update(); deleteButton.Update(); } }; slotsList.DoubleClick += (s, e) => { selectButton.PerformClick(); }; deleteButton.Click += (s, e) => { if (slotsList.SelectedIndices != null && slotsList.SelectedIndices.Count == 1) { int index = slotsList.SelectedIndices[0]; API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account; if (currentDrive.ReadAccount(index, out account)) { var message = $"Account \'{new string(account.Gamertag).TrimEnd('\0')}\' will be deleted from the following device:\n\n" + $"Device: {currentDrive.Name} ({(currentDrive.IsMemoryCard ? "MU" : "HDD")})\n" + $"Capacity: {currentDrive.FriendlyCapacity} ({currentDrive.Capacity.ToString("N0")} bytes)\n" + $"Slot: {index + 1} (index: {index})\n\n" + "Continue?"; if (MessageBox.Show(this, message, "Confirm device write", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { if (currentDrive.DeleteAccount(index)) { MessageBox.Show(this, "Account data was deleted successfully", "Account saved", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(this, "Failed to write data to device\n\nThis can fail on occassion if the Operating System is busy with the device.\nWait 5-10 seconds and try again\n\n" + "If writes continue to fail, close the program, unplug your device for a few seconds, plug it back in, and try again", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } ListAccounts(); //refresh } } } }; selectButton.Click += (s, e) => { if (slotsList.SelectedIndices != null && slotsList.SelectedIndices.Count == 1) { int index = slotsList.SelectedIndices[0]; if (saving) { if (!default(API.XOnline.ONLINE_USER_ACCOUNT_STRUCT).Equals(Account)) { var message = $"Account \'{new string(Account.Gamertag).TrimEnd('\0')}\' will be written to the following device:\n\n" + $"Device: {currentDrive.Name} ({(currentDrive.IsMemoryCard ? "MU" : "HDD")})\n" + $"Capacity: {currentDrive.FriendlyCapacity} ({currentDrive.Capacity.ToString("N0")} bytes)\n" + $"Slot: {index + 1} (index: {index})\n\n" + "If an account already exists in the selected slot, it will be overwritten.\n\nContinue?"; if (MessageBox.Show(this, message, "Confirm device write", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { if (currentDrive.WriteAccount(index, Account)) { MessageBox.Show(this, "Account data was written successfully", "Account saved", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(this, "Failed to write data to device\n\nThis can fail on occassion if the Operating System is busy with the device.\nWait 5-10 seconds and try again\n\n" + "If writes continue to fail, close the program, unplug your device for a few seconds, plug it back in, and try again", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } else { Account = loadedAccounts[index]; } DialogResult = DialogResult.OK; Close(); } }; cancelButton.Click += (s, e) => { Close(); }; if (drive == null) //this shouldnt happen { Close(); } currentDrive = drive; Text = currentDrive.Name; }
public Main() { InitializeComponent(); checkBox1.CheckedChanged += (s, e) => { comboBox1.Enabled = checkBox1.Checked; comboBox2.Enabled = checkBox1.Checked; comboBox3.Enabled = checkBox1.Checked; comboBox4.Enabled = checkBox1.Checked; comboBox1.Update(); comboBox2.Update(); comboBox3.Update(); comboBox4.Update(); }; blankMenuItem.Click += (s, e) => { Blank(); }; generateMenuItem.Click += (s, e) => { Generate(); }; openFileMenuItem.Click += (s, e) => { using (var dialog = new OpenFileDialog()) { dialog.Title = "Open XBL Account File"; dialog.Filter = "All Files (*.*)|*.*"; dialog.Multiselect = false; dialog.CheckFileExists = true; dialog.CheckPathExists = true; dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); dialog.RestoreDirectory = true; if (dialog.ShowDialog(this) == DialogResult.OK) { var file = new FileInfo(dialog.FileName); if (file.Length != 0x6C) { MessageBox.Show(this, "Selected file is not a valid Xbox LIVE account file", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var buffer = new byte[0x6C]; using (var stream = file.OpenRead()) { stream.Read(buffer, 0, 0x6C); } var account = buffer.Deserialize <API.XOnline.ONLINE_USER_ACCOUNT_STRUCT>(); if (!API.XOnline.VerifyOnlineUserSignature(account)) { MessageBox.Show(this, "Selected file is not a valid Xbox LIVE account file", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } LoadAccountToUI(account); } } }; saveFileMenuItem.Click += (s, e) => { //check xuid if (string.IsNullOrEmpty(textBox1.Text) || textBox1.Text.Length != 16 || !textBox1.Text.IsHex()) { MessageBox.Show(this, "XUID must be 8 bytes in length (16 hexadecimal characters)\n\nIt's safe to set the XUID to all zeroes", "Invalid XUID", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //check gamertag if (string.IsNullOrEmpty(textBox2.Text) || !textBox2.Text.IsASCII()) { MessageBox.Show(this, "Gamertag must be at least 1 character in length. Only ASCII characters are valid", "Invalid Gamertag", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } using (var dialog = new SaveFileDialog()) { dialog.Title = "Save XBL Account File"; dialog.Filter = "All Files (*.*)|*.*"; dialog.CheckPathExists = true; dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); dialog.RestoreDirectory = true; dialog.OverwritePrompt = true; if (dialog.ShowDialog(this) == DialogResult.OK) { var account = UnloadAccountFromUI(); if (!API.XOnline.SignOnlineUserSignature(ref account)) { //this shouldnt fail but we'll handle it anyway MessageBox.Show(this, "Failed to encrypt and sign account data", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var buffer = account.Serialize(); using (var stream = File.Open(dialog.FileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { stream.Write(buffer, 0, 0x6C); stream.Flush(); } MessageBox.Show(this, "Account data was written successfully", "Account saved", MessageBoxButtons.OK, MessageBoxIcon.Information); } } }; openDeviceMenuItem.Click += (s, e) => { using (var deviceDialog = new DeviceDialog(false)) { if (deviceDialog.ShowDialog(this) == DialogResult.OK) { LoadAccountToUI(deviceDialog.Account); } } }; saveDeviceMenuItem.Click += (s, e) => { //check xuid if (string.IsNullOrEmpty(textBox1.Text) || textBox1.Text.Length != 16 || !textBox1.Text.IsHex()) { MessageBox.Show(this, "XUID must be 8 bytes in length (16 hexadecimal characters)\n\nIt's safe to set the XUID to all zeroes", "Invalid XUID", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //check gamertag if (string.IsNullOrEmpty(textBox2.Text) || !textBox2.Text.IsASCII()) { MessageBox.Show(this, "Gamertag must be at least 1 character in length. Only ASCII characters are valid", "Invalid Gamertag", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } using (var deviceDialog = new DeviceDialog(true)) { deviceDialog.Account = UnloadAccountFromUI(); deviceDialog.ShowDialog(this); } }; openDeviceImageMenuItem.Click += (s, e) => { using (var dialog = new OpenFileDialog()) { dialog.Title = "Open Device Image Backup"; dialog.Filter = "All Files (*.*)|*.*"; dialog.Multiselect = false; dialog.CheckFileExists = true; dialog.CheckPathExists = true; dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); dialog.RestoreDirectory = true; if (dialog.ShowDialog(this) == DialogResult.OK) { var file = dialog.FileName; if (!CheckDeviceImageFile(file)) { MessageBox.Show(this, "Selected file is not a valid Xbox memory card or harddrive image", "Invalid FATX Image", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account; IDrive image = new DriveImage(file); using (var accountDialog = new AccountDialog(ref image, false)) { if (accountDialog.ShowDialog(this) == DialogResult.OK) { account = accountDialog.Account; LoadAccountToUI(account); } } image.Dispose(); } } }; saveDeviceImageMenuItem.Click += (s, e) => { //check xuid if (string.IsNullOrEmpty(textBox1.Text) || textBox1.Text.Length != 16 || !textBox1.Text.IsHex()) { MessageBox.Show(this, "XUID must be 8 bytes in length (16 hexadecimal characters)\n\nIt's safe to set the XUID to all zeroes", "Invalid XUID", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //check gamertag if (string.IsNullOrEmpty(textBox2.Text) || !textBox2.Text.IsASCII()) { MessageBox.Show(this, "Gamertag must be at least 1 character in length. Only ASCII characters are valid", "Invalid Gamertag", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } using (var dialog = new OpenFileDialog()) { dialog.Title = "Open Device Image Backup"; dialog.Filter = "All Files (*.*)|*.*"; dialog.Multiselect = false; dialog.CheckFileExists = true; dialog.CheckPathExists = true; dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); dialog.RestoreDirectory = true; if (dialog.ShowDialog(this) == DialogResult.OK) { var file = dialog.FileName; if (!CheckDeviceImageFile(file)) { MessageBox.Show(this, "Selected file is not a valid Xbox memory card or harddrive image", "Invalid FATX Image", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } API.XOnline.ONLINE_USER_ACCOUNT_STRUCT account = UnloadAccountFromUI(); IDrive image = new DriveImage(file); using (var accountDialog = new AccountDialog(ref image, true)) { accountDialog.Account = account; accountDialog.ShowDialog(this); } image.Dispose(); } } }; Generate(); }
public DeviceDialog(bool saving) { InitializeComponent(); DialogResult = DialogResult.Cancel; Shown += (s, e) => { ListDrives(); }; deviceList.SelectedIndexChanged += (s, e) => { if (deviceList.SelectedIndices == null || deviceList.SelectedIndices.Count == 0) { openButton.Enabled = false; openButton.Update(); } else { openButton.Enabled = true; openButton.Update(); } }; deviceList.DoubleClick += (s, e) => { openButton.PerformClick(); }; FormClosing += (s, e) => { ClearDrives(); }; refreshButton.Click += (s, e) => { ListDrives(); }; openButton.Click += (s, e) => { if (deviceList.SelectedIndices == null || deviceList.SelectedIndices.Count != 1) { return; } var drive = loadedDrives[deviceList.SelectedIndices[0]]; using (var accountDialog = new AccountDialog(ref drive, saving)) { if (saving) { accountDialog.Account = Account; if (accountDialog.ShowDialog(this) == DialogResult.OK) { Close(); } else { ListDrives(); //refresh } } else { if (accountDialog.ShowDialog(this) == DialogResult.OK) { Account = accountDialog.Account; DialogResult = DialogResult.OK; Close(); } else { ListDrives(); //refresh } } } }; cancelButton.Click += (s, e) => { Close(); }; }