WIP Generate function stubs

This commit is contained in:
Guus Waals 2024-09-23 23:43:42 +08:00
parent 3d9181f654
commit 2b945e4406
12 changed files with 192 additions and 155 deletions

3
game_re/.gitignore vendored
View File

@ -1,3 +1,4 @@
gh_auto/* gh_auto/*
gh_ref/* gh_ref/*
*.bak *.bak
gh_cmake_timestamp

View File

@ -37,3 +37,14 @@ target_sources(game_re PRIVATE
${GH_AUTO_SOURCES} ${GH_AUTO_SOURCES}
${GH_FIX_SOURCES} ${GH_FIX_SOURCES}
) )
# Ignore -Wformat-security
target_compile_options(game_re PRIVATE -Wno-format-security)
# Automatically re-run CMake if any gh_*.cxx files change
# due to ghidra script runs
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gh_cmake_timestamp
)

View File

@ -10,30 +10,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
// struct undefined {
// size_t _0;
// undefined(int i) {
// *this = i;
// }
// undefined(uint32_t i) {
// *this = i;
// }
// undefined(void* i) {
// reinterpret_cast<void*&>(_0) = i;
// }
// undefined(uint64_t i) {
// *this = i;
// }
// undefined() = default;
// template <typename T> operator T&() {
// static_assert(sizeof(T) <= sizeof(_0), "Invalid assignment");
// return reinterpret_cast<T&>(_0);
// }
// template <typename T> T& operator=(const T &other) {
// static_assert(sizeof(T) <= sizeof(_0), "Invalid assignment");
// return reinterpret_cast<T&>(_0) = other;
// }
// };
typedef uint8_t undefined; typedef uint8_t undefined;
typedef uint32_t undefined4; typedef uint32_t undefined4;
typedef uint16_t undefined2; typedef uint16_t undefined2;

View File

@ -5,21 +5,22 @@
extern undefined r3_initEngine(void); // 00401220 // r3_initEngine extern undefined r3_initEngine(void); // 00401220 // r3_initEngine
extern undefined r3_module0_init(void); // 00401000 // r3_module0_init extern undefined r3_module0_init(void); // 00401000 // r3_module0_init
extern uint32_t __stdcall r3_containsCmdLine( extern uint32_t r3_containsCmdLine(
uint *param_1, char *param_2); // 004028e0 // r3_containsCmdLine uint *param_1, char *param_2); // 004028e0 // r3_containsCmdLine
extern undefined FUN_004010b0(void); // 004010b0 // FUN_004010b0 extern undefined FUN_004010b0(void); // 004010b0 // FUN_004010b0
extern undefined FUN_004464f0(void); // 004464f0 // FUN_004464f0 extern undefined FUN_004464f0(void); // 004464f0 // FUN_004464f0
extern undefined FUN_00503710(void); // 00503710 // FUN_00503710 extern undefined FUN_00503710(void); // 00503710 // FUN_00503710
extern undefined __stdcall r3_setupWindow( extern undefined r3_setupWindow(
HINSTANCE hInstance, undefined4 param_2, HINSTANCE hInstance, undefined4 param_2,
undefined4 param_3); // 00402140 // r3_setupWindow undefined4 param_3); // 00402140 // r3_setupWindow
extern undefined FUN_00401320(void); // 00401320 // FUN_00401320 extern undefined FUN_00401320(void); // 00401320 // FUN_00401320
extern undefined spawnThread(void); // 004477d0 // spawnThread extern undefined spawnThread(void); // 004477d0 // spawnThread
extern undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0 extern undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0
extern undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300 extern undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300
extern void __stdcall g_setInitVar0(void); // 00401310 // g_setInitVar0 extern void g_setInitVar0(void); // 00401310 // g_setInitVar0
extern void __stdcall r3_noop(void *p_cTxt1, extern void r3_noop(void *p_cTxt1,
void *p_cTxt2); // 00401100 // r3_noop void *p_cTxt2); // 00401100 // r3_noop
extern undefined r3_checkDisc(void); // 004464f0 // r3_checkDisc
extern undefined gfx_init2(void); // 00470be0 // gfx_init2 extern undefined gfx_init2(void); // 00470be0 // gfx_init2
extern undefined4 __cdecl r3_get_gli_width( extern undefined4 __cdecl r3_get_gli_width(
void); // 0047baf0 // r3_get_gli_width void); // 0047baf0 // r3_get_gli_width
@ -340,7 +341,7 @@ LAB_004017ce:
(acStack_200[0] != '\0')) { (acStack_200[0] != '\0')) {
/* always true */ /* always true */
hasGLIMode = (uint)(acStack_200[0] != '0'); hasGLIMode = (uint)(acStack_200[0] != '0');
FUN_004464f0(); // r3_checkDisc();
dwOptions = 0; dwOptions = 0;
BVar20 = 0; BVar20 = 0;
lpTargetHandle = &pvStack_834; lpTargetHandle = &pvStack_834;

View File

