Iterating on RtImageXexHeaderField.

This commit is contained in:
Ben Vanik 2015-06-28 13:44:59 -07:00
parent 996f99bd85
commit 010b701e05
4 changed files with 23 additions and 19 deletions

View File

@ -153,12 +153,13 @@ X_STATUS XUserModule::GetOptHeader(xe_xex2_header_keys key,
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;
} }
auto ptr = xex2_get_opt_header(header, key); uint32_t field_value =
if (!ptr) { xex2_get_opt_header(memory()->virtual_membase(), header, key);
if (!field_value) {
return X_STATUS_NOT_FOUND; return X_STATUS_NOT_FOUND;
} }
*out_header_guest_ptr = (uint32_t)(ptr - memory()->virtual_membase()); *out_header_guest_ptr = field_value;
return X_STATUS_SUCCESS; return X_STATUS_SUCCESS;
} }

View File

@ -29,23 +29,29 @@
namespace xe { namespace xe {
namespace kernel { namespace kernel {
uint8_t *xex2_get_opt_header(const xex2_header *header, uint32_t key) { uint32_t xex2_get_opt_header(uint8_t *membase, const xex2_header *header,
uint32_t key) {
for (uint32_t i = 0; i < header->header_count; i++) { for (uint32_t i = 0; i < header->header_count; i++) {
const xex2_opt_header &opt_header = header->headers[i]; const xex2_opt_header &opt_header = header->headers[i];
if (opt_header.key != key) { if (opt_header.key != key) {
continue; continue;
} }
if ((opt_header.key & 0xFF) == 0x01) { switch (opt_header.key & 0xFF) {
// Data is stored in the opt header case 0x00:
return (uint8_t *)&opt_header.value; // Return data stored in header value.
} else { return opt_header.value;
// Data stored at offset. case 0x01:
return ((uint8_t *)&header->headers[0] + opt_header.offset); // Return pointer to data stored in header value.
return uint32_t((uint8_t *)&opt_header.value - membase);
default:
// Data stored at offset to header.
return uint32_t((uint8_t *)&header->headers[0] - membase) +
opt_header.offset;
} }
} }
return nullptr; return 0;
} }
uint32_t xex2_get_header_size(const xex2_header *header) { uint32_t xex2_get_header_size(const xex2_header *header) {

View File

@ -15,8 +15,8 @@
namespace xe { namespace xe {
namespace kernel { namespace kernel {
uint8_t* xex2_get_opt_header(const xex2_header* header, uint32_t key); uint32_t xex2_get_opt_header(uint8_t* membase, const xex2_header* header,
uint32_t key);
uint32_t xex2_get_header_size(const xex2_header* header); uint32_t xex2_get_header_size(const xex2_header* header);
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -394,12 +394,9 @@ SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_context,
return; return;
} }
uint8_t* field_ptr = xex2_get_opt_header(header, image_field); uint32_t field_value =
if (!field_ptr) { xex2_get_opt_header(SHIM_MEM_BASE, header, image_field);
SHIM_SET_RETURN_32(0); SHIM_SET_RETURN_32(field_value);
return;
}
SHIM_SET_RETURN_32(uint32_t(field_ptr - kernel_memory()->virtual_membase()));
} }
// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one // Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one