From 5cef220e9f2b4d1278a53c07ced5b6ffb319ff2f Mon Sep 17 00:00:00 2001 From: Sajid Date: Fri, 13 Sep 2024 16:13:19 +0600 Subject: [PATCH] Implement xex imports --- PowerUtils/xex.cpp | 33 +++++++++++++++++++++++++++++- PowerUtils/xex.h | 51 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/PowerUtils/xex.cpp b/PowerUtils/xex.cpp index dc658c3..721c1a4 100644 --- a/PowerUtils/xex.cpp +++ b/PowerUtils/xex.cpp @@ -1,6 +1,7 @@ #include "xex.h" #include "image.h" #include +#include Image Xex2LoadImage(const uint8_t* data) { @@ -79,5 +80,35 @@ Image Xex2LoadImage(const uint8_t* data) section.Misc.VirtualSize, flags, image.data.get() + section.VirtualAddress); } + auto* imports = Xex2FindOptionalHeader(header, XEX_HEADER_IMPORT_LIBRARIES); + if (imports != nullptr) + { + std::vector stringTable; + auto* pStrTable = reinterpret_cast(imports + 1); + + for (size_t i = 0; i < imports->NumImports; i++) + { + stringTable.emplace_back(pStrTable); + pStrTable += strlen(pStrTable) + 1; + } + + auto* library = (XEX_IMPORT_LIBRARY*)(((char*)imports) + sizeof(XEX_IMPORT_HEADER) + imports->SizeOfStringTable); + for (size_t i = 0; i < stringTable.size(); i++) + { + auto* descriptors = (XEX_IMPORT_DESCRIPTOR*)(library + 1); + for (size_t im = 0; im < library->NumberOfImports; im++) + { + auto originalThunk = (XEX_THUNK_DATA*)image.Find(descriptors[im].FirstThunk); + auto thunkType = originalThunk->Function >> 24; + + if (thunkType == 1) + { + uint32_t thunk[4] = { 0x00000060, 0x00000060, 0x00000060, 0x2000804E }; + memcpy(originalThunk, thunk, sizeof(thunk)); + } + } + } + } + return image; -} \ No newline at end of file +} diff --git a/PowerUtils/xex.h b/PowerUtils/xex.h index 0ff0a5e..eb82e54 100644 --- a/PowerUtils/xex.h +++ b/PowerUtils/xex.h @@ -7,6 +7,12 @@ #define XEX_ENCRYPTION_NONE 0 +enum _XEX_THUNK_TYPES +{ + XEX_THUNK_VARIABLE = 0, + XEX_THUNK_FUNCTION = 1, +}; + enum _XEX_OPTIONAL_HEADER_TYPES { XEX_HEADER_RESOURCE_INFO = 0x000002FF, @@ -54,10 +60,51 @@ typedef struct _XEX_BASIC_FILE_COMPRESSION_INFO be SizeOfPadding; } XEX_BASIC_FILE_COMPRESSION_INFO; +typedef struct _XEX_THUNK_DATA { + union + { + struct + { + WORD Ordinal : 16; + WORD Hint : 8; + WORD Type : 8; + } OriginalData; + + XDWORD Ordinal; + XDWORD Function; + XDWORD AddressOfData; + + // For easier swapping + DWORD Data; + }; +} XEX_THUNK_DATA; + +typedef struct _XEX_IMPORT_HEADER { + XDWORD SizeOfHeader; + XDWORD SizeOfStringTable; + XDWORD NumImports; +} XEX_IMPORT_HEADER; + +typedef struct _XEX_IMPORT_LIBRARY { + XDWORD Size; + char NextImportDigest[0x14]; + XDWORD ID; + XDWORD Version; + XDWORD MinVersion; + XWORD Name; + XWORD NumberOfImports; +} XEX_IMPORT_LIBRARY; + +static_assert(sizeof(XEX_IMPORT_LIBRARY) == 0x28); + +typedef struct _XEX_IMPORT_DESCRIPTOR { + XDWORD FirstThunk; // VA XEX_THUNK_DATA +} XEX_IMPORT_DESCRIPTOR; + typedef struct _XEX_OPTIONAL_HEADER { - be Type; - be Address; + XDWORD Type; + XDWORD Address; } XEX_OPTIONAL_HEADER; typedef struct _XEX2_SECURITY_INFO