@ -19,19 +19,19 @@ char(&s_QUIT)[8] = *reinterpret_cast<char(*)[8]>(GH_MEM(0x005b6624));
const char* s_or_press_ESC_to_quit_Rayman_3__005b662c = "or press ESC to quit Rayman 3."; // 005b662c const char* s_or_press_ESC_to_quit_Rayman_3__005b662c = "or press ESC to quit Rayman 3."; // 005b662c
const char* s__s___Restoring_data____005b664c = "%s - Restoring data..."; // 005b664c const char* s__s___Restoring_data____005b664c = "%s - Restoring data..."; // 005b664c
const char* s_Daten_Reparatur____005b6664 = "Daten-Reparatur..."; // 005b6664 const char* s_Daten_Reparatur____005b6664 = "Daten-Reparatur..."; // 005b6664
undefined s_BEENDIGEN_005b6678= (undefined&) GH_MEM(0x005b6678); undefined& s_BEENDIGEN_005b6678= (undefined&) GH_MEM(0x005b6678);
undefined2 DAT_005b6684= (undefined2&) GH_MEM(0x005b6684); undefined2& DAT_005b6684= (undefined2&) GH_MEM(0x005b6684);
const char* s__s___Daten_Reparatur____005b66ac = "%s - Daten-Reparatur..."; // 005b66ac const char* s__s___Daten_Reparatur____005b66ac = "%s - Daten-Reparatur..."; // 005b66ac
const char* s_German_005b66c4 = "German"; // 005b66c4 const char* s_German_005b66c4 = "German"; // 005b66c4
const char* s_Ripristino_dati____005b66cc = "Ripristino dati..."; // 005b66cc const char* s_Ripristino_dati____005b66cc = "Ripristino dati..."; // 005b66cc
const char* s__s___Pausa_005b66e0 = "%s - Pausa"; // 005b66e0 const char* s__s___Pausa_005b66e0 = "%s - Pausa"; // 005b66e0
undefined s_USCIRE_005b66ec= (undefined&) GH_MEM(0x005b66ec); undefined& s_USCIRE_005b66ec= (undefined&) GH_MEM(0x005b66ec);
const char* s_Premi_ESC_per_uscire_da_Rayman_3_005b66f4 = "Premi ESC per uscire da Rayman 3."; // 005b66f4 const char* s_Premi_ESC_per_uscire_da_Rayman_3_005b66f4 = "Premi ESC per uscire da Rayman 3."; // 005b66f4
const char* s__s___Ripristino_dati____005b6718 = "%s - Ripristino dati..."; // 005b6718 const char* s__s___Ripristino_dati____005b6718 = "%s - Ripristino dati..."; // 005b6718
const char* s_Italian_005b6730 = "Italian"; // 005b6730 const char* s_Italian_005b6730 = "Italian"; // 005b6730
const char* s_Restablecer_datos____005b6738 = "Restablecer datos..."; // 005b6738 const char* s_Restablecer_datos____005b6738 = "Restablecer datos..."; // 005b6738
const char* s__s___Rotura_005b6750 = "%s - Rotura"; // 005b6750 const char* s__s___Rotura_005b6750 = "%s - Rotura"; // 005b6750
undefined s_SALIR_005b675c= (undefined&) GH_MEM(0x005b675c); undefined& s_SALIR_005b675c= (undefined&) GH_MEM(0x005b675c);
const char* s_Pulsa_ESC_para_salir_Rayman_3__005b6764 = "Pulsa ESC para salir Rayman 3."; // 005b6764 const char* s_Pulsa_ESC_para_salir_Rayman_3__005b6764 = "Pulsa ESC para salir Rayman 3."; // 005b6764
const char* s__s___Restablecer_datos____005b6784 = "%s - Restablecer datos..."; // 005b6784 const char* s__s___Restablecer_datos____005b6784 = "%s - Restablecer datos..."; // 005b6784
const char* s_Spanish_005b67a0 = "Spanish"; // 005b67a0 const char* s_Spanish_005b67a0 = "Spanish"; // 005b67a0
@ -57,39 +57,51 @@ const char* lpAppName_005b68f0 = "Rayman3"; // 005b68f0
const char* s_Directory_005b68f8 = "Directory"; // 005b68f8 const char* s_Directory_005b68f8 = "Directory"; // 005b68f8
const char* s_None = "None"; // 005b6904 const char* s_None = "None"; // 005b6904
const char* s_UbiSoft_Ubi_ini = "/UbiSoft/Ubi.ini"; // 005b690c const char* s_UbiSoft_Ubi_ini = "/UbiSoft/Ubi.ini"; // 005b690c
const char* s_UbiSoft_bmp_005bda4c = "UbiSoft.bmp"; // 005bda4c
const char* s_R3_DVD_005bdfd8 = "R3_DVD"; // 005bdfd8 const char* s_R3_DVD_005bdfd8 = "R3_DVD"; // 005bdfd8
const char* s_R3_DVD_005be0ec = "R3_DVD"; // 005be0ec const char* s_R3_DVD_005be0ec = "R3_DVD"; // 005be0ec
const char* s__s_DVD_missing_005be0f4 = "%s DVD missing "; // 005be0f4 const char* s__s_DVD_missing_005be0f4 = "%s DVD missing "; // 005be0f4
const char* s_Die__s_DVDROM_kann_nicht_gelesen_005be130 = "Die %s DVDROM kann nicht gelesen werden"; // 005be130 const char* s_Die__s_DVDROM_kann_nicht_gelesen_005be130 = "Die %s DVDROM kann nicht gelesen werden"; // 005be130
const char* s_Impossibile_trovare_il_DVD____s_005be198 = "Impossibile trovare il DVD : %s"; // 005be198 const char* s_Impossibile_trovare_il_DVD____s_005be198 = "Impossibile trovare il DVD : %s"; // 005be198
undefined DAT_005be1ec= (undefined&) GH_MEM(0x005be1ec); undefined& DAT_005be1ec= (undefined&) GH_MEM(0x005be1ec);
const char* s_Impossible_de_trouver_le_DVD_____005be238 = "Impossible de trouver le DVD : %s"; // 005be238 const char* s_Impossible_de_trouver_le_DVD_____005be238 = "Impossible de trouver le DVD : %s"; // 005be238
const char* s_Please_insert_the_DVD_in_the_DVD_005be400 = "Please insert the DVD in the DVD-Rom drive."; // 005be400 const char* s_Please_insert_the_DVD_in_the_DVD_005be400 = "Please insert the DVD in the DVD-Rom drive."; // 005be400
const char* s_Bitte_legen_Sie_DVD_von_Rayman_3_005be438 = "Bitte legen Sie DVD von Rayman 3 in Ihr DVD-ROM Laufwerk ein."; // 005be438 const char* s_Bitte_legen_Sie_DVD_von_Rayman_3_005be438 = "Bitte legen Sie DVD von Rayman 3 in Ihr DVD-ROM Laufwerk ein."; // 005be438
const char* s_Inserisci_il_DVD_di_Rayman_3_nel_005be484 = "Inserisci il DVD di Rayman 3 nel lettore DVD-ROM."; // 005be484 const char* s_Inserisci_il_DVD_di_Rayman_3_nel_005be484 = "Inserisci il DVD di Rayman 3 nel lettore DVD-ROM."; // 005be484
const char* s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0 = "Introduce el DVD de Rayman 3 en la unidad de DVD-ROM."; // 005be4c0 const char* s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0 = "Introduce el DVD de Rayman 3 en la unidad de DVD-ROM."; // 005be4c0
undefined DAT_005be500= (undefined&) GH_MEM(0x005be500); undefined& DAT_005be500= (undefined&) GH_MEM(0x005be500);
const char* s__c__s_005be540 = "%c:%s"; // 005be540 const char* s_fmt_c_colon_s = "%c:%s"; // 005be540
const char* s__program_files_Ubi_Soft_Rayman3_005be548 = "\\program files\\Ubi Soft\\Rayman3"; // 005be548 const char* s_r3_program_files = "\\program files\\Ubi Soft\\Rayman3"; // 005be548
undefined* PTR_DAT_005be568 = (undefined*)&GH_MEM(0x005be568); // 005be568 undefined *& PTR_DAT_005be568= (undefined *&) GH_MEM(0x005be568);
long lpDefault_005cf96c= (long&) GH_MEM(0x005cf96c); long& lpDefault_005cf96c= (long&) GH_MEM(0x005cf96c);
undefined1 DAT_005d26a8= (undefined1&) GH_MEM(0x005d26a8); undefined4& DAT_005d2660= (undefined4&) GH_MEM(0x005d2660);
undefined lpVolumeNameBuffer_005d27b0= (undefined&) GH_MEM(0x005d27b0); undefined1& DAT_005d26a8= (undefined1&) GH_MEM(0x005d26a8);
r3_main_data r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6); undefined& lpVolumeNameBuffer_005d27b0= (undefined&) GH_MEM(0x005d27b0);
uint hasGLIMode= (uint&) GH_MEM(0x0077d0a8); r3_main_data& r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6);
undefined4 g_engineRunning= (undefined4&) GH_MEM(0x0077d0b4); uint& hasGLIMode= (uint&) GH_MEM(0x0077d0a8);
HANDLE g_drawSemaphore= (HANDLE&) GH_MEM(0x0077d0bc); undefined4& g_engineRunning= (undefined4&) GH_MEM(0x0077d0b4);
HANDLE& g_drawSemaphore= (HANDLE&) GH_MEM(0x0077d0bc);
char(&g_mutexName_Rayman3)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d0c0)); char(&g_mutexName_Rayman3)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d0c0));
char(&g_windowTitle)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d1c0)); char(&g_windowTitle)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d1c0));
char(&lpString_0077d2c0)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d2c0)); char(&lpString_0077d2c0)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d2c0));
char(&s_windowTitleRestoring)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d3c0)); char(&s_windowTitleRestoring)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d3c0));
HINSTANCE g_hinstance= (HINSTANCE&) GH_MEM(0x0077d4c0); HINSTANCE& g_hinstance= (HINSTANCE&) GH_MEM(0x0077d4c0);
HWND g_gameHWND= (HWND&) GH_MEM(0x0077d4c4); HWND& g_gameHWND= (HWND&) GH_MEM(0x0077d4c4);
HANDLE g_mainThreadHandle= (HANDLE&) GH_MEM(0x0077d4c8); HANDLE& g_mainThreadHandle= (HANDLE&) GH_MEM(0x0077d4c8);
char(&g_appCmdLine)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d4e0)); char(&g_appCmdLine)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d4e0));
char(&s_wndStrRestoring)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d5e0)); char(&s_wndStrRestoring)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d5e0));
undefined2 DAT_007825c0= (undefined2&) GH_MEM(0x007825c0); undefined2& DAT_007825c0= (undefined2&) GH_MEM(0x007825c0);
char(&s_wndStrQuiting)[56] = *reinterpret_cast<char(*)[56]>(GH_MEM(0x00782600)); char(&s_wndStrQuiting)[56] = *reinterpret_cast<char(*)[56]>(GH_MEM(0x00782600));
uint DAT_007d9cc4= (uint&) GH_MEM(0x007d9cc4); undefined& DAT_007d7d84= (undefined&) GH_MEM(0x007d7d84);
undefined lpRootPathName_007d9e70= (undefined&) GH_MEM(0x007d9e70); undefined2& DAT_007d7ea8= (undefined2&) GH_MEM(0x007d7ea8);
undefined3 UNK_007d9e71= (undefined3&) GH_MEM(0x007d9e71); short& DAT_007d80f8= (short&) GH_MEM(0x007d80f8);
undefined4& DAT_007d83a8= (undefined4&) GH_MEM(0x007d83a8);
r3_TaggedFloatUnk& r3_TaggedFloatUnk_007d83e0= (r3_TaggedFloatUnk&) GH_MEM(0x007d83e0);
r3_TaggedFloatUnk& r3_TaggedFloatUnk_007d8434= (r3_TaggedFloatUnk&) GH_MEM(0x007d8434);
undefined& DAT_007d98fd= (undefined&) GH_MEM(0x007d98fd);
undefined& DAT_007d9928= (undefined&) GH_MEM(0x007d9928);
uint& DAT_007d9cc4= (uint&) GH_MEM(0x007d9cc4);
undefined& lpSystemTime_007d9e40= (undefined&) GH_MEM(0x007d9e40);
undefined4& DAT_007d9e60= (undefined4&) GH_MEM(0x007d9e60);
undefined& lpRootPathName_007d9e70= (undefined&) GH_MEM(0x007d9e70);
undefined3& UNK_007d9e71= (undefined3&) GH_MEM(0x007d9e71);

