Exemple #1
0
        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);
        }
Exemple #5
0
        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();
            };
        }