mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-11-04 06:47:09 +00:00 
			
		
		
		
	XEX2 Loading Fixes (#51)
* Fixes loading .xex import table names when a name is not aligned to 4 bytes. * Fixes loading .xex optional headers, adds missing case when the header_key & 0xFF == 1 * Fixes loading .xex base address and entry point to be the XEX2 base/entry to successfully resolve all import thunks.
This commit is contained in:
		@@ -201,8 +201,17 @@ Image Xex2LoadImage(const uint8_t* data, size_t dataSize)
 | 
				
			|||||||
    const auto* dosHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(image.data.get());
 | 
					    const auto* dosHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(image.data.get());
 | 
				
			||||||
    const auto* ntHeaders = reinterpret_cast<IMAGE_NT_HEADERS32*>(image.data.get() + dosHeader->e_lfanew);
 | 
					    const auto* ntHeaders = reinterpret_cast<IMAGE_NT_HEADERS32*>(image.data.get() + dosHeader->e_lfanew);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    image.base = ntHeaders->OptionalHeader.ImageBase;
 | 
					    image.base = security->loadAddress;
 | 
				
			||||||
    image.entry_point = image.base + ntHeaders->OptionalHeader.AddressOfEntryPoint;
 | 
					    const void* xex2BaseAddressPtr = getOptHeaderPtr(data, XEX_HEADER_IMAGE_BASE_ADDRESS);
 | 
				
			||||||
 | 
					    if (xex2BaseAddressPtr != nullptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        image.base = *reinterpret_cast<const be<uint32_t>*>(xex2BaseAddressPtr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const void* xex2EntryPointPtr = getOptHeaderPtr(data, XEX_HEADER_ENTRY_POINT);
 | 
				
			||||||
 | 
					    if (xex2EntryPointPtr != nullptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        image.entry_point = *reinterpret_cast<const be<uint32_t>*>(xex2EntryPointPtr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auto numSections = ntHeaders->FileHeader.NumberOfSections;
 | 
					    const auto numSections = ntHeaders->FileHeader.NumberOfSections;
 | 
				
			||||||
    const auto* sections = reinterpret_cast<const IMAGE_SECTION_HEADER*>(ntHeaders + 1);
 | 
					    const auto* sections = reinterpret_cast<const IMAGE_SECTION_HEADER*>(ntHeaders + 1);
 | 
				
			||||||
@@ -227,10 +236,13 @@ Image Xex2LoadImage(const uint8_t* data, size_t dataSize)
 | 
				
			|||||||
        std::vector<std::string_view> stringTable;
 | 
					        std::vector<std::string_view> stringTable;
 | 
				
			||||||
        auto* pStrTable = reinterpret_cast<const char*>(imports + 1);
 | 
					        auto* pStrTable = reinterpret_cast<const char*>(imports + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        size_t paddedStringOffset = 0;
 | 
				
			||||||
        for (size_t i = 0; i < imports->numImports; i++)
 | 
					        for (size_t i = 0; i < imports->numImports; i++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            stringTable.emplace_back(pStrTable);
 | 
					            stringTable.emplace_back(pStrTable + paddedStringOffset);
 | 
				
			||||||
            pStrTable += strlen(pStrTable) + 1;
 | 
					            
 | 
				
			||||||
 | 
					            // pad the offset to the next multiple of 4
 | 
				
			||||||
 | 
					            paddedStringOffset += ((stringTable.back().length() + 1) + 3) & ~3;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto* library = (Xex2ImportLibrary*)(((char*)imports) + sizeof(Xex2ImportHeader) + imports->sizeOfStringTable);
 | 
					        auto* library = (Xex2ImportLibrary*)(((char*)imports) + sizeof(Xex2ImportHeader) + imports->sizeOfStringTable);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -245,13 +245,17 @@ inline const void* getOptHeaderPtr(const uint8_t* moduleBytes, uint32_t headerKe
 | 
				
			|||||||
        const Xex2OptHeader& optHeader = ((const Xex2OptHeader*)(xex2Header + 1))[i];
 | 
					        const Xex2OptHeader& optHeader = ((const Xex2OptHeader*)(xex2Header + 1))[i];
 | 
				
			||||||
        if (optHeader.key == headerKey)
 | 
					        if (optHeader.key == headerKey)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if ((headerKey & 0xFF) == 0)
 | 
					            if((headerKey & 0xFF) == 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return &optHeader.value;
 | 
					                return reinterpret_cast<const uint32_t *>(&optHeader.value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if ((headerKey & 0xFF) == 1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return reinterpret_cast<const void *>(&optHeader.value);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return &moduleBytes[optHeader.offset];
 | 
					                return reinterpret_cast<const void *>(reinterpret_cast<uintptr_t>(moduleBytes) + optHeader.offset);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user