Skip to content

Commit

Permalink
Merge branch 'xenia-canary:canary_experimental' into Custom
Browse files Browse the repository at this point in the history
  • Loading branch information
backgamon authored Sep 28, 2024
2 parents 0a6cf11 + 952526a commit b3c161a
Show file tree
Hide file tree
Showing 17 changed files with 403 additions and 124 deletions.
42 changes: 4 additions & 38 deletions src/xenia/kernel/kernel_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@

DEFINE_bool(apply_title_update, true, "Apply title updates.", "Kernel");

DEFINE_uint32(max_signed_profiles, 4,
"Limits how many profiles can be assigned. Possible values: 1-4",
"Kernel");

DEFINE_uint32(kernel_build_version, 1888, "Define current kernel version",
"Kernel");

Expand Down Expand Up @@ -68,20 +64,11 @@ KernelState::KernelState(Emulator* emulator)
shared_kernel_state_ = this;
processor_ = emulator->processor();
file_system_ = emulator->file_system();

app_manager_ = std::make_unique<xam::AppManager>();
achievement_manager_ = std::make_unique<AchievementManager>();
user_profiles_.emplace(0, std::make_unique<xam::UserProfile>(0));
xam_state_ = std::make_unique<xam::XamState>(emulator, this);

InitializeKernelGuestGlobals();
kernel_version_ = KernelVersion(cvars::kernel_build_version);

auto content_root = emulator_->content_root();
if (!content_root.empty()) {
content_root = std::filesystem::absolute(content_root);
}
content_manager_ = std::make_unique<xam::ContentManager>(this, content_root);

// Hardcoded maximum of 2048 TLS slots.
tls_bitmap_.Resize(2048);

Expand All @@ -92,8 +79,6 @@ KernelState::KernelState(Emulator* emulator)
kMemoryProtectRead | kMemoryProtectWrite);

xenia_assert(fixed_alloc_worked);

xam::AppManager::RegisterApps(this, app_manager_.get());
}