View File

@ -62,6 +62,7 @@ extern const char* lpAppName_005b68f0; // 005b68f0
extern const char* s_Directory_005b68f8; // 005b68f8 extern const char* s_Directory_005b68f8; // 005b68f8
extern const char* s_None; // 005b6904 extern const char* s_None; // 005b6904
extern const char* s_UbiSoft_Ubi_ini; // 005b690c extern const char* s_UbiSoft_Ubi_ini; // 005b690c
extern const char* s_UbiSoft_bmp_005bda4c; // 005bda4c
extern const char* s_R3_DVD_005bdfd8; // 005bdfd8 extern const char* s_R3_DVD_005bdfd8; // 005bdfd8
extern const char* s_R3_DVD_005be0ec; // 005be0ec extern const char* s_R3_DVD_005be0ec; // 005be0ec
extern const char* s__s_DVD_missing_005be0f4; // 005be0f4 extern const char* s__s_DVD_missing_005be0f4; // 005be0f4
@ -74,10 +75,11 @@ extern const char* s_Bitte_legen_Sie_DVD_von_Rayman_3_005be438; // 005be438
extern const char* s_Inserisci_il_DVD_di_Rayman_3_nel_005be484; // 005be484 extern const char* s_Inserisci_il_DVD_di_Rayman_3_nel_005be484; // 005be484
extern const char* s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0; // 005be4c0 extern const char* s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0; // 005be4c0
extern undefined& DAT_005be500; // 005be500 extern undefined& DAT_005be500; // 005be500
extern const char* s__c__s_005be540; // 005be540 extern const char* s_fmt_c_colon_s; // 005be540
extern const char* s__program_files_Ubi_Soft_Rayman3_005be548; // 005be548 extern const char* s_r3_program_files; // 005be548
extern undefined* PTR_DAT_005be568; // 005be568 extern undefined *& PTR_DAT_005be568; // 005be568
extern long& lpDefault_005cf96c; // 005cf96c extern long& lpDefault_005cf96c; // 005cf96c
extern undefined4& DAT_005d2660; // 005d2660
extern undefined1& DAT_005d26a8; // 005d26a8 extern undefined1& DAT_005d26a8; // 005d26a8
extern undefined& lpVolumeNameBuffer_005d27b0; // 005d27b0 extern undefined& lpVolumeNameBuffer_005d27b0; // 005d27b0
extern r3_main_data& r3_main_data_005d28b6; // 005d28b6 extern r3_main_data& r3_main_data_005d28b6; // 005d28b6
@ -95,7 +97,17 @@ extern char(&g_appCmdLine)[256]; // 0077d4e0
extern char(&s_wndStrRestoring)[256]; // 0077d5e0 extern char(&s_wndStrRestoring)[256]; // 0077d5e0
extern undefined2& DAT_007825c0; // 007825c0 extern undefined2& DAT_007825c0; // 007825c0
extern char(&s_wndStrQuiting)[56]; // 00782600 extern char(&s_wndStrQuiting)[56]; // 00782600
extern undefined& DAT_007d7d84; // 007d7d84
extern undefined2& DAT_007d7ea8; // 007d7ea8
extern short& DAT_007d80f8; // 007d80f8
extern undefined4& DAT_007d83a8; // 007d83a8
extern r3_TaggedFloatUnk& r3_TaggedFloatUnk_007d83e0; // 007d83e0
extern r3_TaggedFloatUnk& r3_TaggedFloatUnk_007d8434; // 007d8434
extern undefined& DAT_007d98fd; // 007d98fd
extern undefined& DAT_007d9928; // 007d9928
extern uint& DAT_007d9cc4; // 007d9cc4 extern uint& DAT_007d9cc4; // 007d9cc4
extern undefined& lpSystemTime_007d9e40; // 007d9e40
extern undefined4& DAT_007d9e60; // 007d9e60
extern undefined& lpRootPathName_007d9e70; // 007d9e70 extern undefined& lpRootPathName_007d9e70; // 007d9e70
extern undefined3& UNK_007d9e71; // 007d9e71 extern undefined3& UNK_007d9e71; // 007d9e71
#endif // GH_GENERATED_GLOBALS_H #endif // GH_GENERATED_GLOBALS_H

