From be5f8d3aa4e27fea69306657fba3594c382460ce Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Mon, 29 Jun 2015 01:54:13 -0500 Subject: [PATCH] Simplify some logic in parsing import libraries Change struct used in export lookups --- src/xenia/kernel/util/xex2.cc | 82 +++++++++++++++---------------- src/xenia/kernel/util/xex2.h | 3 -- src/xenia/kernel/util/xex2_info.h | 24 ++++----- 3 files changed, 52 insertions(+), 57 deletions(-) diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 238ecb64d..94f2a387b 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -28,11 +28,6 @@ #include "xenia/base/platform.h" namespace xe { -namespace kernel { -uint32_t xex2_get_header_size(const xex2_header* header) { - return header->exe_offset; -} -} // namespace kernel } // namespace xe // TODO(benvanik): remove. @@ -251,56 +246,59 @@ int xe_xex2_read_header(const uint8_t* addr, const size_t length, // size = xe::load_and_swap(pp + 0x04); } break; case XEX_HEADER_IMPORT_LIBRARIES: { - const size_t max_count = xe::countof(header->import_libraries); - size_t count = xe::load_and_swap(pp + 0x08); + auto import_libraries = + reinterpret_cast(pp); + + const uint32_t max_count = (uint32_t)xe::countof(header->import_libraries); + uint32_t count = import_libraries->library_count; assert_true(count <= max_count); if (count > max_count) { XELOGW("ignoring %zu extra entries in XEX_HEADER_IMPORT_LIBRARIES", - (max_count - count)); + (max_count - import_libraries->library_count)); count = max_count; } header->import_library_count = count; - uint32_t string_table_size = xe::load_and_swap(pp + 0x04); - const char* string_table = (const char*)(pp + 0x0C); + uint32_t string_table_size = import_libraries->string_table_size; + const char *string_table[32]; // Pretend 32 is max_count + std::memset(string_table, 0, sizeof(string_table)); - pp += 12 + string_table_size; + // Parse the string table + for (size_t i = 0, j = 0; i < string_table_size; j++) { + const char* str = import_libraries->string_table + i; + + string_table[j] = str; + i += std::strlen(str) + 1; + + // Padding + if ((i % 4) != 0) { + i += 4 - (i % 4); + } + } + + pp += 12 + import_libraries->string_table_size; for (size_t m = 0; m < count; m++) { xe_xex2_import_library_t* library = &header->import_libraries[m]; + auto src_library = (xe::xex2_import_library *)pp; + memcpy(library->digest, pp + 0x04, 20); - library->import_id = xe::load_and_swap(pp + 0x18); - library->version.value = xe::load_and_swap(pp + 0x1C); - library->min_version.value = xe::load_and_swap(pp + 0x20); + library->import_id = src_library->id; + library->version.value = src_library->version.value; + library->min_version.value = src_library->version_min.value; - const uint16_t name_index = - xe::load_and_swap(pp + 0x24) & 0xFF; - for (size_t i = 0, j = 0; i < string_table_size;) { - assert_true(j <= 0xFF); - if (j == name_index) { - std::strncpy(library->name, string_table + i, - xe::countof(library->name)); - break; - } - if (string_table[i] == 0) { - i++; - if (i % 4) { - i += 4 - (i % 4); - } - j++; - } else { - i++; - } - } + std::strncpy(library->name, + string_table[src_library->name_index], + xe::countof(library->name)); - library->record_count = xe::load_and_swap(pp + 0x26); + library->record_count = src_library->count; library->records = (uint32_t*)calloc(library->record_count, sizeof(uint32_t)); XEEXPECTNOTNULL(library->records); - pp += 0x28; for (size_t i = 0; i < library->record_count; i++) { - library->records[i] = xe::load_and_swap(pp); - pp += 4; + library->records[i] = src_library->import_table[i]; } + + pp += src_library->size; } } break; case XEX_HEADER_STATIC_LIBRARIES: { @@ -1058,17 +1056,17 @@ uint32_t xe_xex2_lookup_export(xe_xex2_ref xex, uint16_t ordinal) { // XEX-style export table. if (header->loader_info.export_table) { - auto export_table = reinterpret_cast( + auto export_table = reinterpret_cast( xex->memory->TranslateVirtual(header->loader_info.export_table)); - uint32_t ordinal_count = xe::byte_swap(export_table->count); - uint32_t ordinal_base = xe::byte_swap(export_table->base); + uint32_t ordinal_count = export_table->count; + uint32_t ordinal_base = export_table->base; if (ordinal > ordinal_count) { XELOGE("xe_xex2_lookup_export: ordinal out of bounds"); return 0; } uint32_t i = ordinal - ordinal_base; - uint32_t ordinal_offset = xe::byte_swap(export_table->ordOffset[i]); - ordinal_offset += xe::byte_swap(export_table->imagebaseaddr) << 16; + uint32_t ordinal_offset = export_table->ordOffset[i]; + ordinal_offset += export_table->imagebaseaddr << 16; return ordinal_offset; } diff --git a/src/xenia/kernel/util/xex2.h b/src/xenia/kernel/util/xex2.h index 85a674b95..77493087f 100644 --- a/src/xenia/kernel/util/xex2.h +++ b/src/xenia/kernel/util/xex2.h @@ -14,9 +14,6 @@ #include "xenia/memory.h" namespace xe { -namespace kernel { -uint32_t xex2_get_header_size(const xex2_header* header); -} // namespace kernel } // namespace xe typedef struct { int reserved; } xe_xex2_options_t; diff --git a/src/xenia/kernel/util/xex2_info.h b/src/xenia/kernel/util/xex2_info.h index afd1ea087..21dece244 100644 --- a/src/xenia/kernel/util/xex2_info.h +++ b/src/xenia/kernel/util/xex2_info.h @@ -297,18 +297,6 @@ typedef struct { xe_xex2_approval_type approval; } xe_xex2_static_library_t; -// credits: some obscure pastebin (http://pastebin.com/ZRvr3Sgj) -typedef struct { - uint32_t magic[3]; - uint32_t modulenumber[2]; - uint32_t version[3]; - uint32_t imagebaseaddr; // must be <<16 to be accurate - uint32_t count; - uint32_t base; - uint32_t ordOffset[1]; // ordOffset[0] + (imagebaseaddr << 16) = function - // offset of ordinal 1 -} xe_xex2_export_table; - typedef enum { XEX_ENCRYPTION_NONE = 0, XEX_ENCRYPTION_NORMAL = 1, @@ -585,6 +573,18 @@ struct xex2_security_info { xe::be allowed_media_types; // 0x17C }; static_assert_size(xex2_security_info, 0x180); + +struct xex2_export_table { + xe::be magic[3]; // 0x0 + xe::be modulenumber[2]; // 0xC + xe::be version[3]; // 0x14 + xe::be imagebaseaddr; // 0x20 must be <<16 to be accurate + xe::be count; // 0x24 + xe::be base; // 0x28 + xe::be + ordOffset[1]; // 0x2C ordOffset[0] + (imagebaseaddr << 16) = function +}; + } // namespace xe #endif // XENIA_KERNEL_XEX2_INFO_H_