KernelState::~KernelState() {
Expand All @@ -112,8 +97,7 @@ KernelState::~KernelState() {
// Delete all objects.
object_table_.Reset();

// Shutdown apps.
app_manager_.reset();
xam_state_.reset();

assert_true(shared_kernel_state_ == this);
shared_kernel_state_ = nullptr;
Expand Down Expand Up @@ -592,8 +576,8 @@ std::vector<xam::XCONTENT_AGGREGATE_DATA> KernelState::FindTitleUpdate(
return {};
}

return content_manager()->ListContent(1, xe::XContentType::kInstaller,
title_id);
return xam_state_->content_manager()->ListContent(
1, xe::XContentType::kInstaller, title_id);
}

const object_ref<UserModule> KernelState::LoadTitleUpdate(
Expand Down Expand Up @@ -1252,24 +1236,6 @@ void KernelState::EmulateCPInterruptDPC(uint32_t interrupt_callback,
EndDPCImpersonation(current_context, dpc_scope);
}

void KernelState::UpdateUsedUserProfiles() {
const std::bitset<4> used_slots = GetConnectedUsers();

for (uint32_t i = 1; i < cvars::max_signed_profiles; i++) {
bool is_used = used_slots.test(i);

if (IsUserSignedIn(i) && !is_used) {
user_profiles_.erase(i);
BroadcastNotification(kXNotificationIDSystemInputDevicesChanged, 0);
}

if (!IsUserSignedIn(i) && is_used) {
user_profiles_.emplace(i, std::make_unique<xam::UserProfile>(i));
BroadcastNotification(kXNotificationIDSystemInputDevicesChanged, 0);
}
}
}

void KernelState::InitializeProcess(X_KPROCESS* process, uint32_t type,
char unk_18, char unk_19, char unk_1A) {
uint32_t guest_kprocess = memory()->HostToGuestVirtual(process);
Expand Down
45 changes: 9 additions & 36 deletions src/xenia/kernel/kernel_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <memory>
#include <vector>

#include "achievement_manager.h"
#include "xenia/base/bit_map.h"
#include "xenia/base/cvar.h"
#include "xenia/base/mutex.h"
Expand All @@ -28,9 +27,11 @@
#include "xenia/kernel/util/native_list.h"
#include "xenia/kernel/util/object_table.h"
#include "xenia/kernel/util/xdbf_utils.h"
#include "xenia/kernel/xam/achievement_manager.h"
#include "xenia/kernel/xam/app_manager.h"
#include "xenia/kernel/xam/content_manager.h"
#include "xenia/kernel/xam/user_profile.h"
#include "xenia/kernel/xam/xam_state.h"
#include "xenia/kernel/xevent.h"
#include "xenia/memory.h"
#include "xenia/vfs/virtual_file_system.h"
Expand Down Expand Up @@ -186,41 +187,17 @@ class KernelState {
util::XdbfGameData title_xdbf() const;
util::XdbfGameData module_xdbf(object_ref<UserModule> exec_module) const;

AchievementManager* achievement_manager() const {
return achievement_manager_.get();
xam::XamState* xam_state() const { return xam_state_.get(); }

xam::AchievementManager* achievement_manager() const {
return xam_state()->achievement_manager();
}
xam::AppManager* app_manager() const { return app_manager_.get(); }
xam::AppManager* app_manager() const { return xam_state()->app_manager(); }
xam::ContentManager* content_manager() const {
return content_manager_.get();
return xam_state()->content_manager();
}

std::bitset<4> GetConnectedUsers() const;
void UpdateUsedUserProfiles();

bool IsUserSignedIn(uint32_t index) const {
return user_profiles_.find(index) != user_profiles_.cend();
}

bool IsUserSignedIn(uint64_t xuid) const {
return user_profile(xuid) != nullptr;
}

xam::UserProfile* user_profile(uint32_t index) const {
if (!IsUserSignedIn(index)) {
return nullptr;
}

return user_profiles_.at(index).get();
}

xam::UserProfile* user_profile(uint64_t xuid) const {
for (const auto& [key, value] : user_profiles_) {
if (value->xuid() == xuid) {
return user_profiles_.at(key).get();
}
}
return nullptr;
}

// Access must be guarded by the global critical region.
util::ObjectTable* object_table() { return &object_table_; }
Expand Down Expand Up @@ -368,11 +345,7 @@ class KernelState {
Memory* memory_;
cpu::Processor* processor_;
vfs::VirtualFileSystem* file_system_;

std::unique_ptr<xam::AppManager> app_manager_;
std::unique_ptr<xam::ContentManager> content_manager_;
std::map<uint8_t, std::unique_ptr<xam::UserProfile>> user_profiles_;
std::unique_ptr<AchievementManager> achievement_manager_;
std::unique_ptr<xam::XamState> xam_state_;

KernelVersion kernel_version_;

Expand Down
130 changes: 130 additions & 0 deletions src/xenia/kernel/util/crypto_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2024 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <algorithm>

#include "xenia/kernel/util/crypto_utils.h"
#include "xenia/xbox.h"

#include "third_party/crypto/TinySHA1.hpp"

namespace xe {
namespace kernel {
namespace util {

uint8_t xekey_0x19[] = {0xE1, 0xBC, 0x15, 0x9C, 0x73, 0xB1, 0xEA, 0xE9,
0xAB, 0x31, 0x70, 0xF3, 0xAD, 0x47, 0xEB, 0xF3};

uint8_t xekey_0x19_devkit[] = {0xDA, 0xB6, 0x9A, 0xD9, 0x8E, 0x28, 0x76, 0x4F,
0x97, 0x7E, 0xE2, 0x48, 0x7E, 0x4F, 0x3F, 0x68};

const uint8_t* GetXeKey(uint32_t idx, bool devkit) {
if (idx != 0x19) {
return nullptr;
}

return devkit ? xekey_0x19_devkit : xekey_0x19;
}

void HmacSha(const uint8_t* key, uint32_t key_size_in, const uint8_t* inp_1,
uint32_t inp_1_size, const uint8_t* inp_2, uint32_t inp_2_size,
const uint8_t* inp_3, uint32_t inp_3_size, uint8_t* out,
uint32_t out_size) {
uint32_t key_size = key_size_in;
sha1::SHA1 sha;
uint8_t kpad_i[0x40];
uint8_t kpad_o[0x40];
uint8_t tmp_key[0x40];
std::memset(kpad_i, 0x36, 0x40);
std::memset(kpad_o, 0x5C, 0x40);

// Setup HMAC key
// If > block size, use its hash
if (key_size > 0x40) {
sha1::SHA1 sha_key;
sha_key.processBytes(key, key_size);
sha_key.finalize((uint8_t*)tmp_key);

key_size = 0x14u;
} else {
std::memcpy(tmp_key, key, key_size);
}

for (uint32_t i = 0; i < key_size; i++) {
kpad_i[i] = tmp_key[i] ^ 0x36;
kpad_o[i] = tmp_key[i] ^ 0x5C;
}

// Inner
sha.processBytes(kpad_i, 0x40);

if (inp_1_size) {
sha.processBytes(inp_1, inp_1_size);
}

if (inp_2_size) {
sha.processBytes(inp_2, inp_2_size);
}

if (inp_3_size) {
sha.processBytes(inp_3, inp_3_size);
}

uint8_t digest[0x14];
sha.finalize(digest);
sha.reset();

// Outer
sha.processBytes(kpad_o, 0x40);
sha.processBytes(digest, 0x14);
sha.finalize(digest);

std::memcpy(out, digest, std::min((uint32_t)out_size, 0x14u));
}

void RC4(const uint8_t* key, uint32_t key_size_in, const uint8_t* data,
uint32_t data_size, uint8_t* out, uint32_t out_size) {
uint8_t tmp_key[0x10];
uint32_t sbox_size;
uint8_t sbox[0x100];
uint32_t i;
uint32_t j;

// Setup RC4 session...
std::memcpy(tmp_key, key, 0x10);
i = j = 0;
sbox_size = 0x100;
for (uint32_t x = 0; x < sbox_size; x++) {
sbox[x] = (uint8_t)x;
}

uint32_t idx = 0;
for (uint32_t x = 0; x < sbox_size; x++) {
idx = (idx + sbox[x] + key[x % 0x10]) % sbox_size;
uint8_t temp = sbox[idx];
sbox[idx] = sbox[x];
sbox[x] = temp;
}

// Crypt data
for (uint32_t idx = 0; idx < data_size; idx++) {
i = (i + 1) % sbox_size;
j = (j + sbox[i]) % sbox_size;
uint8_t temp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = temp;

uint8_t a = data[idx];
uint8_t b = sbox[(sbox[i] + sbox[j]) % sbox_size];
out[idx] = (uint8_t)(a ^ b);
}
}

} // namespace util
} // namespace kernel
} // namespace xe
28 changes: 28 additions & 0 deletions src/xenia/kernel/util/crypto_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2024 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/

#include "xenia/xbox.h"

namespace xe {
namespace kernel {
namespace util {

const uint8_t* GetXeKey(uint32_t idx, bool devkit = false);

void HmacSha(const uint8_t* key, uint32_t key_size_in, const uint8_t* inp_1,
uint32_t inp_1_size, const uint8_t* inp_2, uint32_t inp_2_size,
const uint8_t* inp_3, uint32_t inp_3_size, uint8_t* out,
uint32_t out_size);

void RC4(const uint8_t* key, uint32_t key_size_in, const uint8_t* data,
uint32_t data_size, uint8_t* out, uint32_t out_size);

} // namespace util
} // namespace kernel
} // namespace xe
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ DECLARE_int32(user_language);

namespace xe {
namespace kernel {
namespace xam {

AchievementManager::AchievementManager() { unlocked_achievements.clear(); };

Expand Down Expand Up @@ -85,5 +86,6 @@ uint64_t AchievementManager::GetAchievementUnlockTime(uint32_t achievement_id) {
return itr->second;
}

} // namespace xam
} // namespace kernel
} // namespace xe
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
******************************************************************************
*/

#ifndef XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
#define XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
#ifndef XENIA_KERNEL_XAM_ACHIEVEMENT_MANAGER_H_
#define XENIA_KERNEL_XAM_ACHIEVEMENT_MANAGER_H_

#include <map>
#include <string>
Expand All @@ -18,6 +18,7 @@

namespace xe {
namespace kernel {
namespace xam {

// TODO(gibbed): probably a FILETIME/LARGE_INTEGER, unknown currently
struct X_ACHIEVEMENT_UNLOCK_TIME {
Expand Down Expand Up @@ -55,7 +56,8 @@ class AchievementManager {
// void Save();
};

} // namespace xam
} // namespace kernel
} // namespace xe

#endif // XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
#endif // XENIA_KERNEL_XAM_ACHIEVEMENT_MANAGER_H_
Loading

0 comments on commit b3c161a

Please sign in to comment.