View File

@ -55,22 +55,24 @@
005b68f8 || s_Directory_005b68f8 || / || string 005b68f8 || s_Directory_005b68f8 || / || string
005b6904 || s_None || / || TerminatedCString 005b6904 || s_None || / || TerminatedCString
005b690c || s_UbiSoft_Ubi_ini || / || TerminatedCString 005b690c || s_UbiSoft_Ubi_ini || / || TerminatedCString
005bda4c || s_UbiSoft_bmp_005bda4c || / || string
005bdfd8 || s_R3_DVD_005bdfd8 || / || string 005bdfd8 || s_R3_DVD_005bdfd8 || / || string
005be0ec || s_R3_DVD_005be0ec || / || string 005be0ec || s_R3_DVD_005be0ec || / || string
005be0f4 || s_%s_DVD_missing_005be0f4 || / || string 005be0f4 || s__s_DVD_missing_005be0f4 || / || string
005be130 || s_Die_%s_DVDROM_kann_nicht_gelesen_005be130 || / || string 005be130 || s_Die__s_DVDROM_kann_nicht_gelesen_005be130 || / || string
005be198 || s_Impossibile_trovare_il_DVD_:_%s_005be198 || / || string 005be198 || s_Impossibile_trovare_il_DVD____s_005be198 || / || string
005be1ec || DAT_005be1ec || / || undefined 005be1ec || DAT_005be1ec || / || undefined
005be238 || s_Impossible_de_trouver_le_DVD_:_%_005be238 || / || string 005be238 || s_Impossible_de_trouver_le_DVD_____005be238 || / || string
005be400 || s_Please_insert_the_DVD_in_the_DVD_005be400 || / || string 005be400 || s_Please_insert_the_DVD_in_the_DVD_005be400 || / || string
005be438 || s_Bitte_legen_Sie_DVD_von_Rayman_3_005be438 || / || string 005be438 || s_Bitte_legen_Sie_DVD_von_Rayman_3_005be438 || / || string
005be484 || s_Inserisci_il_DVD_di_Rayman_3_nel_005be484 || / || string 005be484 || s_Inserisci_il_DVD_di_Rayman_3_nel_005be484 || / || string
005be4c0 || s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0 || / || string 005be4c0 || s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0 || / || string
005be500 || DAT_005be500 || / || undefined 005be500 || DAT_005be500 || / || undefined
005be540 || s_%c:%s_005be540 || / || string 005be540 || s_fmt_c_colon_s || / || string
005be548 || s_\program_files\Ubi_Soft\Rayman3_005be548 || / || string 005be548 || s_r3_program_files || / || string
005be568 || PTR_DAT_005be568 || / || undefined * 005be568 || PTR_DAT_005be568 || / || undefined *
005cf96c || lpDefault_005cf96c || / || long 005cf96c || lpDefault_005cf96c || / || long
005d2660 || DAT_005d2660 || / || undefined4
005d26a8 || DAT_005d26a8 || / || undefined1 005d26a8 || DAT_005d26a8 || / || undefined1
005d27b0 || lpVolumeNameBuffer_005d27b0 || / || undefined 005d27b0 || lpVolumeNameBuffer_005d27b0 || / || undefined
005d28b6 || r3_main_data_005d28b6 || / || r3_main_data 005d28b6 || r3_main_data_005d28b6 || / || r3_main_data
@ -88,6 +90,16 @@
0077d5e0 || s_wndStrRestoring || / || char[256] 0077d5e0 || s_wndStrRestoring || / || char[256]
007825c0 || DAT_007825c0 || / || undefined2 007825c0 || DAT_007825c0 || / || undefined2
00782600 || s_wndStrQuiting || / || char[56] 00782600 || s_wndStrQuiting || / || char[56]
007d7d84 || DAT_007d7d84 || / || undefined
007d7ea8 || DAT_007d7ea8 || / || undefined2
007d80f8 || DAT_007d80f8 || / || short
007d83a8 || DAT_007d83a8 || / || undefined4
007d83e0 || r3_TaggedFloatUnk_007d83e0 || /auto_structs || r3_TaggedFloatUnk
007d8434 || r3_TaggedFloatUnk_007d8434 || /auto_structs || r3_TaggedFloatUnk
007d98fd || DAT_007d98fd || / || undefined
007d9928 || DAT_007d9928 || / || undefined
007d9cc4 || DAT_007d9cc4 || / || uint 007d9cc4 || DAT_007d9cc4 || / || uint
007d9e40 || lpSystemTime_007d9e40 || / || undefined
007d9e60 || DAT_007d9e60 || / || undefined4
007d9e70 || lpRootPathName_007d9e70 || / || undefined 007d9e70 || lpRootPathName_007d9e70 || / || undefined
007d9e71 || UNK_007d9e71 || / || undefined3 007d9e71 || UNK_007d9e71 || / || undefined3

