Create a random console_unique_id (#2668)

* Create a random console_id when config save_file is created

Added button in system config to refresh the console unique id

* Moved the connect for the button from .ui file to constructor of ConfigureSystem

* Added warning and info dialog
Fixup: Make use of qt5 style connects,
  renamed the refresh button,
  removed some duplicate code,
  changed random device and moved all to the generate function

* Changed the random generator to reflect what a real 3DS stores as console unique id
Fixup: Changed the warning message

* Fixup: Set and Create

* Fixup: Added console id label, therfore removed second message box

* Fixup: fixed the endianess

* Fixup: more endianness fixes

* Fixup: Endianness the 3rd
This commit is contained in:
B3n30 2017-05-06 02:55:51 +02:00 committed by bunnei
parent de1b6cc695
commit 8bee016145
5 changed files with 123 additions and 7 deletions

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <QMessageBox>
#include "citra_qt/configuration/configure_system.h"
#include "citra_qt/ui_settings.h"
#include "core/core.h"
@ -15,8 +16,11 @@ static const std::array<int, 12> days_in_month = {{
ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) {
ui->setupUi(this);
connect(ui->combo_birthmonth, SIGNAL(currentIndexChanged(int)),
SLOT(updateBirthdayComboBox(int)));
connect(ui->combo_birthmonth,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&ConfigureSystem::updateBirthdayComboBox);
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
&ConfigureSystem::refreshConsoleID);
this->setConfiguration();
}
@ -71,6 +75,10 @@ void ConfigureSystem::ReadSystemSettings() {
// set sound output mode
sound_index = Service::CFG::GetSoundOutputMode();
ui->combo_sound->setCurrentIndex(sound_index);
// set the console id
u64 console_id = Service::CFG::GetConsoleUniqueId();
ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper());
}
void ConfigureSystem::applyConfiguration() {
@ -140,3 +148,21 @@ void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) {
// restore the day selection
ui->combo_birthday->setCurrentIndex(birthday_index);
}
void ConfigureSystem::refreshConsoleID() {
QMessageBox::StandardButton reply;
QString warning_text = tr("This will replace your current virtual 3DS with a new one. "
"Your current virtual 3DS will not be recoverable. "
"This might have unexpected effects in games. This might fail, "
"if you use an outdated config savegame. Continue?");
reply = QMessageBox::critical(this, tr("Warning"), warning_text,
QMessageBox::No | QMessageBox::Yes);
if (reply == QMessageBox::No)
return;
u32 random_number;
u64 console_id;
Service::CFG::GenerateConsoleUniqueId(random_number, console_id);
Service::CFG::SetConsoleUniqueId(random_number, console_id);
Service::CFG::UpdateConfigNANDSavegame();
ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper());
}

View file

@ -23,6 +23,7 @@ public:
public slots:
void updateBirthdayComboBox(int birthmonth_index);
void refreshConsoleID();
private:
void ReadSystemSettings();

View file

@ -220,6 +220,29 @@
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_console_id">
<property name="text">
<string>Console ID:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="button_regenerate_console_id">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Regenerate</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -4,6 +4,7 @@
#include <algorithm>
#include <array>
#include <cryptopp/osrng.h>
#include <cryptopp/sha.h>
#include "common/file_util.h"
#include "common/logging/log.h"
@ -50,6 +51,7 @@ enum ConfigBlockID {
SoundOutputModeBlockID = 0x00070001,
ConsoleUniqueID1BlockID = 0x00090000,
ConsoleUniqueID2BlockID = 0x00090001,
ConsoleUniqueID3BlockID = 0x00090002,
UsernameBlockID = 0x000A0000,
BirthdayBlockID = 0x000A0001,
LanguageBlockID = 0x000A0002,
@ -86,7 +88,6 @@ struct ConsoleCountryInfo {
static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes");
}
static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE;
static const ConsoleModelInfo CONSOLE_MODEL = {NINTENDO_3DS_XL, {0, 0, 0}};
static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN;
static const UsernameBlock CONSOLE_USERNAME_BLOCK = {u"CITRA", 0, 0};
@ -438,13 +439,22 @@ ResultCode FormatConfig() {
if (!res.IsSuccess())
return res;
res = CreateConfigInfoBlk(ConsoleUniqueID1BlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE,
&CONSOLE_UNIQUE_ID);
u32 random_number;
u64 console_id;
GenerateConsoleUniqueId(random_number, console_id);
u64_le console_id_le = console_id;
res = CreateConfigInfoBlk(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le);
if (!res.IsSuccess())
return res;
res = CreateConfigInfoBlk(ConsoleUniqueID2BlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE,
&CONSOLE_UNIQUE_ID);
res = CreateConfigInfoBlk(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le);
if (!res.IsSuccess())
return res;
u32_le random_number_le = random_number;
res = CreateConfigInfoBlk(ConsoleUniqueID3BlockID, sizeof(random_number_le), 0xE,
&random_number_le);
if (!res.IsSuccess())
return res;
@ -663,5 +673,40 @@ SoundOutputMode GetSoundOutputMode() {
return static_cast<SoundOutputMode>(block);
}
void GenerateConsoleUniqueId(u32& random_number, u64& console_id) {
CryptoPP::AutoSeededRandomPool rng;
random_number = rng.GenerateWord32(0, 0xFFFF);
u64_le local_friend_code_seed;
rng.GenerateBlock(reinterpret_cast<byte*>(&local_friend_code_seed),
sizeof(local_friend_code_seed));
console_id = (local_friend_code_seed & 0x3FFFFFFFF) | (static_cast<u64>(random_number) << 48);
}
ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id) {
u64_le console_id_le = console_id;
ResultCode res =
SetConfigInfoBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le);
if (!res.IsSuccess())
return res;
res = SetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le);
if (!res.IsSuccess())
return res;
u32_le random_number_le = random_number;
res = SetConfigInfoBlock(ConsoleUniqueID3BlockID, sizeof(random_number_le), 0xE,
&random_number_le);
if (!res.IsSuccess())
return res;
return RESULT_SUCCESS;
}
u64 GetConsoleUniqueId() {
u64_le console_id_le;
GetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le);
return console_id_le;
}
} // namespace CFG
} // namespace Service

View file

@ -342,5 +342,26 @@ void SetSoundOutputMode(SoundOutputMode mode);
*/
SoundOutputMode GetSoundOutputMode();
/**
* Generates a new random console unique id.
* @param random_number a random generated 16bit number stored at 0x90002, used for generating the
* console_id
* @param console_id the randomly created console id
*/
void GenerateConsoleUniqueId(u32& random_number, u64& console_id);
/**
* Sets the random_number and the console unique id in the config savegame.
* @param random_number the random_number to set
* @param console_id the console id to set
*/
ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id);
/**
* Gets the console unique id from config savegame.
* @returns the console unique id
*/
u64 GetConsoleUniqueId();
} // namespace CFG
} // namespace Service