diff options
Diffstat (limited to 'src/wiiu')
| -rw-r--r-- | src/wiiu/CMakeLists.txt | 71 | ||||
| -rw-r--r-- | src/wiiu/ReadMe.md | 14 | ||||
| -rw-r--r-- | src/wiiu/cafe_loader.cpp | 24 | ||||
| -rw-r--r-- | src/wiiu/cafe_loader.h | 12 | ||||
| -rw-r--r-- | src/wiiu/wiiu.cpp | 41 |
5 files changed, 104 insertions, 58 deletions
diff --git a/src/wiiu/CMakeLists.txt b/src/wiiu/CMakeLists.txt index 1f472ff..0d723cc 100644 --- a/src/wiiu/CMakeLists.txt +++ b/src/wiiu/CMakeLists.txt @@ -1,28 +1,63 @@ -cmake_minimum_required(VERSION 2.8) -project(wiiuldr) +cmake_minimum_required(VERSION 3.27) +project(wiiuldr LANGUAGES CXX) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/../../cmake) -set(ELF_COMMON_PATH ${CMAKE_SOURCE_DIR}/../elf_common) -set(THIRD_PARTY_PATH ${CMAKE_SOURCE_DIR}../../third_party) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(REPO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../..") +set(ELF_COMMON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../elf_common") +set(IDA_SDK_ROOT "${REPO_ROOT}/third_party/ida-sdk/src") +set(IDA_INCLUDE_DIR "${IDA_SDK_ROOT}/include") +set(IDA_LOADER_DIR "${IDA_SDK_ROOT}/ldr") +set(IDA_LIBRARY "${IDA_SDK_ROOT}/lib/x64_win_64/ida.lib") + +if(NOT EXISTS "${IDA_INCLUDE_DIR}/ida.hpp") + message(FATAL_ERROR + "The ida-sdk submodule was not found at ${IDA_SDK_ROOT}. " + "Initialize submodules before configuring this project.") +endif() + +if(NOT EXISTS "${IDA_LIBRARY}") + message(FATAL_ERROR + "The 64-bit Windows IDA import library was not found at ${IDA_LIBRARY}.") +endif() + +if(NOT MSVC) + message(FATAL_ERROR "The Wii U loader is configured for Visual Studio/MSVC builds.") +endif() + +if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "Build the Wii U loader with a 64-bit generator (-A x64).") +endif() set(SOURCES - ${ELF_COMMON_PATH}/elf_reader.h - ${ELF_COMMON_PATH}/elf.h - tinfl.c - cafe_loader.cpp + "${ELF_COMMON_PATH}/elf_reader.h" + "${ELF_COMMON_PATH}/elf.h" + cafe.h cafe_loader.h + cafe_loader.cpp wiiu.cpp - cafe.h ) -find_package(IDA) +add_library(wiiuldr SHARED ${SOURCES}) -include_directories(${IDA_INCLUDE_DIR}) -include_directories(${IDA_SDK_PATH}/ldr) -include_directories(${ELF_COMMON_PATH}) +target_include_directories(wiiuldr PRIVATE + "${IDA_INCLUDE_DIR}" + "${IDA_LOADER_DIR}" + "${ELF_COMMON_PATH}" +) -add_definitions(${IDA_DEFINITIONS}) +target_compile_definitions(wiiuldr PRIVATE + __IDP__ + __EA64__ +) -add_library(wiiuldr SHARED ${SOURCES}) -target_link_libraries(wiiuldr ${IDA_LIBRARIES}) -set_target_properties(wiiuldr PROPERTIES OUTPUT_NAME "wiiu" PREFIX "" SUFFIX "${IDA_PLUGIN_EXT}")
\ No newline at end of file +target_link_libraries(wiiuldr PRIVATE "${IDA_LIBRARY}") + +set_target_properties(wiiuldr PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" + OUTPUT_NAME "wiiu" + PREFIX "" + SUFFIX ".dll" +) diff --git a/src/wiiu/ReadMe.md b/src/wiiu/ReadMe.md index d7bb7f6..0fdd60a 100644 --- a/src/wiiu/ReadMe.md +++ b/src/wiiu/ReadMe.md @@ -7,5 +7,17 @@ An IDA Pro loader for the Wii U Cafe OS. * Symbol table loading * Adds imports and exports +## Building +This loader now builds against the vendored IDA SDK submodule in `third_party/ida-sdk`. + +Open [CMakeLists.txt](/C:/Projects/Decompilation/ida_game_elf_loaders/src/wiiu/CMakeLists.txt) in Visual Studio as a CMake project and build the `x64` `Release` configuration. + +If you prefer the command line with the Visual Studio toolchain: + +```powershell +& "C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -S . -B build -G "Visual Studio 18 2026" -A x64 +& "C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --build build --config Release +``` + ## Todo -* Support RPL relocation
\ No newline at end of file +* Support RPL relocation diff --git a/src/wiiu/cafe_loader.cpp b/src/wiiu/cafe_loader.cpp index 54a7483..9575428 100644 --- a/src/wiiu/cafe_loader.cpp +++ b/src/wiiu/cafe_loader.cpp @@ -2,10 +2,12 @@ #include "cafe.h" #include "tinfl.c" +#include <cstring> + cafe_loader::cafe_loader(elf_reader<elf32> *elf) : m_elf(elf) { - m_externStart = 0xffffffff; + m_externStart = BADADDR; m_externEnd = 0; } @@ -54,7 +56,7 @@ void cafe_loader::applySegments() { continue; uchar perm = SEGPERM_READ; - char *sclass; + const char *sclass; if (section.sh_flags & SHF_WRITE) perm |= SEGPERM_WRITE; @@ -72,8 +74,8 @@ void cafe_loader::applySegments() { const char *data = section.data(); - const char *name = NULL; - if (section.sh_name != NULL) + const char *name = nullptr; + if (section.sh_name != 0) name = &stringTable[section.sh_name]; applySegment(index, @@ -114,10 +116,10 @@ void cafe_loader::applySegment(uint32 sel, set_selector(sel, 0); - if (name == NULL) + if (name == nullptr) name = ""; - add_segm_ex(&seg, name, sclass, NULL); + add_segm_ex(&seg, name, sclass, 0); if (load == true) mem2base(data, addr, addr + size, BADADDR); @@ -199,7 +201,7 @@ void cafe_loader::applyRelocations() { } void cafe_loader::processImports() { - if (m_externStart != 0xffffffff && m_externEnd != 0) { + if (m_externStart != BADADDR && m_externEnd != 0) { segment_t ext; ext.start_ea = m_externStart; ext.end_ea = m_externEnd; @@ -213,7 +215,7 @@ void cafe_loader::processImports() { ext.align = saRelQword; set_selector(255, 0); - add_segm_ex(&ext, ".extern", "XTRN", NULL); + add_segm_ex(&ext, ".extern", "XTRN", 0); } for (auto &import : m_imports) { @@ -239,13 +241,13 @@ void cafe_loader::processImports() { else impnode.supset(import.addr, import.name); - import_module(lib.c_str() + 9, NULL, impnode, NULL, "wiiu"); + import_module(lib.c_str() + 9, nullptr, impnode, nullptr, "wiiu"); } } void cafe_loader::processExports() { segment_t *seg; - uint32 start = 0; + ea_t start = 0; uint32 numExports; if ((seg = get_segm_by_name(".fexports")) != NULL) { @@ -361,4 +363,4 @@ void cafe_loader::applySymbols() { break; } } -}
\ No newline at end of file +} diff --git a/src/wiiu/cafe_loader.h b/src/wiiu/cafe_loader.h index 5417690..dbfdddb 100644 --- a/src/wiiu/cafe_loader.h +++ b/src/wiiu/cafe_loader.h @@ -3,16 +3,18 @@ #include "elf_reader.h" #include "cafe.h" +#include <vector> + class cafe_loader { elf_reader<elf32> *m_elf; uint32 m_relocAddr; - uint32 m_externStart; - uint32 m_externEnd; + ea_t m_externStart; + ea_t m_externEnd; struct import { - uint32 addr; - uint32 orig; + ea_t addr; + ea_t orig; const char *name; }; @@ -42,4 +44,4 @@ private: void swapSymbols(); void applySymbols(); -};
\ No newline at end of file +}; diff --git a/src/wiiu/wiiu.cpp b/src/wiiu/wiiu.cpp index 2588145..41ac110 100644 --- a/src/wiiu/wiiu.cpp +++ b/src/wiiu/wiiu.cpp @@ -4,19 +4,16 @@ #include <idaldr.h> static int idaapi - //accept_file(linput_t *li, char fileformatname[MAX_FILE_FORMAT_NAME], int n) - accept_file(qstring *fileformatname, qstring *processor, linput_t *li, const char *filename) -{ +accept_file(qstring *fileformatname, qstring *processor, linput_t *li, const char * /*filename*/) +{ elf_reader<elf32> elf(li); - if (elf.verifyHeader()) { - if (elf.type() == ELF_FILETYPE_CAFE_RPL) { - - //set_processor_type("ppc", SETPROC_ALL); - //qsnprintf(fileformatname, MAX_FILE_FORMAT_NAME, "WII U RPX/RPL"); - - *processor = "ppc"; + if (elf.verifyHeader()) + { + if (elf.type() == ELF_FILETYPE_CAFE_RPL) + { + *processor = "ppc"; *fileformatname = "WII U RPX/RPL"; - + return ACCEPT_FIRST | 1; } } @@ -25,28 +22,26 @@ static int idaapi } static void idaapi - load_file(linput_t *li, ushort neflags, const char *fileformatname) +load_file(linput_t *li, ushort /*neflags*/, const char * /*fileformatname*/) { set_processor_type("ppc", SETPROC_LOADER); - elf_reader<elf32> elf(li); elf.read(); - - ea_t relocAddr = 0; - if (neflags & NEF_MAN) { - ask_addr(&relocAddr, "Please specify a relocation address base."); - } - + elf_reader<elf32> elf(li); + elf.read(); + cafe_loader ldr(&elf); ldr.apply(); } +#ifdef _WIN32 +__declspec(dllexport) +#endif loader_t LDSC = { IDP_INTERFACE_VERSION, LDRF_REQ_PROC, accept_file, load_file, - NULL, - NULL, - NULL + nullptr, + nullptr, + nullptr }; - |