View File

@ -25,6 +25,9 @@ public class DumpCurrentFunction extends GhidraScript {
println("No function found at the current address."); println("No function found at the current address.");
} }
if (functionDumper.createdFile)
RecompileConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals(); globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest(); globalDumper.saveGlobalManifest();
} }

View File

@ -1,103 +1,23 @@
// Script to sanitize global symbols in Ghidra // Script to sanitize global symbols in Ghidra
// @category _Reman3 // @category _Reman3
// @menupath Reman3.Sanitize Global Symbols
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import ghidra.app.cmd.label.AddLabelCmd;
import ghidra.app.decompiler.DecompileResults;
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address; import re3lib.GlobalDumper;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.VariableStorage;
import ghidra.program.model.pcode.HighSymbol;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import re3lib.RecompileConfig; import re3lib.RecompileConfig;
import re3lib.Utils;
public class SanitizeGlobalSymbols extends GhidraScript { public class SanitizeGlobalSymbols extends GhidraScript {
private static final boolean AUTO_RENAME_SYMBOLS = true;
HashSet<Address> functionAddrBlackList = new HashSet<>();
boolean shouldDecompileFunction(Function function) {
return !functionAddrBlackList.contains(function.getEntryPoint());
}
void sanitizeGlobalSymbolsPass(List<Function> functions) {
Hashtable<String, HighSymbol> globalSymbols = new Hashtable<>();
for (Function function : functions) {
println("Processing global symbols for " + function.getName());
DecompileResults decompRes = RecompileConfig.INSTANCE.decompCache.getOrInsert(function);
Iterator<HighSymbol> smyIt = decompRes.getHighFunction().getGlobalSymbolMap().getSymbols();
HighSymbol gsym = smyIt.next();
if (globalSymbols.containsKey(gsym.getName()))
continue;
println("GLOBAL: " + gsym.getName());
String sanitizedName = sanitizeFunctionName(gsym.getName());
if (!sanitizedName.equals(gsym.getName())) {
if (AUTO_RENAME_SYMBOLS) {
Symbol symbol = gsym.getSymbol();
VariableStorage storage = gsym.getStorage();
Address addr = storage.getMinAddress();
println("Renaming global symbol: " + gsym.getName() + " (" + addr
+ ") -> " + sanitizedName);
if (symbol != null) {
AddLabelCmd cmd = new AddLabelCmd(addr, sanitizedName, symbol.getParentNamespace(),
SourceType.USER_DEFINED);
if (cmd.applyTo(currentProgram)) {
println("Renamed global symbol: " + gsym.getName() + " -> " + sanitizedName);
} else {
println("Error renaming symbol: " + cmd.getStatusMsg());
}
} else {
println("Symbol is null: " + gsym.getName() + " - " + function.getName());
}
} else {
println("Invalid global symbol name: " + gsym.getName() + " - " + function.getName());
}
}
}
}
private static String sanitizeFunctionName(String name) {
return name.replaceAll("[^a-zA-Z0-9_]", "_");
}
@Override @Override
public void run() throws Exception { public void run() throws Exception {
if (currentProgram == null) {
return;
}
RecompileConfig.INSTANCE = new RecompileConfig(this); RecompileConfig.INSTANCE = new RecompileConfig(this);
RecompileConfig.INSTANCE.createDirectories();
if (!new File(RecompileConfig.INSTANCE.outputDir).exists()) { GlobalDumper globalDumper = new GlobalDumper(this);
throw new Exception("Output directory does not exist: " + RecompileConfig.INSTANCE.outputDir); globalDumper.loadGlobalManifest();
}
functionAddrBlackList = Utils.loadFunctionBlacklist(RecompileConfig.INSTANCE.functionBlacklistPath); globalDumper.sanitizeGlobalSymbols();
List<Function> functions = new ArrayList<>(); globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
Iterator<Function> functionsIt = currentProgram.getFunctionManager().getFunctions(true).iterator();
while (functionsIt.hasNext()) {
Function function = functionsIt.next();
if (!shouldDecompileFunction(function)) {
continue;
}
functions.add(function);
}
sanitizeGlobalSymbolsPass(functions);
} }
} }

