XexExecutableModuleHandle export now points to the executing HMODULE

This commit is contained in:
Dr. Chat 2015-06-27 23:17:56 -05:00
parent 944b39c51d
commit bb900ba9db
3 changed files with 23 additions and 46 deletions

View File

@ -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) {

View File

@ -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.

View File

@ -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