[CPU] Check for modification of base_address during patch application

This commit is contained in:
Gliniak 2024-09-15 17:08:23 +02:00
parent f95a1e591b
commit edc829f3e6
1 changed files with 28 additions and 0 deletions

View File

@ -224,6 +224,8 @@ int XexModule::ApplyPatch(XexModule* module) {
return 1; return 1;
} }
const uint32_t original_base_address = module->base_address();
// Grab the delta descriptor and get to work. // Grab the delta descriptor and get to work.
xex2_opt_delta_patch_descriptor* patch_header = nullptr; xex2_opt_delta_patch_descriptor* patch_header = nullptr;
GetOptHeader(XEX_HEADER_DELTA_PATCH_DESCRIPTOR, GetOptHeader(XEX_HEADER_DELTA_PATCH_DESCRIPTOR,
@ -317,6 +319,25 @@ int XexModule::ApplyPatch(XexModule* module) {
uint32_t size_delta = new_image_size - original_image_size; uint32_t size_delta = new_image_size - original_image_size;
uint32_t addr_new_mem = module->base_address_ + original_image_size; uint32_t addr_new_mem = module->base_address_ + original_image_size;
// Before we allocate new range we must check if patch haven't modified
// base_address.
uint32_t new_base_address = module->base_address();
xe::be<uint32_t>* base_addr_opt = nullptr;
if (module->GetOptHeader(XEX_HEADER_IMAGE_BASE_ADDRESS, &base_addr_opt)) {
new_base_address = *base_addr_opt;
}
if (original_base_address != new_base_address) {
XELOGW(
"Patch for module: {} changed base_address from {:08X} to {:08X}, "
"need to reallocate xex "
"data!",
module->name(), module->base_address_, new_base_address);
module->base_address_ = new_base_address;
addr_new_mem = new_base_address;
size_delta = new_image_size;
}
bool alloc_result = bool alloc_result =
memory() memory()
->LookupHeap(addr_new_mem) ->LookupHeap(addr_new_mem)
@ -331,6 +352,13 @@ int XexModule::ApplyPatch(XexModule* module) {
assert_always(); assert_always();
return 6; return 6;
} }
// For base_address change we need to copy data from previous allocation to
// new one
if (original_base_address != new_base_address) {
kernel_state_->memory()->Copy(new_base_address, original_base_address,
original_image_size);
}
} }
uint8_t orig_session_key[0x10]; uint8_t orig_session_key[0x10];