XexExecutableModuleHandle export now points to the executing HMODULE
This commit is contained in:
parent
944b39c51d
commit
bb900ba9db
|
@ -68,6 +68,7 @@ KernelState::KernelState(Emulator* emulator)
|
|||
shared_kernel_state_ = this;
|
||||
|
||||
process_info_block_address_ = memory_->SystemHeapAlloc(0x60);
|
||||
|
||||
auto pib =
|
||||
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
|
||||
// TODO(benvanik): figure out what this list is.
|
||||
|
@ -188,6 +189,17 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
|
|||
pib->tls_raw_data_size = header->tls_info.raw_data_size;
|
||||
pib->tls_slot_size = header->tls_info.slot_count * 4;
|
||||
}
|
||||
|
||||
// Setup the kernel's XexExecutableModuleHandle field
|
||||
auto exp = processor()->export_resolver()->GetExportByOrdinal(
|
||||
"xboxkrnl.exe", ordinals::XexExecutableModuleHandle);
|
||||
|
||||
if (exp) {
|
||||
auto variable_ptr =
|
||||
memory()->TranslateVirtual<xe::be<uint32_t>*>(exp->variable_ptr);
|
||||
|
||||
*variable_ptr = module->hmodule_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
|
||||
|
|
|
@ -89,17 +89,9 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
|||
// 0x80101058 <- pointer to xex header
|
||||
// 0x80101100 <- xex header base
|
||||
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
|
||||
auto lppXexExecutableModuleHandle =
|
||||
memory_->TranslateVirtual(ppXexExecutableModuleHandle);
|
||||
export_resolver_->SetVariableMapping("xboxkrnl.exe",
|
||||
ordinals::XexExecutableModuleHandle,
|
||||
ppXexExecutableModuleHandle);
|
||||
uint32_t pXexExecutableModuleHandle = memory_->SystemHeapAlloc(256);
|
||||
auto lpXexExecutableModuleHandle =
|
||||
memory_->TranslateVirtual(pXexExecutableModuleHandle);
|
||||
xe::store_and_swap<uint32_t>(lppXexExecutableModuleHandle,
|
||||
pXexExecutableModuleHandle);
|
||||
xe::store_and_swap<uint32_t>(lpXexExecutableModuleHandle + 0x58, 0x80101100);
|
||||
|
||||
// ExLoadedCommandLine (char*)
|
||||
// The name of the xex. Not sure this is ever really used on real devices.
|
||||
|
|
|
@ -385,49 +385,22 @@ SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_context,
|
|||
uint32_t xex_header_base = SHIM_GET_ARG_32(0);
|
||||
uint32_t image_field = SHIM_GET_ARG_32(1);
|
||||
|
||||
// NOTE: this is totally faked!
|
||||
// We set the XexExecutableModuleHandle pointer to a block that has at offset
|
||||
// 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match
|
||||
// then die.
|
||||
// The only ImageField I've seen in the wild is
|
||||
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
||||
|
||||
XELOGD("RtlImageXexHeaderField(%.8X, %.8X)", xex_header_base, image_field);
|
||||
|
||||
// PVOID
|
||||
// PVOID XexHeaderBase
|
||||
// DWORD ImageField
|
||||
|
||||
// NOTE: this is totally faked!
|
||||
// We set the XexExecutableModuleHandle pointer to a block that has at offset
|
||||
// 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match
|
||||
// then die.
|
||||
|
||||
// TODO(benvanik): use xex_header_base to dereference this.
|
||||
// Right now we are only concerned with games making this call on their main
|
||||
// module, so this hack is fine.
|
||||
assert_true(xex_header_base == 0x80101100);
|
||||
auto module = kernel_state->GetExecutableModule();
|
||||
|
||||
const xe_xex2_header_t* xex_header = module->xex_header();
|
||||
for (size_t n = 0; n < xex_header->header_count; n++) {
|
||||
if (xex_header->headers[n].key == image_field) {
|
||||
uint32_t value = xex_header->headers[n].value;
|
||||
SHIM_SET_RETURN_32(value);
|
||||
return;
|
||||
}
|
||||
auto header =
|
||||
kernel_memory()->TranslateVirtual<xex2_header*>(xex_header_base);
|
||||
if (!header) {
|
||||
SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Some games seem to expect 0xC0000225 for not-found results, while
|
||||
// others will explode if it's not zero. Maybe there are default headers?
|
||||
switch (image_field) {
|
||||
case 0x20401: // XEX_HEADER_DEFAULT_HEAP_SIZE
|
||||
SHIM_SET_RETURN_32(0);
|
||||
break;
|
||||
default:
|
||||
SHIM_SET_RETURN_32(X_STATUS_NOT_FOUND);
|
||||
break;
|
||||
uint8_t* hdr = xex2_get_opt_header(header, image_field);
|
||||
if (!hdr) {
|
||||
SHIM_SET_RETURN_32(X_STATUS_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32((uint32_t)(hdr - kernel_memory()->virtual_membase()));
|
||||
}
|
||||
|
||||
// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one
|
||||
|
|
Loading…
Reference in New Issue