View File

@ -30,6 +30,8 @@ public class FunctionDumper {
GlobalDumper globalDumper; GlobalDumper globalDumper;
HashSet<Address> functionAddrBlackList = new HashSet<>(); HashSet<Address> functionAddrBlackList = new HashSet<>();
public boolean createdFile = false;
static final Pattern fieldAccessRegex = Pattern.compile("^_([0-9]+)_([0-9]+)_$"); static final Pattern fieldAccessRegex = Pattern.compile("^_([0-9]+)_([0-9]+)_$");
public FunctionDumper(GhidraScript script, GlobalDumper globalDumper) { public FunctionDumper(GhidraScript script, GlobalDumper globalDumper) {
@ -112,11 +114,15 @@ public class FunctionDumper {
f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName); f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName);
if (f0.exists()) { if (f0.exists()) {
f0.delete(); f0.delete();
} else {
createdFile = true;
} }
} }
script.println("Processing " + function.getName() + " => " + f0.toString()); script.println("Processing " + function.getName() + " => " + f0.toString());
List<Function> externalFunctionCalls = new ArrayList<>();
DecompileResults decompRes = RecompileConfig.INSTANCE.decompCache.getOrInsert(function); DecompileResults decompRes = RecompileConfig.INSTANCE.decompCache.getOrInsert(function);
try (PrintWriter writer2 = new PrintWriter(f0, "UTF-8")) { try (PrintWriter writer2 = new PrintWriter(f0, "UTF-8")) {
writer2.println("// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!! "); writer2.println("// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!! ");
@ -213,6 +219,7 @@ public class FunctionDumper {
headers.add("extern " + proto headers.add("extern " + proto
+ "; // " + calledFunction.getEntryPoint() + " // " + "; // " + calledFunction.getEntryPoint() + " // "
+ calledFunction.getName()); + calledFunction.getName());
externalFunctionCalls.add(calledFunction);
} }
} }
} }
@ -236,5 +243,39 @@ public class FunctionDumper {
writer2.print(codeWriter.toString()); writer2.print(codeWriter.toString());
writer2.println(); writer2.println();
} }
// Possibly generate stubs for external functions
for (Function externalFunction : externalFunctionCalls) {
File f2 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName);
File f3 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName);
if (f2.exists() || f3.exists()) {
continue;
}
File f4 = new File(RecompileConfig.INSTANCE.dirDecompStub, fileName);
script.println("Generating function stub for " + externalFunction.getName() + " => " + f4.toString());
try (PrintWriter writer2 = new PrintWriter(f4, "UTF-8")) {
writer2.println("// AUTO-GENERATED FILE!!!!");
writer2.println("// This function has yet to be decompiled using 'Dump Current Function' in ghidra");
writer2.println("// with possible manualy fixes");
writer2.println();
writer2.println("#include <gh_auto_binder.h>");
writer2.println("#include \"../gh_global.h\"");
writer2.println("#include <stdexcept>");
writer2.println();
writer2.println("// " + externalFunction.getEntryPoint());
writer2.println("// " + externalFunction.getName());
writer2.println(externalFunction.getSignature().getPrototypeString(false) + " {");
writer2.println(" // TODO: Implement this function");
writer2
.println(" throw std::runtime_error(\"Function not implemented: " + externalFunction.getName() + "\");");
writer2.println("}");
}
if (!f4.exists()) {
createdFile = true;
}
}
} }
} }

