summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraerosoul <aerosoul94@hotmail.com>2019-10-28 13:59:30 -0500
committerRick Gibbed <rick@gibbed.us>2019-11-20 18:09:28 -0600
commitbc8b62909291017f4867ceaa1b46f1654a0aaefa (patch)
tree0f05a66664e16983dcfa45e11376241bb4ebc4a7
parent03d5455a2f8b5c5d029d7612a37cf7a24a64fc18 (diff)
[Kernel] Enable XEX1 loading
-rw-r--r--src/xenia/cpu/xex_module.cc41
-rw-r--r--src/xenia/cpu/xex_module.h24
-rw-r--r--src/xenia/kernel/user_module.cc2
-rw-r--r--src/xenia/kernel/util/xex2_info.h17
4 files changed, 75 insertions, 9 deletions
diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc
index e842b58b4..09cea5143 100644
--- a/src/xenia/cpu/xex_module.cc
+++ b/src/xenia/cpu/xex_module.cc
@@ -103,10 +103,9 @@ bool XexModule::GetOptHeader(xex2_header_keys key, void** out_ptr) const {
return XexModule::GetOptHeader(xex_header(), key, out_ptr);
}
-const xex2_security_info* XexModule::GetSecurityInfo(
- const xex2_header* header) {
- return reinterpret_cast<const xex2_security_info*>(uintptr_t(header) +
- header->security_offset);
+const void* XexModule::GetSecurityInfo(const xex2_header* header) {
+ return reinterpret_cast<const void*>(uintptr_t(header) +
+ header->security_offset);
}
const PESection* XexModule::GetPESection(const char* name) {
@@ -870,7 +869,11 @@ bool XexModule::Load(const std::string& name, const std::string& path,
const void* xex_addr, size_t xex_length) {
auto src_header = reinterpret_cast<const xex2_header*>(xex_addr);
- if (src_header->magic != 'XEX2') {
+ if (src_header->magic == 'XEX1') {
+ xex_format_ = kFormatXex1;
+ } else if (src_header->magic == 'XEX2') {
+ xex_format_ = kFormatXex2;
+ } else {
return false;
}
@@ -881,6 +884,34 @@ bool XexModule::Load(const std::string& name, const std::string& path,
xex_header_mem_.resize(src_header->header_size);
std::memcpy(xex_header_mem_.data(), src_header, src_header->header_size);
+ if (xex_format_ == kFormatXex1) {
+ const xex1_security_info* xex1_sec_info =
+ reinterpret_cast<const xex1_security_info*>(
+ GetSecurityInfo(xex_header()));
+
+ security_info_.rsa_signature = xex1_sec_info->rsa_signature;
+ security_info_.aes_key = xex1_sec_info->aes_key;
+ security_info_.image_size = xex1_sec_info->image_size;
+ security_info_.image_flags = xex1_sec_info->image_flags;
+ security_info_.export_table = xex1_sec_info->export_table;
+ security_info_.load_address = xex1_sec_info->load_address;
+ security_info_.page_descriptor_count = xex1_sec_info->page_descriptor_count;
+ security_info_.page_descriptors = xex1_sec_info->page_descriptors;
+ } else if (xex_format_ == kFormatXex2) {
+ const xex2_security_info* xex2_sec_info =
+ reinterpret_cast<const xex2_security_info*>(
+ GetSecurityInfo(xex_header()));
+
+ security_info_.rsa_signature = xex2_sec_info->rsa_signature;
+ security_info_.aes_key = xex2_sec_info->aes_key;
+ security_info_.image_size = xex2_sec_info->image_size;
+ security_info_.image_flags = xex2_sec_info->image_flags;
+ security_info_.export_table = xex2_sec_info->export_table;
+ security_info_.load_address = xex2_sec_info->load_address;
+ security_info_.page_descriptor_count = xex2_sec_info->page_descriptor_count;
+ security_info_.page_descriptors = xex2_sec_info->page_descriptors;
+ }
+
auto sec_header = xex_security_info();
// Try setting our base_address based on XEX_HEADER_IMAGE_BASE_ADDRESS, fall
diff --git a/src/xenia/cpu/xex_module.h b/src/xenia/cpu/xex_module.h
index 5c8cb8d6b..e2c5f5a3b 100644
--- a/src/xenia/cpu/xex_module.h
+++ b/src/xenia/cpu/xex_module.h
@@ -43,6 +43,21 @@ class XexModule : public xe::cpu::Module {
xe_xex2_version_t min_version;
std::vector<ImportLibraryFn> imports;
};
+ struct SecurityInfoContext {
+ const char* rsa_signature;
+ const char* aes_key;
+ uint32_t image_size;
+ uint32_t image_flags;
+ uint32_t export_table;
+ uint32_t load_address;
+ uint32_t page_descriptor_count;
+ const xex2_page_descriptor* page_descriptors;
+ };
+ enum XexFormat {
+ kFormatUnknown,
+ kFormatXex1,
+ kFormatXex2,
+ };
XexModule(Processor* processor, kernel::KernelState* kernel_state);
virtual ~XexModule();
@@ -51,8 +66,8 @@ class XexModule : public xe::cpu::Module {
const xex2_header* xex_header() const {
return reinterpret_cast<const xex2_header*>(xex_header_mem_.data());
}
- const xex2_security_info* xex_security_info() const {
- return GetSecurityInfo(xex_header());
+ const SecurityInfoContext* xex_security_info() const {
+ return &security_info_;
}
uint32_t image_size() const {
@@ -112,7 +127,7 @@ class XexModule : public xe::cpu::Module {
return GetOptHeader(key, reinterpret_cast<void**>(out_ptr));
}
- static const xex2_security_info* GetSecurityInfo(const xex2_header* header);
+ static const void* GetSecurityInfo(const xex2_header* header);
const PESection* GetPESection(const char* name);
@@ -186,6 +201,9 @@ class XexModule : public xe::cpu::Module {
uint32_t base_address_ = 0;
uint32_t low_address_ = 0;
uint32_t high_address_ = 0;
+
+ XexFormat xex_format_ = kFormatUnknown;
+ SecurityInfoContext security_info_ = {};
};
} // namespace cpu
diff --git a/src/xenia/kernel/user_module.cc b/src/xenia/kernel/user_module.cc
index 2d070a65a..58ab9f36c 100644
--- a/src/xenia/kernel/user_module.cc
+++ b/src/xenia/kernel/user_module.cc
@@ -135,7 +135,7 @@ X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) {
auto processor = kernel_state()->processor();
auto magic = xe::load_and_swap<uint32_t>(addr);
- if (magic == 'XEX2') {
+ if (magic == 'XEX2' || magic == 'XEX1') {
module_format_ = kModuleFormatXex;
} else if (magic == 0x7F454C46 /* 0x7F 'ELF' */) {
module_format_ = kModuleFormatElf;
diff --git a/src/xenia/kernel/util/xex2_info.h b/src/xenia/kernel/util/xex2_info.h
index f91b7c30f..6203b18f2 100644
--- a/src/xenia/kernel/util/xex2_info.h
+++ b/src/xenia/kernel/util/xex2_info.h
@@ -544,6 +544,23 @@ struct xex2_security_info {
xex2_page_descriptor page_descriptors[1]; // 0x184
};
+struct xex1_security_info {
+ xe::be<uint32_t> header_size;
+ xe::be<uint32_t> image_size;
+ char rsa_signature[0x100];
+ char image_digest[0x14];
+ char import_table_digest[0x14];
+ xe::be<uint32_t> load_address;
+ char aes_key[0x10];
+ char xgd2_media_id[0x10];
+ xe::be<uint32_t> region;
+ xe::be<uint32_t> image_flags;
+ xe::be<uint32_t> export_table;
+ xe::be<uint32_t> allowed_media_types;
+ xe::be<uint32_t> page_descriptor_count;
+ xex2_page_descriptor page_descriptors[1];
+};
+
struct xex2_export_table {
xe::be<uint32_t> magic[3]; // 0x0
xe::be<uint32_t> modulenumber[2]; // 0xC