[CPU] Add XEXP support to XexModule, if XEXP is in same folder as XEX

This was a headache to work out, big thanks to the lack of documentation on .xexp files... a ton of guesswork was involved here but luckily it turned out well.

I did have to make some pretty major changes to the way XEX files are loaded though.
Previously it'd just load everything in one go: XEX headers -> decrypt/decompress data -> load imports/symbols -> set loader data table entries, etc...

Now it's changed to something like this:
- Load base XEX headers + decrypted/decompressed image data, return X_STATUS_PENDING
- In the LoadFromFile call used to load the XEX, search for XEXP patch file (only .xexp in same folder atm)
- If patch exists: load XEXP, decrypt headers/data, apply patch to base XEX, dispose of XEXP
- Finish XEX load via LoadXexContinue() (handles imports/symbols/loader data...)

This saves us from needing to reset the imports/function/symbol stuff after patching (since all the XEX code will be a lot different), but I'm not really sure if I went about it the best way.
This commit is contained in:
emoose
2018-10-20 04:36:21 +01:00
parent 0b7f7e1657
commit 265903fe66
5 changed files with 589 additions and 223 deletions

View File

@@ -436,12 +436,20 @@ struct xex2_opt_resource_info {
xex2_resource resources[1]; // 0x4
};
struct xex2_delta_patch {
xe::be<uint32_t> old_addr;
xe::be<uint32_t> new_addr;
xe::be<uint16_t> uncompressed_len;
xe::be<uint16_t> compressed_len;
char patch_data[1];
};
struct xex2_opt_delta_patch_descriptor {
xe::be<uint32_t> size; // 0x0
xex2_version target_version; // 0x4
xex2_version source_version; // 0x8
char digest_source[0x14]; // 0xC
char image_key_source[0x10]; // 0x20
uint8_t digest_source[0x14]; // 0xC
uint8_t image_key_source[0x10]; // 0x20
xe::be<uint32_t> size_of_target_headers; // 0x30
xe::be<uint32_t> delta_headers_source_offset; // 0x34
xe::be<uint32_t> delta_headers_source_size; // 0x38
@@ -449,9 +457,8 @@ struct xex2_opt_delta_patch_descriptor {
xe::be<uint32_t> delta_image_source_offset; // 0x40
xe::be<uint32_t> delta_image_source_size; // 0x44
xe::be<uint32_t> delta_image_target_offset; // 0x48
char delta_header_patch_data[1];
xex2_delta_patch info; // 0x4C
};
// static_assert_size(xex2_opt_delta_patch_descriptor, 0x4D);
struct xex2_opt_execution_info {
xe::be<uint32_t> media_id; // 0x0