[Kernel] Enable XEX1 loading
This commit is contained in:
parent
03d5455a2f
commit
bc8b629092
|
@ -103,10 +103,9 @@ bool XexModule::GetOptHeader(xex2_header_keys key, void** out_ptr) const {
|
||||||
return XexModule::GetOptHeader(xex_header(), key, out_ptr);
|
return XexModule::GetOptHeader(xex_header(), key, out_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const xex2_security_info* XexModule::GetSecurityInfo(
|
const void* XexModule::GetSecurityInfo(const xex2_header* header) {
|
||||||
const xex2_header* header) {
|
return reinterpret_cast<const void*>(uintptr_t(header) +
|
||||||
return reinterpret_cast<const xex2_security_info*>(uintptr_t(header) +
|
header->security_offset);
|
||||||
header->security_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PESection* XexModule::GetPESection(const char* name) {
|
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) {
|
const void* xex_addr, size_t xex_length) {
|
||||||
auto src_header = reinterpret_cast<const xex2_header*>(xex_addr);
|
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;
|
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);
|
xex_header_mem_.resize(src_header->header_size);
|
||||||
std::memcpy(xex_header_mem_.data(), src_header, 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();
|
auto sec_header = xex_security_info();
|
||||||
|
|
||||||
// Try setting our base_address based on XEX_HEADER_IMAGE_BASE_ADDRESS, fall
|
// Try setting our base_address based on XEX_HEADER_IMAGE_BASE_ADDRESS, fall
|
||||||
|
|
|
@ -43,6 +43,21 @@ class XexModule : public xe::cpu::Module {
|
||||||
xe_xex2_version_t min_version;
|
xe_xex2_version_t min_version;
|
||||||
std::vector<ImportLibraryFn> imports;
|
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);
|
XexModule(Processor* processor, kernel::KernelState* kernel_state);
|
||||||
virtual ~XexModule();
|
virtual ~XexModule();
|
||||||
|
@ -51,8 +66,8 @@ class XexModule : public xe::cpu::Module {
|
||||||
const xex2_header* xex_header() const {
|
const xex2_header* xex_header() const {
|
||||||
return reinterpret_cast<const xex2_header*>(xex_header_mem_.data());
|
return reinterpret_cast<const xex2_header*>(xex_header_mem_.data());
|
||||||
}
|
}
|
||||||
const xex2_security_info* xex_security_info() const {
|
const SecurityInfoContext* xex_security_info() const {
|
||||||
return GetSecurityInfo(xex_header());
|
return &security_info_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t image_size() const {
|
uint32_t image_size() const {
|
||||||
|
@ -112,7 +127,7 @@ class XexModule : public xe::cpu::Module {
|
||||||
return GetOptHeader(key, reinterpret_cast<void**>(out_ptr));
|
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);
|
const PESection* GetPESection(const char* name);
|
||||||
|
|
||||||
|
@ -186,6 +201,9 @@ class XexModule : public xe::cpu::Module {
|
||||||
uint32_t base_address_ = 0;
|
uint32_t base_address_ = 0;
|
||||||
uint32_t low_address_ = 0;
|
uint32_t low_address_ = 0;
|
||||||
uint32_t high_address_ = 0;
|
uint32_t high_address_ = 0;
|
||||||
|
|
||||||
|
XexFormat xex_format_ = kFormatUnknown;
|
||||||
|
SecurityInfoContext security_info_ = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
|
|
|
@ -135,7 +135,7 @@ X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) {
|
||||||
auto processor = kernel_state()->processor();
|
auto processor = kernel_state()->processor();
|
||||||
|
|
||||||
auto magic = xe::load_and_swap<uint32_t>(addr);
|
auto magic = xe::load_and_swap<uint32_t>(addr);
|
||||||
if (magic == 'XEX2') {
|
if (magic == 'XEX2' || magic == 'XEX1') {
|
||||||
module_format_ = kModuleFormatXex;
|
module_format_ = kModuleFormatXex;
|
||||||
} else if (magic == 0x7F454C46 /* 0x7F 'ELF' */) {
|
} else if (magic == 0x7F454C46 /* 0x7F 'ELF' */) {
|
||||||
module_format_ = kModuleFormatElf;
|
module_format_ = kModuleFormatElf;
|
||||||
|
|
|
@ -544,6 +544,23 @@ struct xex2_security_info {
|
||||||
xex2_page_descriptor page_descriptors[1]; // 0x184
|
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 {
|
struct xex2_export_table {
|
||||||
xe::be<uint32_t> magic[3]; // 0x0
|
xe::be<uint32_t> magic[3]; // 0x0
|
||||||
xe::be<uint32_t> modulenumber[2]; // 0xC
|
xe::be<uint32_t> modulenumber[2]; // 0xC
|
||||||
|
|
Loading…
Reference in New Issue