View File

@ -15,6 +15,7 @@ import java.util.Map;
import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.DatatypeFactory;
import ghidra.app.cmd.label.AddLabelCmd;
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.app.services.DataTypeManagerService; import ghidra.app.services.DataTypeManagerService;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
@ -27,6 +28,8 @@ import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.Undefined; import ghidra.program.model.data.Undefined;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.program.model.pcode.HighSymbol; import ghidra.program.model.pcode.HighSymbol;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import ghidra.util.data.DataTypeParser; import ghidra.util.data.DataTypeParser;
import ghidra.util.data.DataTypeParser.AllowedDataTypes; import ghidra.util.data.DataTypeParser.AllowedDataTypes;
@ -181,8 +184,9 @@ public class GlobalDumper {
initBlk += "(" + dataType + ")&GH_MEM(0x" + addr + ")"; initBlk += "(" + dataType + ")&GH_MEM(0x" + addr + ")";
fullyDefinedType = true; fullyDefinedType = true;
} }
String linkagePrefix = "extern ";
if (fullyDefinedType) { if (fullyDefinedType) {
hwriter.println("extern " + dataType + " " + name + "; // " + addr); hwriter.println(linkagePrefix + dataType + " " + name + "; // " + addr);
cwriter.println(dataType + " " + name + initBlk + "; // " + addr); cwriter.println(dataType + " " + name + initBlk + "; // " + addr);
} else { } else {
if (dt instanceof Array) { if (dt instanceof Array) {
@ -191,14 +195,14 @@ public class GlobalDumper {
Array adt = (Array) dt; Array adt = (Array) dt;
DataType baseType = adt.getDataType(); DataType baseType = adt.getDataType();
hwriter.println( hwriter.println(
"extern " + baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "]; // " + addr); linkagePrefix + baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "]; // " + addr);
cwriter.println( cwriter.println(
baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "] = *reinterpret_cast<" baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "] = *reinterpret_cast<"
+ baseType.getDisplayName() + "(*)[" + adt.getNumElements() + "]>(GH_MEM(0x" + addr + "));"); + baseType.getDisplayName() + "(*)[" + adt.getNumElements() + "]>(GH_MEM(0x" + addr + "));");
} else { } else {
String refTypeStr = dt.getDisplayName() + "&"; String refTypeStr = dt.getDisplayName() + "&";
hwriter.println("extern " + refTypeStr + " " + name + "; // " + addr); hwriter.println(linkagePrefix + refTypeStr + " " + name + "; // " + addr);
cwriter.println(dataType + " " + name + "= (" + refTypeStr + ") GH_MEM(0x" + addr + ");"); cwriter.println(refTypeStr + " " + name + "= (" + refTypeStr + ") GH_MEM(0x" + addr + ");");
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -233,4 +237,23 @@ public class GlobalDumper {
} }
} }
} }
public void sanitizeGlobalSymbols() {
for (GlobalRec global : globalAddrs.values()) {
String sanitizedName = Utils.sanitizeIdentifier(global.name);
if (!sanitizedName.equals(global.name)) {
Symbol symbol = script.getSymbolAt(global.address);
if (symbol != null) {
script.println("Renaming global symbol: " + global.name + " -> " + sanitizedName);
AddLabelCmd cmd = new AddLabelCmd(global.address, sanitizedName,
symbol.getParentNamespace(),
SourceType.USER_DEFINED);
if (!cmd.applyTo(script.getCurrentProgram())) {
script.println("Error renaming symbol: " + cmd.getStatusMsg());
}
global.name = sanitizedName;
}
}
}
}
} }

