WIP Generate function stubs
This commit is contained in:
parent
3d9181f654
commit
2b945e4406
|
@ -1,3 +1,4 @@
|
|||
gh_auto/*
|
||||
gh_ref/*
|
||||
*.bak
|
||||
*.bak
|
||||
gh_cmake_timestamp
|
|
@ -37,3 +37,14 @@ target_sources(game_re PRIVATE
|
|||
${GH_AUTO_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
|
||||
)
|
||||
|
|
|
@ -10,30 +10,6 @@
|
|||
#include <stdio.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 uint32_t undefined4;
|
||||
typedef uint16_t undefined2;
|
||||
|
|
|
@ -5,21 +5,22 @@
|
|||
|
||||
extern undefined r3_initEngine(void); // 00401220 // r3_initEngine
|
||||
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
|
||||
extern undefined FUN_004010b0(void); // 004010b0 // FUN_004010b0
|
||||
extern undefined FUN_004464f0(void); // 004464f0 // FUN_004464f0
|
||||
extern undefined FUN_00503710(void); // 00503710 // FUN_00503710
|
||||
extern undefined __stdcall r3_setupWindow(
|
||||
extern undefined r3_setupWindow(
|
||||
HINSTANCE hInstance, undefined4 param_2,
|
||||
undefined4 param_3); // 00402140 // r3_setupWindow
|
||||
extern undefined FUN_00401320(void); // 00401320 // FUN_00401320
|
||||
extern undefined spawnThread(void); // 004477d0 // spawnThread
|
||||
extern undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0
|
||||
extern undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300
|
||||
extern void __stdcall g_setInitVar0(void); // 00401310 // g_setInitVar0
|
||||
extern void __stdcall r3_noop(void *p_cTxt1,
|
||||
extern void g_setInitVar0(void); // 00401310 // g_setInitVar0
|
||||
extern void r3_noop(void *p_cTxt1,
|
||||
void *p_cTxt2); // 00401100 // r3_noop
|
||||
extern undefined r3_checkDisc(void); // 004464f0 // r3_checkDisc
|
||||
extern undefined gfx_init2(void); // 00470be0 // gfx_init2
|
||||
extern undefined4 __cdecl r3_get_gli_width(
|
||||
void); // 0047baf0 // r3_get_gli_width
|
||||
|
@ -340,7 +341,7 @@ LAB_004017ce:
|
|||
(acStack_200[0] != '\0')) {
|
||||
/* always true */
|
||||
hasGLIMode = (uint)(acStack_200[0] != '0');
|
||||
FUN_004464f0();
|
||||
// r3_checkDisc();
|
||||
dwOptions = 0;
|
||||
BVar20 = 0;
|
||||
lpTargetHandle = &pvStack_834;
|
||||
|
|
|
@ -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__s___Restoring_data____005b664c = "%s - Restoring data..."; // 005b664c
|
||||
const char* s_Daten_Reparatur____005b6664 = "Daten-Reparatur..."; // 005b6664
|
||||
undefined s_BEENDIGEN_005b6678= (undefined&) GH_MEM(0x005b6678);
|
||||
undefined2 DAT_005b6684= (undefined2&) GH_MEM(0x005b6684);
|
||||
undefined& s_BEENDIGEN_005b6678= (undefined&) GH_MEM(0x005b6678);
|
||||
undefined2& DAT_005b6684= (undefined2&) GH_MEM(0x005b6684);
|
||||
const char* s__s___Daten_Reparatur____005b66ac = "%s - Daten-Reparatur..."; // 005b66ac
|
||||
const char* s_German_005b66c4 = "German"; // 005b66c4
|
||||
const char* s_Ripristino_dati____005b66cc = "Ripristino dati..."; // 005b66cc
|
||||
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__s___Ripristino_dati____005b6718 = "%s - Ripristino dati..."; // 005b6718
|
||||
const char* s_Italian_005b6730 = "Italian"; // 005b6730
|
||||
const char* s_Restablecer_datos____005b6738 = "Restablecer datos..."; // 005b6738
|
||||
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__s___Restablecer_datos____005b6784 = "%s - Restablecer datos..."; // 005b6784
|
||||
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_None = "None"; // 005b6904
|
||||
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_005be0ec = "R3_DVD"; // 005be0ec
|
||||
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_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_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_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
|
||||
undefined DAT_005be500= (undefined&) GH_MEM(0x005be500);
|
||||
const char* s__c__s_005be540 = "%c:%s"; // 005be540
|
||||
const char* s__program_files_Ubi_Soft_Rayman3_005be548 = "\\program files\\Ubi Soft\\Rayman3"; // 005be548
|
||||
undefined* PTR_DAT_005be568 = (undefined*)&GH_MEM(0x005be568); // 005be568
|
||||
long lpDefault_005cf96c= (long&) GH_MEM(0x005cf96c);
|
||||
undefined1 DAT_005d26a8= (undefined1&) GH_MEM(0x005d26a8);
|
||||
undefined lpVolumeNameBuffer_005d27b0= (undefined&) GH_MEM(0x005d27b0);
|
||||
r3_main_data r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6);
|
||||
uint hasGLIMode= (uint&) GH_MEM(0x0077d0a8);
|
||||
undefined4 g_engineRunning= (undefined4&) GH_MEM(0x0077d0b4);
|
||||
HANDLE g_drawSemaphore= (HANDLE&) GH_MEM(0x0077d0bc);
|
||||
undefined& DAT_005be500= (undefined&) GH_MEM(0x005be500);
|
||||
const char* s_fmt_c_colon_s = "%c:%s"; // 005be540
|
||||
const char* s_r3_program_files = "\\program files\\Ubi Soft\\Rayman3"; // 005be548
|
||||
undefined *& PTR_DAT_005be568= (undefined *&) GH_MEM(0x005be568);
|
||||
long& lpDefault_005cf96c= (long&) GH_MEM(0x005cf96c);
|
||||
undefined4& DAT_005d2660= (undefined4&) GH_MEM(0x005d2660);
|
||||
undefined1& DAT_005d26a8= (undefined1&) GH_MEM(0x005d26a8);
|
||||
undefined& lpVolumeNameBuffer_005d27b0= (undefined&) GH_MEM(0x005d27b0);
|
||||
r3_main_data& r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6);
|
||||
uint& hasGLIMode= (uint&) GH_MEM(0x0077d0a8);
|
||||
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_windowTitle)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d1c0));
|
||||
char(&lpString_0077d2c0)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d2c0));
|
||||
char(&s_windowTitleRestoring)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d3c0));
|
||||
HINSTANCE g_hinstance= (HINSTANCE&) GH_MEM(0x0077d4c0);
|
||||
HWND g_gameHWND= (HWND&) GH_MEM(0x0077d4c4);
|
||||
HANDLE g_mainThreadHandle= (HANDLE&) GH_MEM(0x0077d4c8);
|
||||
HINSTANCE& g_hinstance= (HINSTANCE&) GH_MEM(0x0077d4c0);
|
||||
HWND& g_gameHWND= (HWND&) GH_MEM(0x0077d4c4);
|
||||
HANDLE& g_mainThreadHandle= (HANDLE&) GH_MEM(0x0077d4c8);
|
||||
char(&g_appCmdLine)[256] = *reinterpret_cast<char(*)[256]>(GH_MEM(0x0077d4e0));
|
||||
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));
|
||||
uint DAT_007d9cc4= (uint&) GH_MEM(0x007d9cc4);
|
||||
undefined lpRootPathName_007d9e70= (undefined&) GH_MEM(0x007d9e70);
|
||||
undefined3 UNK_007d9e71= (undefined3&) GH_MEM(0x007d9e71);
|
||||
undefined& DAT_007d7d84= (undefined&) GH_MEM(0x007d7d84);
|
||||
undefined2& DAT_007d7ea8= (undefined2&) GH_MEM(0x007d7ea8);
|
||||
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);
|
||||
|
|
|
@ -62,6 +62,7 @@ extern const char* lpAppName_005b68f0; // 005b68f0
|
|||
extern const char* s_Directory_005b68f8; // 005b68f8
|
||||
extern const char* s_None; // 005b6904
|
||||
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_005be0ec; // 005be0ec
|
||||
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_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0; // 005be4c0
|
||||
extern undefined& DAT_005be500; // 005be500
|
||||
extern const char* s__c__s_005be540; // 005be540
|
||||
extern const char* s__program_files_Ubi_Soft_Rayman3_005be548; // 005be548
|
||||
extern undefined* PTR_DAT_005be568; // 005be568
|
||||
extern const char* s_fmt_c_colon_s; // 005be540
|
||||
extern const char* s_r3_program_files; // 005be548
|
||||
extern undefined *& PTR_DAT_005be568; // 005be568
|
||||
extern long& lpDefault_005cf96c; // 005cf96c
|
||||
extern undefined4& DAT_005d2660; // 005d2660
|
||||
extern undefined1& DAT_005d26a8; // 005d26a8
|
||||
extern undefined& lpVolumeNameBuffer_005d27b0; // 005d27b0
|
||||
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 undefined2& DAT_007825c0; // 007825c0
|
||||
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 undefined& lpSystemTime_007d9e40; // 007d9e40
|
||||
extern undefined4& DAT_007d9e60; // 007d9e60
|
||||
extern undefined& lpRootPathName_007d9e70; // 007d9e70
|
||||
extern undefined3& UNK_007d9e71; // 007d9e71
|
||||
#endif // GH_GENERATED_GLOBALS_H
|
||||
|
|
|
@ -55,22 +55,24 @@
|
|||
005b68f8 || s_Directory_005b68f8 || / || string
|
||||
005b6904 || s_None || / || TerminatedCString
|
||||
005b690c || s_UbiSoft_Ubi_ini || / || TerminatedCString
|
||||
005bda4c || s_UbiSoft_bmp_005bda4c || / || string
|
||||
005bdfd8 || s_R3_DVD_005bdfd8 || / || string
|
||||
005be0ec || s_R3_DVD_005be0ec || / || string
|
||||
005be0f4 || s_%s_DVD_missing_005be0f4 || / || string
|
||||
005be130 || s_Die_%s_DVDROM_kann_nicht_gelesen_005be130 || / || string
|
||||
005be198 || s_Impossibile_trovare_il_DVD_:_%s_005be198 || / || string
|
||||
005be0f4 || s__s_DVD_missing_005be0f4 || / || string
|
||||
005be130 || s_Die__s_DVDROM_kann_nicht_gelesen_005be130 || / || string
|
||||
005be198 || s_Impossibile_trovare_il_DVD____s_005be198 || / || string
|
||||
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
|
||||
005be438 || s_Bitte_legen_Sie_DVD_von_Rayman_3_005be438 || / || string
|
||||
005be484 || s_Inserisci_il_DVD_di_Rayman_3_nel_005be484 || / || string
|
||||
005be4c0 || s_Introduce_el_DVD_de_Rayman_3_en_l_005be4c0 || / || string
|
||||
005be500 || DAT_005be500 || / || undefined
|
||||
005be540 || s_%c:%s_005be540 || / || string
|
||||
005be548 || s_\program_files\Ubi_Soft\Rayman3_005be548 || / || string
|
||||
005be540 || s_fmt_c_colon_s || / || string
|
||||
005be548 || s_r3_program_files || / || string
|
||||
005be568 || PTR_DAT_005be568 || / || undefined *
|
||||
005cf96c || lpDefault_005cf96c || / || long
|
||||
005d2660 || DAT_005d2660 || / || undefined4
|
||||
005d26a8 || DAT_005d26a8 || / || undefined1
|
||||
005d27b0 || lpVolumeNameBuffer_005d27b0 || / || undefined
|
||||
005d28b6 || r3_main_data_005d28b6 || / || r3_main_data
|
||||
|
@ -88,6 +90,16 @@
|
|||
0077d5e0 || s_wndStrRestoring || / || char[256]
|
||||
007825c0 || DAT_007825c0 || / || undefined2
|
||||
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
|
||||
007d9e40 || lpSystemTime_007d9e40 || / || undefined
|
||||
007d9e60 || DAT_007d9e60 || / || undefined4
|
||||
007d9e70 || lpRootPathName_007d9e70 || / || undefined
|
||||
007d9e71 || UNK_007d9e71 || / || undefined3
|
||||
|
|
|
@ -25,6 +25,9 @@ public class DumpCurrentFunction extends GhidraScript {
|
|||
println("No function found at the current address.");
|
||||
}
|
||||
|
||||
if (functionDumper.createdFile)
|
||||
RecompileConfig.INSTANCE.touchCMakeTimestamp();
|
||||
|
||||
globalDumper.dumpGlobals();
|
||||
globalDumper.saveGlobalManifest();
|
||||
}
|
||||
|
|
|
@ -1,103 +1,23 @@
|
|||
// Script to sanitize global symbols in Ghidra
|
||||
// @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.program.model.address.Address;
|
||||
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.GlobalDumper;
|
||||
import re3lib.RecompileConfig;
|
||||
import re3lib.Utils;
|
||||
|
||||
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
|
||||
public void run() throws Exception {
|
||||
if (currentProgram == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RecompileConfig.INSTANCE = new RecompileConfig(this);
|
||||
RecompileConfig.INSTANCE.createDirectories();
|
||||
|
||||
if (!new File(RecompileConfig.INSTANCE.outputDir).exists()) {
|
||||
throw new Exception("Output directory does not exist: " + RecompileConfig.INSTANCE.outputDir);
|
||||
}
|
||||
GlobalDumper globalDumper = new GlobalDumper(this);
|
||||
globalDumper.loadGlobalManifest();
|
||||
|
||||
functionAddrBlackList = Utils.loadFunctionBlacklist(RecompileConfig.INSTANCE.functionBlacklistPath);
|
||||
globalDumper.sanitizeGlobalSymbols();
|
||||
|
||||
List<Function> functions = new ArrayList<>();
|
||||
|
||||
Iterator<Function> functionsIt = currentProgram.getFunctionManager().getFunctions(true).iterator();
|
||||
while (functionsIt.hasNext()) {
|
||||
Function function = functionsIt.next();
|
||||
if (!shouldDecompileFunction(function)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
functions.add(function);
|
||||
}
|
||||
|
||||
sanitizeGlobalSymbolsPass(functions);
|
||||
globalDumper.dumpGlobals();
|
||||
globalDumper.saveGlobalManifest();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ public class FunctionDumper {
|
|||
GlobalDumper globalDumper;
|
||||
HashSet<Address> functionAddrBlackList = new HashSet<>();
|
||||
|
||||
public boolean createdFile = false;
|
||||
|
||||
static final Pattern fieldAccessRegex = Pattern.compile("^_([0-9]+)_([0-9]+)_$");
|
||||
|
||||
public FunctionDumper(GhidraScript script, GlobalDumper globalDumper) {
|
||||
|
@ -112,11 +114,15 @@ public class FunctionDumper {
|
|||
f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName);
|
||||
if (f0.exists()) {
|
||||
f0.delete();
|
||||
} else {
|
||||
createdFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
script.println("Processing " + function.getName() + " => " + f0.toString());
|
||||
|
||||
List<Function> externalFunctionCalls = new ArrayList<>();
|
||||
|
||||
DecompileResults decompRes = RecompileConfig.INSTANCE.decompCache.getOrInsert(function);
|
||||
try (PrintWriter writer2 = new PrintWriter(f0, "UTF-8")) {
|
||||
writer2.println("// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!! ");
|
||||
|
@ -213,6 +219,7 @@ public class FunctionDumper {
|
|||
headers.add("extern " + proto
|
||||
+ "; // " + calledFunction.getEntryPoint() + " // "
|
||||
+ calledFunction.getName());
|
||||
externalFunctionCalls.add(calledFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,5 +243,39 @@ public class FunctionDumper {
|
|||
writer2.print(codeWriter.toString());
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Map;
|
|||
|
||||
import javax.xml.datatype.DatatypeFactory;
|
||||
|
||||
import ghidra.app.cmd.label.AddLabelCmd;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
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.listing.Data;
|
||||
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.AllowedDataTypes;
|
||||
|
||||
|
@ -181,8 +184,9 @@ public class GlobalDumper {
|
|||
initBlk += "(" + dataType + ")&GH_MEM(0x" + addr + ")";
|
||||
fullyDefinedType = true;
|
||||
}
|
||||
String linkagePrefix = "extern ";
|
||||
if (fullyDefinedType) {
|
||||
hwriter.println("extern " + dataType + " " + name + "; // " + addr);
|
||||
hwriter.println(linkagePrefix + dataType + " " + name + "; // " + addr);
|
||||
cwriter.println(dataType + " " + name + initBlk + "; // " + addr);
|
||||
} else {
|
||||
if (dt instanceof Array) {
|
||||
|
@ -191,14 +195,14 @@ public class GlobalDumper {
|
|||
Array adt = (Array) dt;
|
||||
DataType baseType = adt.getDataType();
|
||||
hwriter.println(
|
||||
"extern " + baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "]; // " + addr);
|
||||
linkagePrefix + baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "]; // " + addr);
|
||||
cwriter.println(
|
||||
baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "] = *reinterpret_cast<"
|
||||
+ baseType.getDisplayName() + "(*)[" + adt.getNumElements() + "]>(GH_MEM(0x" + addr + "));");
|
||||
} else {
|
||||
String refTypeStr = dt.getDisplayName() + "&";
|
||||
hwriter.println("extern " + refTypeStr + " " + name + "; // " + addr);
|
||||
cwriter.println(dataType + " " + name + "= (" + refTypeStr + ") GH_MEM(0x" + addr + ");");
|
||||
hwriter.println(linkagePrefix + refTypeStr + " " + name + "; // " + addr);
|
||||
cwriter.println(refTypeStr + " " + name + "= (" + refTypeStr + ") GH_MEM(0x" + addr + ");");
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package re3lib;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
|
@ -27,10 +28,20 @@ public class RecompileConfig {
|
|||
// The manually decompiled files (will not be overwritten by the auto
|
||||
// decompiler)
|
||||
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
|
||||
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 DecompileCache decompCache;
|
||||
|
||||
|
@ -54,6 +65,9 @@ public class RecompileConfig {
|
|||
dirDecompAuto = new File(outputDir, "gh_auto");
|
||||
dirDecompFix = new File(outputDir, "gh_fix");
|
||||
dirDecompRef = new File(outputDir, "gh_ref");
|
||||
dirDecompStub = new File(outputDir, "gh_stub");
|
||||
|
||||
cmakeTimestampFile = new File(outputDir, "gh_cmake_timestamp");
|
||||
|
||||
currentProgram = script.getCurrentProgram();
|
||||
|
||||
|
@ -66,5 +80,16 @@ public class RecompileConfig {
|
|||
dirDecompAuto.mkdirs();
|
||||
dirDecompFix.mkdirs();
|
||||
dirDecompRef.mkdirs();
|
||||
dirDecompStub.mkdirs();
|
||||
}
|
||||
|
||||
public void touchCMakeTimestamp() {
|
||||
try {
|
||||
if (!cmakeTimestampFile.exists()) {
|
||||
cmakeTimestampFile.createNewFile();
|
||||
}
|
||||
cmakeTimestampFile.setLastModified(System.currentTimeMillis());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue