From e5e697564d61f889bd0345d6507e8eea123a37cd Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sun, 20 Mar 2022 19:31:05 -0500 Subject: [PATCH] Move fixup_embedded_pck to EditorExportPlatform classes --- editor/editor_export.cpp | 18 +--- editor/editor_export.h | 14 +-- platform/linuxbsd/export/export.cpp | 108 --------------------- platform/linuxbsd/export/export_plugin.cpp | 105 ++++++++++++++++++++ platform/linuxbsd/export/export_plugin.h | 1 + platform/windows/export/export.cpp | 74 -------------- platform/windows/export/export_plugin.cpp | 71 ++++++++++++++ platform/windows/export/export_plugin.h | 1 + 8 files changed, 183 insertions(+), 209 deletions(-) diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 3c2c7232f80..d36f6b7e73b 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1890,10 +1890,7 @@ Error EditorExportPlatformPC::export_project(const Ref &p_pr return ERR_INVALID_PARAMETER; } - FixUpEmbeddedPckFunc fixup_func = get_fixup_embedded_pck_func(); - if (fixup_func) { - err = fixup_func(p_path, embedded_pos, embedded_size); - } + err = fixup_embedded_pck(p_path, embedded_pos, embedded_size); } if (err == OK && !so_files.is_empty()) { @@ -1984,19 +1981,6 @@ void EditorExportPlatformPC::set_chmod_flags(int p_flags) { chmod_flags = p_flags; } -EditorExportPlatformPC::FixUpEmbeddedPckFunc EditorExportPlatformPC::get_fixup_embedded_pck_func() const { - return fixup_embedded_pck_func; -} - -void EditorExportPlatformPC::set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func) { - fixup_embedded_pck_func = p_fixup_embedded_pck_func; -} - -EditorExportPlatformPC::EditorExportPlatformPC() { - chmod_flags = -1; - fixup_embedded_pck_func = nullptr; -} - /////////////////////// void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const Set &p_features) { diff --git a/editor/editor_export.h b/editor/editor_export.h index d9039f601e3..8cca2025745 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -421,9 +421,6 @@ public: class EditorExportPlatformPC : public EditorExportPlatform { GDCLASS(EditorExportPlatformPC, EditorExportPlatform); -public: - typedef Error (*FixUpEmbeddedPckFunc)(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); - private: Ref logo; String name; @@ -435,9 +432,7 @@ private: String debug_file_32; String debug_file_64; - int chmod_flags; - - FixUpEmbeddedPckFunc fixup_embedded_pck_func; + int chmod_flags = -1; public: virtual void get_preset_features(const Ref &p_preset, List *r_features) override; @@ -471,10 +466,9 @@ public: int get_chmod_flags() const; void set_chmod_flags(int p_flags); - FixUpEmbeddedPckFunc get_fixup_embedded_pck_func() const; - void set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func); - - EditorExportPlatformPC(); + virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const { + return Error::OK; + } }; class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp index 796e82594ab..e5caff28605 100644 --- a/platform/linuxbsd/export/export.cpp +++ b/platform/linuxbsd/export/export.cpp @@ -32,8 +32,6 @@ #include "export_plugin.h" -static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); - void register_linuxbsd_exporter() { Ref platform; platform.instantiate(); @@ -52,112 +50,6 @@ void register_linuxbsd_exporter() { platform->set_debug_64("linux_x11_64_debug"); platform->set_os_name("LinuxBSD"); platform->set_chmod_flags(0755); - platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } - -static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { - // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data - - FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); - if (!f) { - return ERR_CANT_OPEN; - } - - // Read and check ELF magic number - { - uint32_t magic = f->get_32(); - if (magic != 0x464c457f) { // 0x7F + "ELF" - f->close(); - return ERR_FILE_CORRUPT; - } - } - - // Read program architecture bits from class field - - int bits = f->get_8() * 32; - - if (bits == 32 && p_embedded_size >= 0x100000000) { - f->close(); - ERR_FAIL_V_MSG(ERR_INVALID_DATA, "32-bit executables cannot have embedded data >= 4 GiB."); - } - - // Get info about the section header table - - int64_t section_table_pos; - int64_t section_header_size; - if (bits == 32) { - section_header_size = 40; - f->seek(0x20); - section_table_pos = f->get_32(); - f->seek(0x30); - } else { // 64 - section_header_size = 64; - f->seek(0x28); - section_table_pos = f->get_64(); - f->seek(0x3c); - } - int num_sections = f->get_16(); - int string_section_idx = f->get_16(); - - // Load the strings table - uint8_t *strings; - { - // Jump to the strings section header - f->seek(section_table_pos + string_section_idx * section_header_size); - - // Read strings data size and offset - int64_t string_data_pos; - int64_t string_data_size; - if (bits == 32) { - f->seek(f->get_position() + 0x10); - string_data_pos = f->get_32(); - string_data_size = f->get_32(); - } else { // 64 - f->seek(f->get_position() + 0x18); - string_data_pos = f->get_64(); - string_data_size = f->get_64(); - } - - // Read strings data - f->seek(string_data_pos); - strings = (uint8_t *)memalloc(string_data_size); - if (!strings) { - f->close(); - return ERR_OUT_OF_MEMORY; - } - f->get_buffer(strings, string_data_size); - } - - // Search for the "pck" section - - bool found = false; - for (int i = 0; i < num_sections; ++i) { - int64_t section_header_pos = section_table_pos + i * section_header_size; - f->seek(section_header_pos); - - uint32_t name_offset = f->get_32(); - if (strcmp((char *)strings + name_offset, "pck") == 0) { - // "pck" section found, let's patch! - - if (bits == 32) { - f->seek(section_header_pos + 0x10); - f->store_32(p_embedded_start); - f->store_32(p_embedded_size); - } else { // 64 - f->seek(section_header_pos + 0x18); - f->store_64(p_embedded_start); - f->store_64(p_embedded_size); - } - - found = true; - break; - } - } - - memfree(strings); - f->close(); - - return found ? OK : ERR_FILE_CORRUPT; -} diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index 99f5b82b34a..6300a37854a 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -72,3 +72,108 @@ Error EditorExportPlatformLinuxBSD::export_project(const Ref return err; } + +Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const { + // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Read and check ELF magic number + { + uint32_t magic = f->get_32(); + if (magic != 0x464c457f) { // 0x7F + "ELF" + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Read program architecture bits from class field + + int bits = f->get_8() * 32; + + if (bits == 32 && p_embedded_size >= 0x100000000) { + f->close(); + ERR_FAIL_V_MSG(ERR_INVALID_DATA, "32-bit executables cannot have embedded data >= 4 GiB."); + } + + // Get info about the section header table + + int64_t section_table_pos; + int64_t section_header_size; + if (bits == 32) { + section_header_size = 40; + f->seek(0x20); + section_table_pos = f->get_32(); + f->seek(0x30); + } else { // 64 + section_header_size = 64; + f->seek(0x28); + section_table_pos = f->get_64(); + f->seek(0x3c); + } + int num_sections = f->get_16(); + int string_section_idx = f->get_16(); + + // Load the strings table + uint8_t *strings; + { + // Jump to the strings section header + f->seek(section_table_pos + string_section_idx * section_header_size); + + // Read strings data size and offset + int64_t string_data_pos; + int64_t string_data_size; + if (bits == 32) { + f->seek(f->get_position() + 0x10); + string_data_pos = f->get_32(); + string_data_size = f->get_32(); + } else { // 64 + f->seek(f->get_position() + 0x18); + string_data_pos = f->get_64(); + string_data_size = f->get_64(); + } + + // Read strings data + f->seek(string_data_pos); + strings = (uint8_t *)memalloc(string_data_size); + if (!strings) { + f->close(); + return ERR_OUT_OF_MEMORY; + } + f->get_buffer(strings, string_data_size); + } + + // Search for the "pck" section + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + int64_t section_header_pos = section_table_pos + i * section_header_size; + f->seek(section_header_pos); + + uint32_t name_offset = f->get_32(); + if (strcmp((char *)strings + name_offset, "pck") == 0) { + // "pck" section found, let's patch! + + if (bits == 32) { + f->seek(section_header_pos + 0x10); + f->store_32(p_embedded_start); + f->store_32(p_embedded_size); + } else { // 64 + f->seek(section_header_pos + 0x18); + f->store_64(p_embedded_start); + f->store_64(p_embedded_size); + } + + found = true; + break; + } + } + + memfree(strings); + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h index f482ddce3da..ba6c9a6a6b9 100644 --- a/platform/linuxbsd/export/export_plugin.h +++ b/platform/linuxbsd/export/export_plugin.h @@ -42,6 +42,7 @@ class EditorExportPlatformLinuxBSD : public EditorExportPlatformPC { public: virtual Error export_project(const Ref &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; + virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const override; }; #endif diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 17a24c08bfd..2a42fbf6f12 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -32,8 +32,6 @@ #include "export_plugin.h" -static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); - void register_windows_exporter() { EDITOR_DEF("export/windows/rcedit", ""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/rcedit", PROPERTY_HINT_GLOBAL_FILE, "*.exe")); @@ -63,78 +61,6 @@ void register_windows_exporter() { platform->set_release_64("windows_64_release.exe"); platform->set_debug_64("windows_64_debug.exe"); platform->set_os_name("Windows"); - platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } - -static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { - // Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data - - FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); - if (!f) { - return ERR_CANT_OPEN; - } - - // Jump to the PE header and check the magic number - { - f->seek(0x3c); - uint32_t pe_pos = f->get_32(); - - f->seek(pe_pos); - uint32_t magic = f->get_32(); - if (magic != 0x00004550) { - f->close(); - return ERR_FILE_CORRUPT; - } - } - - // Process header - - int num_sections; - { - int64_t header_pos = f->get_position(); - - f->seek(header_pos + 2); - num_sections = f->get_16(); - f->seek(header_pos + 16); - uint16_t opt_header_size = f->get_16(); - - // Skip rest of header + optional header to go to the section headers - f->seek(f->get_position() + 2 + opt_header_size); - } - - // Search for the "pck" section - - int64_t section_table_pos = f->get_position(); - - bool found = false; - for (int i = 0; i < num_sections; ++i) { - int64_t section_header_pos = section_table_pos + i * 40; - f->seek(section_header_pos); - - uint8_t section_name[9]; - f->get_buffer(section_name, 8); - section_name[8] = '\0'; - - if (strcmp((char *)section_name, "pck") == 0) { - // "pck" section found, let's patch! - - // Set virtual size to a little to avoid it taking memory (zero would give issues) - f->seek(section_header_pos + 8); - f->store_32(8); - - f->seek(section_header_pos + 16); - f->store_32(p_embedded_size); - f->seek(section_header_pos + 20); - f->store_32(p_embedded_start); - - found = true; - break; - } - } - - f->close(); - - return found ? OK : ERR_FILE_CORRUPT; -} diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 7b9cb598968..e579c967fb6 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -403,3 +403,74 @@ bool EditorExportPlatformWindows::can_export(const Ref &p_pr return valid; } + +Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const { + // Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Jump to the PE header and check the magic number + { + f->seek(0x3c); + uint32_t pe_pos = f->get_32(); + + f->seek(pe_pos); + uint32_t magic = f->get_32(); + if (magic != 0x00004550) { + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Process header + + int num_sections; + { + int64_t header_pos = f->get_position(); + + f->seek(header_pos + 2); + num_sections = f->get_16(); + f->seek(header_pos + 16); + uint16_t opt_header_size = f->get_16(); + + // Skip rest of header + optional header to go to the section headers + f->seek(f->get_position() + 2 + opt_header_size); + } + + // Search for the "pck" section + + int64_t section_table_pos = f->get_position(); + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + int64_t section_header_pos = section_table_pos + i * 40; + f->seek(section_header_pos); + + uint8_t section_name[9]; + f->get_buffer(section_name, 8); + section_name[8] = '\0'; + + if (strcmp((char *)section_name, "pck") == 0) { + // "pck" section found, let's patch! + + // Set virtual size to a little to avoid it taking memory (zero would give issues) + f->seek(section_header_pos + 8); + f->store_32(8); + + f->seek(section_header_pos + 16); + f->store_32(p_embedded_size); + f->seek(section_header_pos + 20); + f->store_32(p_embedded_start); + + found = true; + break; + } + } + + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h index b40e8724610..c483917a4c8 100644 --- a/platform/windows/export/export_plugin.h +++ b/platform/windows/export/export_plugin.h @@ -48,6 +48,7 @@ public: virtual void get_export_options(List *r_options) override; virtual bool get_export_option_visibility(const String &p_option, const Map &p_options) const override; virtual bool can_export(const Ref &p_preset, String &r_error, bool &r_missing_templates) const override; + virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const override; }; #endif