WIP Dump required function pointer types for globals

This commit is contained in:
Guus Waals 2025-06-02 00:05:18 +08:00
parent 2423d68e0a
commit ac9879a4aa
11 changed files with 134 additions and 87 deletions

View File

@ -4,37 +4,35 @@
#include <gh_global.h> #include <gh_global.h>
extern "C" { extern "C" {
undefined IPT_fn_vActivateAllEntryElements(void); // 00505490 // IPT_fn_vActivateAllEntryElements // cdecl // Params: | Types: | Return: undefined undefined FUN_00470350(void); // 00470350 // FUN_00470350 // cdecl
undefined FUN_00443120(undefined4 param_1); // 00443120 // FUN_00443120 // cdecl // Params: param_1 | Types: undefined4 | Return: undefined undefined r3_load_textures_2(void); // 00471760 // r3_load_textures_2 // cdecl
undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300 // cdecl // Params: | Types: | Return: undefined void level_displayFn(byte param); // 00446fc0 // level_displayFn // cdecl
undefined FUN_0047bae0(void); // 0047bae0 // FUN_0047bae0 // cdecl // Params: | Types: | Return: undefined void r3_noop(void * p_cTxt1, void * p_cTxt2); // 00401100 // r3_noop // stdcall
void r3_noop(void * p_cTxt1, void * p_cTxt2); // 00401100 // r3_noop // stdcall // Params: p_cTxt1;p_cTxt2 | Types: void *;void * | Return: void undefined r3_closeConcatTextureFile(void); // 004711d0 // r3_closeConcatTextureFile // cdecl
undefined r3_load_textures_2(void); // 00471760 // r3_load_textures_2 // cdecl // Params: | Types: | Return: undefined undefined FUN_00470db0(void); // 00470db0 // FUN_00470db0 // cdecl
undefined gfx_init2(void); // 00470be0 // gfx_init2 // cdecl // Params: | Types: | Return: undefined undefined FUN_00503710(void); // 00503710 // FUN_00503710 // cdecl
undefined FUN_00402470(undefined4 param_1); // 00402470 // FUN_00402470 // cdecl // Params: param_1 | Types: undefined4 | Return: undefined undefined FUN_00443120(undefined4 param_1); // 00443120 // FUN_00443120 // cdecl
undefined FUN_00470410(void); // 00470410 // FUN_00470410 // cdecl // Params: | Types: | Return: undefined undefined FUN_00442c50(void); // 00442c50 // FUN_00442c50 // cdecl
undefined FUN_00445460(void); // 00445460 // FUN_00445460 // cdecl // Params: | Types: | Return: undefined undefined FUN_00470410(void); // 00470410 // FUN_00470410 // cdecl
undefined FUN_00442c50(void); // 00442c50 // FUN_00442c50 // cdecl // Params: | Types: | Return: undefined undefined FUN_00472150(void); // 00472150 // FUN_00472150 // cdecl
undefined FUN_0051a7a0(short hGLDDevice, undefined4 param_2); // 0051a7a0 // FUN_0051a7a0 // cdecl // Params: hGLDDevice;param_2 | Types: short;undefined4 | Return: undefined undefined FUN_00445460(void); // 00445460 // FUN_00445460 // cdecl
undefined r3_closeConcatTextureFile(void); // 004711d0 // r3_closeConcatTextureFile // cdecl // Params: | Types: | Return: undefined undefined FUN_00442f70(undefined4 param_1); // 00442f70 // FUN_00442f70 // cdecl
undefined r3_processInput1(void); // 00446f10 // r3_processInput1 // cdecl // Params: | Types: | Return: undefined undefined FUN_00445440(void); // 00445440 // FUN_00445440 // cdecl
undefined SND_fn_vResumeSound(void); // 0040a1e0 // SND_fn_vResumeSound // cdecl // Params: | Types: | Return: undefined undefined SND_fn_vResumeSound(void); // 0040a1e0 // SND_fn_vResumeSound // cdecl
undefined FUN_004fa650(void); // 004fa650 // FUN_004fa650 // cdecl // Params: | Types: | Return: undefined undefined IPT_fn_vActivateAllEntryElements(void); // 00505490 // IPT_fn_vActivateAllEntryElements // cdecl
undefined FUN_00445440(void); // 00445440 // FUN_00445440 // cdecl // Params: | Types: | Return: undefined undefined r3_windowLockCursor(void); // 00401320 // r3_windowLockCursor // cdecl
undefined FUN_004725a0(void); // 004725a0 // FUN_004725a0 // cdecl // Params: | Types: | Return: undefined undefined FUN_00402470(undefined4 param_1); // 00402470 // FUN_00402470 // cdecl
undefined FUN_00470db0(void); // 00470db0 // FUN_00470db0 // cdecl // Params: | Types: | Return: undefined undefined gfx_init2(void); // 00470be0 // gfx_init2 // cdecl
undefined r3_windowLockCursor(void); // 00401320 // r3_windowLockCursor // cdecl // Params: | Types: | Return: undefined undefined FUN_004725a0(void); // 004725a0 // FUN_004725a0 // cdecl
undefined FUN_00442f70(undefined4 param_1); // 00442f70 // FUN_00442f70 // cdecl // Params: param_1 | Types: undefined4 | Return: undefined undefined FUN_0051a900(short hGLDDevice); // 0051a900 // FUN_0051a900 // cdecl
undefined FUN_00470350(void); // 00470350 // FUN_00470350 // cdecl // Params: | Types: | Return: undefined undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0 // cdecl
undefined FUN_00503710(void); // 00503710 // FUN_00503710 // cdecl // Params: | Types: | Return: undefined undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300 // cdecl
undefined FUN_00472150(void); // 00472150 // FUN_00472150 // cdecl // Params: | Types: | Return: undefined undefined FUN_004fa650(void); // 004fa650 // FUN_004fa650 // cdecl
undefined FUN_0051a900(short hGLDDevice); // 0051a900 // FUN_0051a900 // cdecl // Params: hGLDDevice | Types: short | Return: undefined undefined r3_processInput1(void); // 00446f10 // r3_processInput1 // cdecl
undefined level_displayFn(void); // 00446fc0 // level_displayFn // cdecl // Params: | Types: | Return: undefined undefined FUN_0047bae0(void); // 0047bae0 // FUN_0047bae0 // cdecl
undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0 // cdecl // Params: | Types: | Return: undefined undefined FUN_0051a7a0(short hGLDDevice, undefined4 param_2); // 0051a7a0 // FUN_0051a7a0 // cdecl
// 00401490 // r3_restore(stdcall)
// Parameters: param_1 | Types: undefined4 | Return: undefined4
// 00401490
/* WARNING: Inlined function: r3_get_engine_mode */ /* WARNING: Inlined function: r3_get_engine_mode */
undefined4 __stdcall r3_restore(undefined4 param_1) undefined4 __stdcall r3_restore(undefined4 param_1)
@ -54,7 +52,7 @@ undefined4 __stdcall r3_restore(undefined4 param_1)
SetWindowTextA(g_gameHWND,g_windowTitleRestoring); SetWindowTextA(g_gameHWND,g_windowTitleRestoring);
UpdateWindow(hWnd); UpdateWindow(hWnd);
SetForegroundWindow(hWnd); SetForegroundWindow(hWnd);
if ((code *)p_fn_vDisplayAll == r3_noop) { if (p_fn_vDisplayAll == r3_noop) {
/* Set window callback? */ /* Set window callback? */
p_fn_vDisplayAll = level_displayFn; p_fn_vDisplayAll = level_displayFn;
} }

View File

@ -5,10 +5,8 @@
extern "C" { extern "C" {
// 004013a0 // r3_windowUnlockCursor(cdecl) // 004013a0
// Parameters: | Types: | Return: void void r3_windowUnlockCursor(void)
void default r3_windowUnlockCursor(void)
{ {
HCURSOR hCursor; HCURSOR hCursor;

View File

@ -1,7 +1,7 @@
// AUTO-GENERATED FILE // AUTO-GENERATED FILE
#include <r3/binders/global.h> #include <r3/binders/global.h>
undefined4& crt_unhandled_exception_handler= (undefined4&) GH_MEM(0x00404a58); undefined4& crt_unhandled_exception_handler= (undefined4&) GH_MEM(0x00404a58);
undefined4& DAT_00597ca0= (undefined4&) GH_MEM(0x00597ca0); dword& DWORD_00597ca0= (dword&) GH_MEM(0x00597ca0);
char(&s__s_not_initialized__005b63e0)[20] = reinterpret_cast<char(&)[20]>(GH_MEM(0x005b63e0)); char(&s__s_not_initialized__005b63e0)[20] = reinterpret_cast<char(&)[20]>(GH_MEM(0x005b63e0));
char(&s_Please_run_the__s_setup__005b63f4)[28] = reinterpret_cast<char(&)[28]>(GH_MEM(0x005b63f4)); char(&s_Please_run_the__s_setup__005b63f4)[28] = reinterpret_cast<char(&)[28]>(GH_MEM(0x005b63f4));
char(&s_dashCC)[4] = reinterpret_cast<char(&)[4]>(GH_MEM(0x005b6410)); char(&s_dashCC)[4] = reinterpret_cast<char(&)[4]>(GH_MEM(0x005b6410));
@ -64,8 +64,8 @@ undefined1& g_errModDInput= (undefined1&) GH_MEM(0x005bd29c);
undefined4& DAT_005bd454= (undefined4&) GH_MEM(0x005bd454); undefined4& DAT_005bd454= (undefined4&) GH_MEM(0x005bd454);
const char* s__jc_z_d__s_005bd460 = "\\jc\\z%d:%s"; // 005bd460 const char* s__jc_z_d__s_005bd460 = "\\jc\\z%d:%s"; // 005bd460
undefined1& g_errModMmg= (undefined1&) GH_MEM(0x005bd58c); undefined1& g_errModMmg= (undefined1&) GH_MEM(0x005bd58c);
undefined* PTR_r3_processInput1_005bdb1c = (undefined*)&GH_MEM(0x005bdb1c); // 005bdb1c pointer& PTR_r3_processInput1_005bdb1c= (pointer&) GH_MEM(0x005bdb1c);
pointer& p_fn_vDisplayAll= (pointer&) GH_MEM(0x005bdb24); level_displayFn *& p_fn_vDisplayAll= (level_displayFn *&) GH_MEM(0x005bdb24);
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
@ -115,8 +115,8 @@ char *& PTR_005cf9b4= (char *&) GH_MEM(0x005cf9b4);
GameStructure& g_currentBinkMovie= (GameStructure&) GH_MEM(0x005d2660); GameStructure& g_currentBinkMovie= (GameStructure&) GH_MEM(0x005d2660);
char(&s_volumeNameBuffer)[128] = reinterpret_cast<char(&)[128]>(GH_MEM(0x005d27b0)); char(&s_volumeNameBuffer)[128] = reinterpret_cast<char(&)[128]>(GH_MEM(0x005d27b0));
r3_main_data& r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6); r3_main_data& r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6);
undefined4& g_soundOnHD= (undefined4&) GH_MEM(0x005d29bc); dword& g_soundOnHD= (dword&) GH_MEM(0x005d29bc);
undefined4& g_complete= (undefined4&) GH_MEM(0x005d29c0); dword& g_complete= (dword&) GH_MEM(0x005d29c0);
int& g_windowInitialized= (int&) GH_MEM(0x0077d0a4); int& g_windowInitialized= (int&) GH_MEM(0x0077d0a4);
int& g_runMaximized= (int&) GH_MEM(0x0077d0a8); int& g_runMaximized= (int&) GH_MEM(0x0077d0a8);
undefined4& g_engineShouldRun= (undefined4&) GH_MEM(0x0077d0b0); undefined4& g_engineShouldRun= (undefined4&) GH_MEM(0x0077d0b0);
@ -137,7 +137,7 @@ char(&s_quitting1)[64] = reinterpret_cast<char(&)[64]>(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));
GAM_EngineStructure& g_stEngineStructure= (GAM_EngineStructure&) GH_MEM(0x007d7dc0); GAM_EngineStructure& g_stEngineStructure= (GAM_EngineStructure&) GH_MEM(0x007d7dc0);
undefined4& DAT_007d9cc4= (undefined4&) GH_MEM(0x007d9cc4); undefined4& DAT_007d9cc4= (undefined4&) GH_MEM(0x007d9cc4);
undefined4& g_config_unused0= (undefined4&) GH_MEM(0x007d9df0); byte& g_config_unused0= (byte&) GH_MEM(0x007d9df0);
char(&g_driveLetter)[4] = reinterpret_cast<char(&)[4]>(GH_MEM(0x007d9e70)); char(&g_driveLetter)[4] = reinterpret_cast<char(&)[4]>(GH_MEM(0x007d9e70));
undefined4& g_GLI_adapter= (undefined4&) GH_MEM(0x007edd60); undefined4& g_GLI_adapter= (undefined4&) GH_MEM(0x007edd60);
undefined1& g_GLI_tnl= (undefined1&) GH_MEM(0x007edd64); undefined1& g_GLI_tnl= (undefined1&) GH_MEM(0x007edd64);

View File

@ -6,7 +6,7 @@
extern undefined4& crt_unhandled_exception_handler; // 00404a58 extern undefined4& crt_unhandled_exception_handler; // 00404a58
extern undefined4& DAT_00597ca0; // 00597ca0 extern dword& DWORD_00597ca0; // 00597ca0
extern char(&s__s_not_initialized__005b63e0)[20]; // 005b63e0 extern char(&s__s_not_initialized__005b63e0)[20]; // 005b63e0
extern char(&s_Please_run_the__s_setup__005b63f4)[28]; // 005b63f4 extern char(&s_Please_run_the__s_setup__005b63f4)[28]; // 005b63f4
extern char(&s_dashCC)[4]; // 005b6410 extern char(&s_dashCC)[4]; // 005b6410
@ -69,8 +69,8 @@ extern undefined1& g_errModDInput; // 005bd29c
extern undefined4& DAT_005bd454; // 005bd454 extern undefined4& DAT_005bd454; // 005bd454
extern const char* s__jc_z_d__s_005bd460; // 005bd460 extern const char* s__jc_z_d__s_005bd460; // 005bd460
extern undefined1& g_errModMmg; // 005bd58c extern undefined1& g_errModMmg; // 005bd58c
extern undefined* PTR_r3_processInput1_005bdb1c; // 005bdb1c extern pointer& PTR_r3_processInput1_005bdb1c; // 005bdb1c
extern pointer& p_fn_vDisplayAll; // 005bdb24 extern level_displayFn *& p_fn_vDisplayAll; // 005bdb24
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
@ -120,8 +120,8 @@ extern char *& PTR_005cf9b4; // 005cf9b4
extern GameStructure& g_currentBinkMovie; // 005d2660 extern GameStructure& g_currentBinkMovie; // 005d2660
extern char(&s_volumeNameBuffer)[128]; // 005d27b0 extern char(&s_volumeNameBuffer)[128]; // 005d27b0
extern r3_main_data& r3_main_data_005d28b6; // 005d28b6 extern r3_main_data& r3_main_data_005d28b6; // 005d28b6
extern undefined4& g_soundOnHD; // 005d29bc extern dword& g_soundOnHD; // 005d29bc
extern undefined4& g_complete; // 005d29c0 extern dword& g_complete; // 005d29c0
extern int& g_windowInitialized; // 0077d0a4 extern int& g_windowInitialized; // 0077d0a4
extern int& g_runMaximized; // 0077d0a8 extern int& g_runMaximized; // 0077d0a8
extern undefined4& g_engineShouldRun; // 0077d0b0 extern undefined4& g_engineShouldRun; // 0077d0b0
@ -142,7 +142,7 @@ extern char(&s_quitting1)[64]; // 007825c0
extern char(&s_wndStrQuiting)[56]; // 00782600 extern char(&s_wndStrQuiting)[56]; // 00782600
extern GAM_EngineStructure& g_stEngineStructure; // 007d7dc0 extern GAM_EngineStructure& g_stEngineStructure; // 007d7dc0
extern undefined4& DAT_007d9cc4; // 007d9cc4 extern undefined4& DAT_007d9cc4; // 007d9cc4
extern undefined4& g_config_unused0; // 007d9df0 extern byte& g_config_unused0; // 007d9df0
extern char(&g_driveLetter)[4]; // 007d9e70 extern char(&g_driveLetter)[4]; // 007d9e70
extern undefined4& g_GLI_adapter; // 007edd60 extern undefined4& g_GLI_adapter; // 007edd60
extern undefined1& g_GLI_tnl; // 007edd64 extern undefined1& g_GLI_tnl; // 007edd64

View File

@ -9,5 +9,5 @@
// 00401300 // 00401300
// getHWND // getHWND
extern "C" HWND getHWND(void) { extern "C" HWND getHWND(void) {
return gh_stub_impl_stdcall<0x00401300, typedef HWND HWND__ *>(); return gh_stub_impl_stdcall<0x00401300, HWND>();
} }

View File

@ -8,6 +8,6 @@
// 00446fc0 // 00446fc0
// level_displayFn // level_displayFn
extern "C" undefined level_displayFn(void) { extern "C" void level_displayFn(byte param) {
return gh_stub_impl_cdecl<0x00446fc0, undefined>(); gh_stub_impl_cdecl<0x00446fc0, void>(param);
} }

View File

@ -10,13 +10,19 @@
static uintptr_t g_gh_translationOffset{}; static uintptr_t g_gh_translationOffset{};
extern "C" { extern "C" {
#define cdecl #define HOOK(addr, name) void name(void *);
#define stdcall __stdcall #define HOOK_S0(addr, name) void __stdcall name();
#define HOOK(addr, name, call_conv) void call_conv name(void *); #define HOOK_S1(addr, name) void __stdcall name(int);
#define HOOK_S2(addr, name) void __stdcall name(int, int);
#define HOOK_S3(addr, name) void __stdcall name(int, int, int);
#define HOOK_S4(addr, name) void __stdcall name(int, int, int, int);
#include "hooks.def" #include "hooks.def"
#undef HOOK #undef HOOK
#undef stdcall #undef HOOK_S0
#undef cdecl #undef HOOK_S1
#undef HOOK_S2
#undef HOOK_S3
#undef HOOK_S4
} }
struct R3Bin { struct R3Bin {
@ -37,10 +43,12 @@ struct R3Bin {
g_gh_translationOffset = translationOffset = g_gh_translationOffset = translationOffset =
uintptr_t(module) - GH_BASE_ADDR; uintptr_t(module) - GH_BASE_ADDR;
std::string msg = fmt::format("Rayman3.exe Base address: 0x{:x}\n", uintptr_t(module)); std::string msg =
fmt::format("Rayman3.exe Base address: 0x{:x}\n", uintptr_t(module));
OutputDebugStringA(msg.c_str()); OutputDebugStringA(msg.c_str());
msg = fmt::format("Rayman3.exe Translation offset: 0x{:x}\n", translationOffset); msg = fmt::format("Rayman3.exe Translation offset: 0x{:x}\n",
translationOffset);
OutputDebugStringA(msg.c_str()); OutputDebugStringA(msg.c_str());
// Now we have to relocate the module to the new base address // Now we have to relocate the module to the new base address
@ -48,8 +56,7 @@ struct R3Bin {
patchFunctions(); patchFunctions();
} }
inline void relocate(void *instr, void *from, inline void relocate(void *instr, void *from, void *originalPointee) {
void *originalPointee) {
void *relocated_addr = (void *)(uintptr_t(from) + translationOffset); void *relocated_addr = (void *)(uintptr_t(from) + translationOffset);
void *relocated_to = void *relocated_to =
(void *)(uintptr_t(originalPointee) + translationOffset); (void *)(uintptr_t(originalPointee) + translationOffset);
@ -179,7 +186,13 @@ struct R3Bin {
"Failed to patch function {} at {} (RVA: {})", name, resolved, at)); "Failed to patch function {} at {} (RVA: {})", name, resolved, at));
} }
void patchFunctions() { void patchFunctions() {
#define HOOK(addr, name, call_conv) patchFunction((void*)addr, &name, #name); #define HOOK(addr, name) patchFunction((void *)addr, &name, #name);
#define HOOK_S0(addr, name) HOOK(addr, name)
#define HOOK_S1(addr, name) HOOK(addr, name)
#define HOOK_S2(addr, name) HOOK(addr, name)
#define HOOK_S3(addr, name) HOOK(addr, name)
#define HOOK_S4(addr, name) HOOK(addr, name)
#include "hooks.def" #include "hooks.def"
} }

View File

@ -150,7 +150,6 @@ public class DataTypeWriter {
} }
} }
// Step 3: Topological sort and write // Step 3: Topological sort and write
List<Block> sortedBlocks = topologicalSort(blocks); List<Block> sortedBlocks = topologicalSort(blocks);
for (Block block : sortedBlocks) { for (Block block : sortedBlocks) {

View File

@ -82,7 +82,7 @@ public class FunctionDumper {
// Helper method to extract return type from Ghidra function // Helper method to extract return type from Ghidra function
private String extractReturnType(Function function) { private String extractReturnType(Function function) {
var returnType = function.getReturnType(); var returnType = function.getReturnType();
return returnType != null ? returnType.toString() : "void"; return returnType != null ? returnType.getDisplayName() : "void";
} }
boolean isValidFunction(Function function) { boolean isValidFunction(Function function) {
@ -180,8 +180,6 @@ public class FunctionDumper {
String parameterTypes = extractParameterTypes(externalFunction); String parameterTypes = extractParameterTypes(externalFunction);
String returnType = extractReturnType(externalFunction); String returnType = extractReturnType(externalFunction);
script.println("Parameters: " + parameterNames + " | Types: " + parameterTypes + " | Return: " + returnType);
try (PrintWriter writer2 = new PrintWriter(f4, "UTF-8")) { try (PrintWriter writer2 = new PrintWriter(f4, "UTF-8")) {
writer2.println("// AUTO-GENERATED FILE!!!!"); writer2.println("// AUTO-GENERATED FILE!!!!");
writer2.println("// This function has yet to be decompiled using 'Dump Current Function' in ghidra"); writer2.println("// This function has yet to be decompiled using 'Dump Current Function' in ghidra");
@ -345,9 +343,9 @@ public class FunctionDumper {
HashMap<String, String> replacementMap = new HashMap<>(); HashMap<String, String> replacementMap = new HashMap<>();
String newFunctionName = sanitizedFunctionName; String newFunctionName = sanitizedFunctionName;
if (callingConvention != FunctionDatabase.CallingConvention.Stdcall || if (callingConvention == FunctionDatabase.CallingConvention.Stdcall ||
callingConvention != FunctionDatabase.CallingConvention.Fastcall) { callingConvention == FunctionDatabase.CallingConvention.Fastcall) {
newFunctionName = callingConventionName + " " + newFunctionName; newFunctionName = "__" + callingConvention.toString() + " " + newFunctionName;
} }
String originalFunctionName = function.getName(); String originalFunctionName = function.getName();
@ -486,14 +484,9 @@ public class FunctionDumper {
String callingConv = externalFunction.getCallingConventionName(); String callingConv = externalFunction.getCallingConventionName();
FunctionDatabase.CallingConvention conv = FunctionDatabase.CallingConvention.fromString(callingConv); FunctionDatabase.CallingConvention conv = FunctionDatabase.CallingConvention.fromString(callingConv);
// Add parameter information to the comment
String extParamNames = extractParameterNames(externalFunction);
String extParamTypes = extractParameterTypes(externalFunction);
String extReturnType = extractReturnType(externalFunction);
headers.add("" + proto headers.add("" + proto
+ "; // " + externalFunction.getEntryPoint() + " // " + "; // " + externalFunction.getEntryPoint() + " // "
+ name + " // " + conv + " // Params: " + extParamNames + " | Types: " + extParamTypes + " | Return: " + extReturnType); + name + " // " + conv);
} }
for (String header : headers) { for (String header : headers) {
@ -501,8 +494,6 @@ public class FunctionDumper {
} }
writer2.println(); writer2.println();
writer2.print("// " + function.getEntryPoint()); writer2.print("// " + function.getEntryPoint());
writer2.println(" // " + function.getName() + "(" + callingConvention + ")");
writer2.println("// Parameters: " + parameterNames + " | Types: " + parameterTypes + " | Return: " + returnType);
String codeString = codeWriter.toString(); String codeString = codeWriter.toString();
for (HashMap.Entry<String, String> entry : replacementMap.entrySet()) { for (HashMap.Entry<String, String> entry : replacementMap.entrySet()) {
String oldName = entry.getKey(); String oldName = entry.getKey();

View File

@ -8,6 +8,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.CategoryPath; import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.Composite; import ghidra.program.model.data.Composite;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
@ -20,7 +21,9 @@ import ghidra.program.model.data.TypeDef;
import ghidra.program.model.data.TypedefDataType; import ghidra.program.model.data.TypedefDataType;
import ghidra.program.model.data.Union; import ghidra.program.model.data.Union;
import ghidra.program.model.data.UnionDataType; import ghidra.program.model.data.UnionDataType;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import re3lib.FunctionDatabase.GlobalEntry;
public class TypeDumper { public class TypeDumper {
Program currentProgram; Program currentProgram;
@ -35,6 +38,25 @@ public class TypeDumper {
public void run() throws Exception { public void run() throws Exception {
ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager(); ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager();
HashSet<String> requiredFunctionTypes = new HashSet<>();
FunctionDatabase fd = new FunctionDatabase(script);
List<GlobalEntry> globals = fd.loadAllGlobals();
for (GlobalEntry globalEntry : globals) {
// Fetch type of global from ghidra
Address addr = globalEntry.address;
if (globalEntry.name == "p_fn_vDisplayAll")
script.println("EEEEE");
Data data = script.getDataAt(addr);
if (data != null) {
DataType type = data.getDataType();
if (type instanceof FunctionDefinition) {
requiredFunctionTypes.add(type.getDisplayName());
script.println("Adding required global function type: " + type.getDisplayName());
}
}
}
HashSet<String> typeBlacklist = Utils.loadSimpleBlacklist(RemanConfig.INSTANCE.typeBlacklistPath); HashSet<String> typeBlacklist = Utils.loadSimpleBlacklist(RemanConfig.INSTANCE.typeBlacklistPath);
HashSet<String> categoryPathBlacklist = Utils HashSet<String> categoryPathBlacklist = Utils
.loadSimpleBlacklist(RemanConfig.INSTANCE.categoryPathBlacklistPath); .loadSimpleBlacklist(RemanConfig.INSTANCE.categoryPathBlacklistPath);
@ -89,7 +111,7 @@ public class TypeDumper {
if (dt instanceof Structure || dt instanceof TypeDef || dt instanceof EnumDataType if (dt instanceof Structure || dt instanceof TypeDef || dt instanceof EnumDataType
|| dt instanceof Union || dt instanceof Enum || dt instanceof FunctionDefinition) { || dt instanceof Union || dt instanceof Enum || dt instanceof FunctionDefinition) {
if (dt.getDisplayName().contains("NormalizeFn") || dt.getDisplayName().contains("_M_IX86")) if (dt.getDisplayName().contains("level_displayFn") || dt.getDisplayName().contains("_M_IX86"))
script.println("DEBUG " + dt.getDisplayName() + " - " + dt.getClass().getSimpleName()); script.println("DEBUG " + dt.getDisplayName() + " - " + dt.getClass().getSimpleName());
// if (dt.getDisplayName().contains("tdstObjectTypeElement_") || // if (dt.getDisplayName().contains("tdstObjectTypeElement_") ||
@ -113,6 +135,7 @@ public class TypeDumper {
writer.println("#include <r3/binders/type.h>"); writer.println("#include <r3/binders/type.h>");
DataTypeWriter dtw = new DataTypeWriter(dtm, writer); DataTypeWriter dtw = new DataTypeWriter(dtm, writer);
dtw.requiredFunctionTypes = requiredFunctionTypes;
dtw.write(filteredTypes, script.getMonitor()); dtw.write(filteredTypes, script.getMonitor());
Utils.headerGuardPost(writer, "STRUCTS"); Utils.headerGuardPost(writer, "STRUCTS");

View File

@ -11,7 +11,8 @@ bool generateHooksFile(const std::string &output_filepath) {
try { try {
DatabaseManager db(options.db_path); DatabaseManager db(options.db_path);
std::vector<FunctionInfo> fix_functions = db.getFunctionsByType(FileType::Fix); std::vector<FunctionInfo> fix_functions =
db.getFunctionsByType(FileType::Fix);
std::ofstream output_stream(output_filepath); std::ofstream output_stream(output_filepath);
if (!output_stream.is_open()) { if (!output_stream.is_open()) {
@ -23,17 +24,40 @@ bool generateHooksFile(const std::string &output_filepath) {
for (const auto &func : fix_functions) { for (const auto &func : fix_functions) {
// Extract just the filename from the full path // Extract just the filename from the full path
std::string filename = std::filesystem::path(func.filepath).filename().string(); std::string filename =
std::filesystem::path(func.filepath).filename().string();
std::string conv_str = callingConventionToString(func.calling_convention); std::string conv_str = callingConventionToString(func.calling_convention);
size_t numParams = 0;
if (!func.parameter_types.empty()) {
std::string params = func.parameter_types;
std::stringstream ss(params);
std::string param;
while (std::getline(ss, param, ';')) {
if (!param.empty()) {
numParams++;
}
}
}
output_stream << "HOOK(0x" << func.address << ", " << func.name << ", " << conv_str << ") // " << filename << std::endl; if (func.parameter_types == "void")
numParams = 0;
spdlog::debug("Added hook: {} {} {} from {}", func.address, func.name, conv_str, filename); if (conv_str == "stdcall") {
output_stream << "HOOK_S" << numParams << "(0x" << func.address << ", "
<< func.name << ") // " << filename << std::endl;
} else {
output_stream << "HOOK(0x" << func.address << ", " << func.name
<< ") // " << filename << std::endl;
}
spdlog::debug("Added hook: {} {} {} from {}", func.address, func.name,
conv_str, filename);
} }
output_stream.close(); output_stream.close();
spdlog::info("Generated {} hooks in {}", fix_functions.size(), output_filepath); spdlog::info("Generated {} hooks in {}", fix_functions.size(),
output_filepath);
return true; return true;
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -43,7 +67,8 @@ bool generateHooksFile(const std::string &output_filepath) {
} }
void register_cmd_hooks(CLI::App &app) { void register_cmd_hooks(CLI::App &app) {
auto cmd = app.add_subcommand("hooks", "Generate hooks file for Fix-type functions"); auto cmd =
app.add_subcommand("hooks", "Generate hooks file for Fix-type functions");
cmd->add_option("-o,--output", output_file, "Output file for hooks") cmd->add_option("-o,--output", output_file, "Output file for hooks")
->default_val("hooks.def"); ->default_val("hooks.def");
cmd->final_callback([]() { cmd->final_callback([]() {