summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCrementif <26669564+Crementif@users.noreply.github.com>2026-05-20 19:58:23 +0200
committerCrementif <26669564+Crementif@users.noreply.github.com>2026-05-21 23:18:21 +0200
commit5190527369bd879a7182eaa39171780b38313c15 (patch)
tree59a6297e0c23cdb57658bd6b56f9119101f729b5 /src
parentf293e2d46492ed9221a3864fdd6613f263cf5bef (diff)
Update Wii U IDA loader to IDA 9.3
Diffstat (limited to 'src')
-rw-r--r--src/elf_common/elf_reader.h4
-rw-r--r--src/wiiu/CMakeLists.txt71
-rw-r--r--src/wiiu/ReadMe.md14
-rw-r--r--src/wiiu/cafe_loader.cpp24
-rw-r--r--src/wiiu/cafe_loader.h12
-rw-r--r--src/wiiu/wiiu.cpp41
6 files changed, 107 insertions, 59 deletions
diff --git a/src/elf_common/elf_reader.h b/src/elf_common/elf_reader.h
index f36ba63..1c6a389 100644
--- a/src/elf_common/elf_reader.h
+++ b/src/elf_common/elf_reader.h
@@ -46,6 +46,8 @@
#include "elf.h"
#include <idaldr.h> // TODO: do not depend on this
+#include <algorithm>
+#include <cstring>
#include <vector>
static void printhex(const unsigned char *data, size_t size)
@@ -441,4 +443,4 @@ private:
++index;
}
}
-}; \ No newline at end of file
+};
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
};
-