View File

@ -1,6 +1,7 @@
package re3lib; package re3lib;
import java.io.File; import java.io.File;
import java.io.IOException;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.app.decompiler.DecompInterface; import ghidra.app.decompiler.DecompInterface;
@ -27,10 +28,20 @@ public class RecompileConfig {
// The manually decompiled files (will not be overwritten by the auto // The manually decompiled files (will not be overwritten by the auto
// decompiler) // decompiler)
public final File dirDecompFix; public final File dirDecompFix;
// The automatically generated files get written here in case a gh_fix entry exists // The automatically generated files get written here in case a gh_fix entry
// exists
// usable for referencing the modified function against the auto-decompiled one // usable for referencing the modified function against the auto-decompiled one
public final File dirDecompRef; public final File dirDecompRef;
// The path for generated function stubs, for yet-to-be-compiled functions
// Usefully for testing a part of the recompiled code without linker errors
public final File dirDecompStub;
// The CMake timestamp file, automatically touched sometimes to trigger a
// reconfigure
// mostly when adding new files to the project
public final File cmakeTimestampFile;
public final Program currentProgram; public final Program currentProgram;
public final DecompileCache decompCache; public final DecompileCache decompCache;
@ -54,6 +65,9 @@ public class RecompileConfig {
dirDecompAuto = new File(outputDir, "gh_auto"); dirDecompAuto = new File(outputDir, "gh_auto");
dirDecompFix = new File(outputDir, "gh_fix"); dirDecompFix = new File(outputDir, "gh_fix");
dirDecompRef = new File(outputDir, "gh_ref"); dirDecompRef = new File(outputDir, "gh_ref");
dirDecompStub = new File(outputDir, "gh_stub");
cmakeTimestampFile = new File(outputDir, "gh_cmake_timestamp");
currentProgram = script.getCurrentProgram(); currentProgram = script.getCurrentProgram();
@ -66,5 +80,16 @@ public class RecompileConfig {
dirDecompAuto.mkdirs(); dirDecompAuto.mkdirs();
dirDecompFix.mkdirs(); dirDecompFix.mkdirs();
dirDecompRef.mkdirs(); dirDecompRef.mkdirs();
dirDecompStub.mkdirs();
}
public void touchCMakeTimestamp() {
try {
if (!cmakeTimestampFile.exists()) {
cmakeTimestampFile.createNewFile();
}
cmakeTimestampFile.setLastModified(System.currentTimeMillis());
} catch (IOException e) {
}
} }
} }