Compare commits
2 Commits
35b2c67e73
...
7a7c907abb
Author | SHA1 | Date |
---|---|---|
|
7a7c907abb | |
|
6bce41bd2d |
|
@ -51,7 +51,10 @@ void gh_pre_main(void) {
|
|||
// pvStack_14 = ExceptionList;
|
||||
// local_1c = &stack0xffffff88;
|
||||
// ExceptionList = &pvStack_14;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
DVar1 = GetVersion();
|
||||
#pragma clang diagnostic pop
|
||||
DWORD_005cf980 = DVar1 >> 8 & 0xff;
|
||||
DWORD_005cf97c = DVar1 & 0xff;
|
||||
DWORD_005cf978 = DWORD_005cf97c * 0x100 + DWORD_005cf980;
|
||||
|
|
|
@ -69,8 +69,7 @@ int r3_main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR *cmdline,
|
|||
CHAR pathToUbi_ini[228];
|
||||
char acStack_528[16];
|
||||
char acStack_518[244];
|
||||
char acStack_424[16];
|
||||
CHAR aCStack_414[244];
|
||||
char acStack_424[0x104];
|
||||
char acStack_320[16];
|
||||
char acStack_310[240];
|
||||
char acStack_220[256];
|
||||
|
@ -544,9 +543,9 @@ LAB_004017ce:
|
|||
return -1;
|
||||
}
|
||||
p_cTxt2 = (void *)0x401e5a;
|
||||
GetWindowsDirectoryA(aCStack_414, 0x104);
|
||||
iVar13 = -1;
|
||||
#if RE_AUTHENTIC == 0
|
||||
GetWindowsDirectoryA(acStack_424, 0x104);
|
||||
iVar13 = -1;
|
||||
/* Append ubi.ini */
|
||||
pcVar4 = acStack_424;
|
||||
do {
|
||||
|
@ -566,6 +565,7 @@ LAB_004017ce:
|
|||
#else
|
||||
strcpy(acStack_424, config.gameRootDir.c_str());
|
||||
strcat(acStack_424, "/ubi.ini");
|
||||
instance = hInstance;
|
||||
#endif
|
||||
/* Read graphics settings */
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_Adapter_005b68e4,
|
||||
|
@ -596,13 +596,6 @@ LAB_004017ce:
|
|||
DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
|
||||
&duplicatedHandle, DVar7, BVar18, dwOptions);
|
||||
/* Copy cmdline */
|
||||
ppCVar8 = puStack_14;
|
||||
g_mainThreadHandle = duplicatedHandle;
|
||||
// do {
|
||||
// uVar14 = *ppCVar8;
|
||||
// *(char *)(((int)g_appCmdLine - (int)puStack_14) + (int)ppCVar8) =
|
||||
// (char)uVar14; ppCVar8 = (uint *)((int)ppCVar8 + 1);
|
||||
// } while ((char)uVar14 != '\0');
|
||||
LPSTR cmdline = GetCommandLineA();
|
||||
strncpy(g_appCmdLine, cmdline, std::size(g_appCmdLine));
|
||||
/* SEM_FAILCRITICALERRORS */
|
||||
|
@ -610,7 +603,7 @@ LAB_004017ce:
|
|||
pcVar4 = strstr(cmdline, s_dashCC);
|
||||
if (pcVar4 == (char *)0x0) {
|
||||
r3_initAllModules();
|
||||
iVar13 = setupWindow(instance, uStack_10, g_runMaximized);
|
||||
iVar13 = setupWindow(instance, 0, g_runMaximized);
|
||||
if (iVar13 == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -628,17 +621,19 @@ LAB_004017ce:
|
|||
iVar10 = r3_get_gli_width1();
|
||||
iVar10 = iVar10 + 0xc;
|
||||
iVar11 = r3_get_gli_height1();
|
||||
iVar11 = (int)(rect.top - iVar11) / 2;
|
||||
iVar11 = (int)(rect.bottom - iVar11) / 2;
|
||||
iVar12 = r3_get_gli_width1();
|
||||
MoveWindow(g_gameHWND, (int)(rect.right - iVar12) / 2, iVar11, iVar10,
|
||||
MoveWindow(g_gameHWND, 0, 0, iVar10,
|
||||
iVar13, BVar18);
|
||||
FUN_004010b0();
|
||||
#if RE_AUTHENTIC == 0
|
||||
DWORD screensaveActive;
|
||||
SystemParametersInfoA(SPI_GETSCREENSAVEACTIVE, 0, &screensaveActive, 0);
|
||||
SystemParametersInfoA(SPI_SETSCREENSAVEACTIVE, 0, (PVOID)0x0, 0);
|
||||
ShowCursor(0);
|
||||
uStack_85c = 0;
|
||||
SystemParametersInfoA(0x61, 1, &uStack_85c, 0);
|
||||
#endif
|
||||
g_engineRunning = 1;
|
||||
r3_engineLoop();
|
||||
/* cleanup starts here */
|
||||
|
@ -648,11 +643,13 @@ LAB_004017ce:
|
|||
FUN_004fb300();
|
||||
FUN_00472150();
|
||||
FUN_00470db0();
|
||||
#if RE_AUTHENTIC == 0
|
||||
uStack_85c = 0;
|
||||
SystemParametersInfoA(0x61, 0, &uStack_85c, 0);
|
||||
ShowCursor(1);
|
||||
SystemParametersInfoA(0x11, uiParam, (PVOID)0x0, 0);
|
||||
CloseHandle(lpBuffer);
|
||||
#endif
|
||||
CloseHandle(duplicatedHandle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <gh_global.h>
|
||||
#include <r3/config/static.hpp>
|
||||
|
||||
extern "C" {
|
||||
undefined
|
||||
r3_config_setIdentifier(char *param_1); // 00470570 // r3_config_setIdentifier
|
||||
void r3_set_GameDataPath(char *param_1); // 0055a8d0 // r3_set_GameDataPath
|
||||
void r3_config_setTexturesMem(
|
||||
char *param_1); // 00470f30 // r3_config_setTexturesMem
|
||||
void r3_noop(void *p_cTxt1, void *p_cTxt2); // 00401100 // r3_noop
|
||||
undefined
|
||||
r3_read_game_config_udp_port(void); // 00446040 // r3_read_game_config_udp_port
|
||||
undefined
|
||||
r3_config_setGLIMode(char *param_1); // 004704e0 // r3_config_setGLIMode
|
||||
undefined r3_read_game_config_modem_quality(
|
||||
void); // 00445fc0 // r3_read_game_config_modem_quality
|
||||
|
||||
// 004460c0
|
||||
/* WARNING: Inlined function: r3_config_set_adapter */
|
||||
/* WARNING: Inlined function: r3_config_setTexturesCompressed */
|
||||
/* WARNING: Inlined function: r3_config_setTnl */
|
||||
/* WARNING: Inlined function: r3_config_setTrilinearFiltering */
|
||||
|
||||
void r3_read_gli_config(void)
|
||||
|
||||
{
|
||||
UINT tempOutVal;
|
||||
void *pcVar2;
|
||||
void *pcVar3;
|
||||
HANDLE hProcess;
|
||||
int iVar4;
|
||||
char *pcVar1;
|
||||
char *pcVar4;
|
||||
void *in_stack_fffffce0;
|
||||
char *ptr0;
|
||||
char *ptr1;
|
||||
char local_218[20];
|
||||
char local_204[168];
|
||||
char local_15c[32];
|
||||
char stringBuffer[256];
|
||||
char cVar1;
|
||||
DWORD_PTR dwProcessAffinityMask;
|
||||
|
||||
const char *iniPath = getIniPath();
|
||||
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_GLI_Mode_005be3e0,
|
||||
g_default_display_mode, stringBuffer, 0xff, iniPath);
|
||||
r3_config_setGLIMode(stringBuffer);
|
||||
g_GLI_adapter =
|
||||
GetPrivateProfileIntA(lpAppName_005b68f0, s_Adapter_005b68e4, 0, iniPath);
|
||||
/* set adapter */
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_Identifier_005b6420,
|
||||
(LPCSTR)&lpDefault_005cf96c, stringBuffer, 0xff,
|
||||
iniPath);
|
||||
r3_config_setIdentifier(stringBuffer);
|
||||
tempOutVal = GetPrivateProfileIntA(lpAppName_005b68f0,
|
||||
s_TexturesCompressed_005be3cc, 0, iniPath);
|
||||
g_config_tex_compressed = (undefined1)tempOutVal;
|
||||
tempOutVal =
|
||||
GetPrivateProfileIntA(lpAppName_005b68f0, (LPCSTR)&s_Tnl, 0, iniPath);
|
||||
g_GLI_tnl = (undefined1)tempOutVal;
|
||||
tempOutVal = GetPrivateProfileIntA(lpAppName_005b68f0, s_TriLinear_005be3bc,
|
||||
0, iniPath);
|
||||
g_GLI_trilinear = (undefined1)tempOutVal;
|
||||
pcVar2 = (void *)GetPrivateProfileIntA(lpAppName_005b68f0,
|
||||
s_DynamicShadows_005be3ac, 0, iniPath);
|
||||
pcVar3 = (void *)GetPrivateProfileIntA(lpAppName_005b68f0,
|
||||
s_StaticShadows_005be39c, 0, iniPath);
|
||||
//r3_noop(pcVar2, pcVar3);
|
||||
pcVar2 = (void *)GetPrivateProfileIntA(lpAppName_005b68f0, s_Outline_005be394,
|
||||
0, iniPath);
|
||||
//r3_noop(pcVar2, in_stack_fffffce0);
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_TexturesMem_005be384,
|
||||
(LPCSTR)&s_Agp, stringBuffer, 0xff, iniPath);
|
||||
r3_config_setTexturesMem(stringBuffer);
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_SoundOnHD_005be374, "0",
|
||||
stringBuffer, 0x104, iniPath);
|
||||
sscanf(stringBuffer, s_percent_d, &g_soundOnHD);
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_Complete_005be364, "1",
|
||||
stringBuffer, 0x104, iniPath);
|
||||
sscanf(stringBuffer, s_percent_d, &g_complete);
|
||||
g_config_unused0 = 0;
|
||||
g_config_camera_hor_axis = GetPrivateProfileIntA(
|
||||
lpAppName_005b68f0, s_Camera_HorizontalAxis_005be34c, 2, iniPath);
|
||||
g_config_camera_ver_axis = GetPrivateProfileIntA(
|
||||
lpAppName_005b68f0, s_Camera_VerticalAxis_005be338, 5, iniPath);
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_StartDirectory_005be31c,
|
||||
s_Gamedata_005be32c, stringBuffer, 0x104, iniPath);
|
||||
r3_set_GameDataPath(stringBuffer);
|
||||
GetPrivateProfileStringA(lpAppName_005b68f0, s_SingleProcessor_005be308, "No",
|
||||
stringBuffer, 0x104, iniPath);
|
||||
/* Set single processor mode */
|
||||
iVar4 = strcmpi(stringBuffer, (char *)&s_Yes);
|
||||
if (iVar4 == 0) {
|
||||
dwProcessAffinityMask = 1;
|
||||
hProcess = GetCurrentProcess();
|
||||
SetProcessAffinityMask(hProcess, dwProcessAffinityMask);
|
||||
}
|
||||
r3_read_game_config_modem_quality();
|
||||
r3_read_game_config_udp_port();
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
extern "C" {
|
||||
undefined r3_windowUnlockCursor(void); // 004013a0 // r3_windowUnlockCursor
|
||||
undefined FUN_00401320(void); // 00401320 // FUN_00401320
|
||||
|
||||
// 004025e0
|
||||
long CALLBACK r3_windowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
|
||||
|
||||
{
|
||||
long lVar1;
|
||||
|
||||
if (uMsg < WM_SETCURSOR + 1) {
|
||||
if (uMsg == WM_SETCURSOR) {
|
||||
if (((g_engineShouldRun != 0) && (g_engineRunning != 0)) && (g_runMaximized != 0)) {
|
||||
FUN_00401320();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uMsg == WM_CLOSE) {
|
||||
r3_windowUnlockCursor();
|
||||
g_windowCloseRequested = 1;
|
||||
if (g_drawSemaphore != (HANDLE)0x0) {
|
||||
CloseHandle(g_drawSemaphore);
|
||||
}
|
||||
g_drawSemaphore = (HANDLE)0x0;
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
if (uMsg == WM_ACTIVATEAPP) {
|
||||
g_engineShouldRun = wParam;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uMsg != WM_NCHITTEST) {
|
||||
if (uMsg != WM_SYSCOMMAND) goto LAB_004026ab;
|
||||
/* handle SYSCOMMAND */
|
||||
if (wParam < SC_MAXIMIZE + 1) {
|
||||
if ((wParam != SC_MAXIMIZE) && ((wParam != SC_SIZE && (wParam != SC_MOVE))))
|
||||
goto LAB_004026ab;
|
||||
}
|
||||
else if ((wParam != SC_KEYMENU) && (wParam != SC_MONITORPOWER)) goto LAB_004026ab;
|
||||
}
|
||||
/* WM_NCHITTEST
|
||||
*/
|
||||
if (g_runMaximized != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
LAB_004026ab:
|
||||
/* WARNING: Could not recover jumptable at 0x004026b3. Too many branches */
|
||||
/* WARNING: Treating indirect jump as call */
|
||||
lVar1 = DefWindowProcA(hwnd,uMsg,wParam,lParam);
|
||||
return lVar1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
extern "C" {
|
||||
long CALLBACK r3_windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // 004025e0 // r3_windowProc
|
||||
undefined fn_bCreateMainDisplayScreen(void); // 004022f0 // fn_bCreateMainDisplayScreen
|
||||
void loadSplashBitmap(HWND unused); // 00402450 // loadSplashBitmap
|
||||
void setGameHWND3(HWND wnd); // 0043e620 // setGameHWND3
|
||||
|
||||
// 00402140
|
||||
int setupWindow(HINSTANCE instance,undefined4 param_2,int windowedParam)
|
||||
|
||||
{
|
||||
ATOM AVar1;
|
||||
int windowHeight;
|
||||
int yCaption;
|
||||
HWND hWnd;
|
||||
HWND pHVar2;
|
||||
int r0;
|
||||
BOOL success;
|
||||
bool windowed;
|
||||
GLD_DeviceAttributes *windowParams;
|
||||
DWORD dwStyle;
|
||||
WNDCLASSA wndClass;
|
||||
int showWindow;
|
||||
int windowWidth;
|
||||
|
||||
g_windowInitialized = 1;
|
||||
/* WindowClassA (overlaps usage below) */
|
||||
wndClass.style = 0x3003;
|
||||
wndClass.lpfnWndProc = r3_windowProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = 0;
|
||||
wndClass.hInstance = instance;
|
||||
wndClass.hIcon = LoadIconA(instance,(LPCSTR)0x65);
|
||||
wndClass.hCursor = LoadCursorA((HINSTANCE)0x0,(LPCSTR)0x7f00);
|
||||
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME;
|
||||
wndClass.lpszMenuName = (LPCSTR)0x0;
|
||||
wndClass.lpszClassName = g_windowTitle;
|
||||
AVar1 = RegisterClassA(&wndClass);
|
||||
if (AVar1 != 0) {
|
||||
windowed = windowedParam == 0;
|
||||
if (windowed) {
|
||||
/* SM_CXSIZEFRAME */
|
||||
windowWidth = GetSystemMetrics(32);
|
||||
/* x*2 + 320 */
|
||||
windowWidth = windowWidth * 2 + 320;
|
||||
/* SM_CYSIZEFRAME, retrieves the size of the vertical resizing border */
|
||||
windowHeight = GetSystemMetrics(33);
|
||||
/* SM_CYCAPTION, The height of a caption area, in pixels */
|
||||
yCaption = GetSystemMetrics(4);
|
||||
/* ebp still 0 at this point */
|
||||
windowHeight = yCaption + 240 + windowHeight * 2;
|
||||
dwStyle = 0x90cf0000;
|
||||
}
|
||||
else {
|
||||
windowHeight = 0xf0;
|
||||
windowWidth = 0x140;
|
||||
dwStyle = 0x91000000;
|
||||
}
|
||||
hWnd = CreateWindowExA(0,g_windowTitle,g_windowTitle,dwStyle,(uint)windowed,(uint)windowed,
|
||||
windowWidth,windowHeight,(HWND)0x0,(HMENU)0x0,instance,(LPVOID)0x0);
|
||||
g_gameHWND1 = hWnd;
|
||||
if (hWnd != (HWND)0x0) {
|
||||
g_gameHWND = hWnd;
|
||||
SetWindowTextA(hWnd,s_windowTitle);
|
||||
if (windowedParam == 0) {
|
||||
/* SW_NORMAL */
|
||||
showWindow = 1;
|
||||
}
|
||||
else {
|
||||
/* SW_MAXIMIZE */
|
||||
showWindow = 3;
|
||||
}
|
||||
ShowWindow(hWnd,showWindow);
|
||||
SetWindowPos(hWnd,(HWND)0x0,0,0,0,0,0x43);
|
||||
EnableWindow(hWnd,1);
|
||||
SetFocus(hWnd);
|
||||
UpdateWindow(hWnd);
|
||||
SetForegroundWindow(hWnd);
|
||||
pHVar2 = GetFocus();
|
||||
while (pHVar2 != hWnd) {
|
||||
SetWindowPos(hWnd,(HWND)0x0,0,0,0,0,0x43);
|
||||
EnableWindow(hWnd,1);
|
||||
SetFocus(hWnd);
|
||||
UpdateWindow(hWnd);
|
||||
SetForegroundWindow(hWnd);
|
||||
pHVar2 = GetFocus();
|
||||
}
|
||||
setGameHWND3(hWnd);
|
||||
loadSplashBitmap(hWnd);
|
||||
/* unused? */
|
||||
g_windowInitialized = 1;
|
||||
r0 = fn_bCreateMainDisplayScreen();
|
||||
return r0;
|
||||
}
|
||||
}
|
||||
/* Failed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -59,6 +59,7 @@ char(&lpAppName_005b68f0)[8] = reinterpret_cast<char(&)[8]>(GH_MEM(0x005b68f0));
|
|||
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_percent_d = "%d"; // 005bad58
|
||||
undefined1& g_errModDInput= (undefined1&) GH_MEM(0x005bd29c);
|
||||
undefined4& DAT_005bd454= (undefined4&) GH_MEM(0x005bd454);
|
||||
const char* s__jc_z_d__s_005bd460 = "\\jc\\z%d:%s"; // 005bd460
|
||||
|
@ -70,6 +71,27 @@ const char* s_Die__s_DVDROM_kann_nicht_gelesen_005be130 = "Die %s DVDROM kann ni
|
|||
const char* s_Impossibile_trovare_il_DVD____s_005be198 = "Impossibile trovare il DVD : %s"; // 005be198
|
||||
const char* s_DVD_s_no_v_lido_005be1ec = "DVD %s no v£lido "; // 005be1ec
|
||||
const char* s_Impossible_de_trouver_le_DVD_____005be238 = "Impossible de trouver le DVD : %s"; // 005be238
|
||||
pointer& s_Yes= (pointer&) GH_MEM(0x005be304);
|
||||
const char* s_SingleProcessor_005be308 = "SingleProcessor"; // 005be308
|
||||
const char* lpDefault_005be318 = "No"; // 005be318
|
||||
const char* s_StartDirectory_005be31c = "StartDirectory"; // 005be31c
|
||||
const char* s_Gamedata_005be32c = "Gamedata"; // 005be32c
|
||||
const char* s_Camera_VerticalAxis_005be338 = "Camera_VerticalAxis"; // 005be338
|
||||
const char* s_Camera_HorizontalAxis_005be34c = "Camera_HorizontalAxis"; // 005be34c
|
||||
const char* s_Complete_005be364 = "Complete"; // 005be364
|
||||
const char* lpDefault_005be370 = "1"; // 005be370
|
||||
const char* s_SoundOnHD_005be374 = "SoundOnHD"; // 005be374
|
||||
const char* lpDefault_005be380 = "0"; // 005be380
|
||||
const char* s_TexturesMem_005be384 = "TexturesMem"; // 005be384
|
||||
pointer& s_Agp= (pointer&) GH_MEM(0x005be390);
|
||||
const char* s_Outline_005be394 = "Outline"; // 005be394
|
||||
const char* s_StaticShadows_005be39c = "StaticShadows"; // 005be39c
|
||||
const char* s_DynamicShadows_005be3ac = "DynamicShadows"; // 005be3ac
|
||||
const char* s_TriLinear_005be3bc = "TriLinear"; // 005be3bc
|
||||
pointer& s_Tnl= (pointer&) GH_MEM(0x005be3c8);
|
||||
const char* s_TexturesCompressed_005be3cc = "TexturesCompressed"; // 005be3cc
|
||||
const char* s_GLI_Mode_005be3e0 = "GLI_Mode"; // 005be3e0
|
||||
const char* g_default_display_mode = "1 - 640 x 480 x 16"; // 005be3ec
|
||||
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
|
||||
|
@ -78,6 +100,8 @@ const char* s_Veuillez_ins_rer_le_DVD_dans_vot_005be500 = "Veuillez ins←rer le
|
|||
const char* s_fmt_c_colon_s = "%c:%s"; // 005be540
|
||||
const char* s_r3_program_files = "\\program files\\Ubi Soft\\Rayman3"; // 005be548
|
||||
const char* s_driveLetterTemplate = "A:\\"; // 005be568
|
||||
undefined4& g_config_camera_hor_axis= (undefined4&) GH_MEM(0x005c67c8);
|
||||
undefined4& g_config_camera_ver_axis= (undefined4&) GH_MEM(0x005c67cc);
|
||||
HWND& g_gameHWND1= (HWND&) GH_MEM(0x005cf964);
|
||||
long& lpDefault_005cf96c= (long&) GH_MEM(0x005cf96c);
|
||||
dword& DWORD_005cf974= (dword&) GH_MEM(0x005cf974);
|
||||
|
@ -88,8 +112,13 @@ char *& PTR_005cf9b4= (char *&) GH_MEM(0x005cf9b4);
|
|||
GameStructure& g_currentBinkMovie= (GameStructure&) GH_MEM(0x005d2660);
|
||||
char(&s_volumeNameBuffer)[128] = reinterpret_cast<char(&)[128]>(GH_MEM(0x005d27b0));
|
||||
r3_main_data& r3_main_data_005d28b6= (r3_main_data&) GH_MEM(0x005d28b6);
|
||||
undefined4& g_soundOnHD= (undefined4&) GH_MEM(0x005d29bc);
|
||||
undefined4& g_complete= (undefined4&) GH_MEM(0x005d29c0);
|
||||
int& g_windowInitialized= (int&) GH_MEM(0x0077d0a4);
|
||||
int& g_runMaximized= (int&) GH_MEM(0x0077d0a8);
|
||||
undefined4& g_engineShouldRun= (undefined4&) GH_MEM(0x0077d0b0);
|
||||
undefined4& g_engineRunning= (undefined4&) GH_MEM(0x0077d0b4);
|
||||
undefined4& g_windowCloseRequested= (undefined4&) GH_MEM(0x0077d0b8);
|
||||
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));
|
||||
|
@ -104,4 +133,9 @@ char *& g_crt_cmdLine= (char *&) GH_MEM(0x0077ea84);
|
|||
char(&s_quitting1)[64] = reinterpret_cast<char(&)[64]>(GH_MEM(0x007825c0));
|
||||
char(&s_wndStrQuiting)[56] = reinterpret_cast<char(&)[56]>(GH_MEM(0x00782600));
|
||||
undefined4& DAT_007d9cc4= (undefined4&) GH_MEM(0x007d9cc4);
|
||||
undefined4& g_config_unused0= (undefined4&) GH_MEM(0x007d9df0);
|
||||
char(&g_driveLetter)[4] = reinterpret_cast<char(&)[4]>(GH_MEM(0x007d9e70));
|
||||
undefined4& g_GLI_adapter= (undefined4&) GH_MEM(0x007edd60);
|
||||
undefined1& g_GLI_tnl= (undefined1&) GH_MEM(0x007edd64);
|
||||
undefined1& g_config_tex_compressed= (undefined1&) GH_MEM(0x007edd65);
|
||||
undefined1& g_GLI_trilinear= (undefined1&) GH_MEM(0x007edd66);
|
||||
|
|
|
@ -64,6 +64,7 @@ extern char(&lpAppName_005b68f0)[8]; // 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_percent_d; // 005bad58
|
||||
extern undefined1& g_errModDInput; // 005bd29c
|
||||
extern undefined4& DAT_005bd454; // 005bd454
|
||||
extern const char* s__jc_z_d__s_005bd460; // 005bd460
|
||||
|
@ -75,6 +76,27 @@ extern const char* s_Die__s_DVDROM_kann_nicht_gelesen_005be130; // 005be130
|
|||
extern const char* s_Impossibile_trovare_il_DVD____s_005be198; // 005be198
|
||||
extern const char* s_DVD_s_no_v_lido_005be1ec; // 005be1ec
|
||||
extern const char* s_Impossible_de_trouver_le_DVD_____005be238; // 005be238
|
||||
extern pointer& s_Yes; // 005be304
|
||||
extern const char* s_SingleProcessor_005be308; // 005be308
|
||||
extern const char* lpDefault_005be318; // 005be318
|
||||
extern const char* s_StartDirectory_005be31c; // 005be31c
|
||||
extern const char* s_Gamedata_005be32c; // 005be32c
|
||||
extern const char* s_Camera_VerticalAxis_005be338; // 005be338
|
||||
extern const char* s_Camera_HorizontalAxis_005be34c; // 005be34c
|
||||
extern const char* s_Complete_005be364; // 005be364
|
||||
extern const char* lpDefault_005be370; // 005be370
|
||||
extern const char* s_SoundOnHD_005be374; // 005be374
|
||||
extern const char* lpDefault_005be380; // 005be380
|
||||
extern const char* s_TexturesMem_005be384; // 005be384
|
||||
extern pointer& s_Agp; // 005be390
|
||||
extern const char* s_Outline_005be394; // 005be394
|
||||
extern const char* s_StaticShadows_005be39c; // 005be39c
|
||||
extern const char* s_DynamicShadows_005be3ac; // 005be3ac
|
||||
extern const char* s_TriLinear_005be3bc; // 005be3bc
|
||||
extern pointer& s_Tnl; // 005be3c8
|
||||
extern const char* s_TexturesCompressed_005be3cc; // 005be3cc
|
||||
extern const char* s_GLI_Mode_005be3e0; // 005be3e0
|
||||
extern const char* g_default_display_mode; // 005be3ec
|
||||
extern const char* s_Please_insert_the_DVD_in_the_DVD_005be400; // 005be400
|
||||
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
|
||||
|
@ -83,6 +105,8 @@ extern const char* s_Veuillez_ins_rer_le_DVD_dans_vot_005be500; // 005be500
|
|||
extern const char* s_fmt_c_colon_s; // 005be540
|
||||
extern const char* s_r3_program_files; // 005be548
|
||||
extern const char* s_driveLetterTemplate; // 005be568
|
||||
extern undefined4& g_config_camera_hor_axis; // 005c67c8
|
||||
extern undefined4& g_config_camera_ver_axis; // 005c67cc
|
||||
extern HWND& g_gameHWND1; // 005cf964
|
||||
extern long& lpDefault_005cf96c; // 005cf96c
|
||||
extern dword& DWORD_005cf974; // 005cf974
|
||||
|
@ -93,8 +117,13 @@ extern char *& PTR_005cf9b4; // 005cf9b4
|
|||
extern GameStructure& g_currentBinkMovie; // 005d2660
|
||||
extern char(&s_volumeNameBuffer)[128]; // 005d27b0
|
||||
extern r3_main_data& r3_main_data_005d28b6; // 005d28b6
|
||||
extern undefined4& g_soundOnHD; // 005d29bc
|
||||
extern undefined4& g_complete; // 005d29c0
|
||||
extern int& g_windowInitialized; // 0077d0a4
|
||||
extern int& g_runMaximized; // 0077d0a8
|
||||
extern undefined4& g_engineShouldRun; // 0077d0b0
|
||||
extern undefined4& g_engineRunning; // 0077d0b4
|
||||
extern undefined4& g_windowCloseRequested; // 0077d0b8
|
||||
extern HANDLE& g_drawSemaphore; // 0077d0bc
|
||||
extern char(&g_mutexName_Rayman3)[256]; // 0077d0c0
|
||||
extern char(&g_windowTitle)[256]; // 0077d1c0
|
||||
|
@ -109,5 +138,10 @@ extern char *& g_crt_cmdLine; // 0077ea84
|
|||
extern char(&s_quitting1)[64]; // 007825c0
|
||||
extern char(&s_wndStrQuiting)[56]; // 00782600
|
||||
extern undefined4& DAT_007d9cc4; // 007d9cc4
|
||||
extern undefined4& g_config_unused0; // 007d9df0
|
||||
extern char(&g_driveLetter)[4]; // 007d9e70
|
||||
extern undefined4& g_GLI_adapter; // 007edd60
|
||||
extern undefined1& g_GLI_tnl; // 007edd64
|
||||
extern undefined1& g_config_tex_compressed; // 007edd65
|
||||
extern undefined1& g_GLI_trilinear; // 007edd66
|
||||
#endif // GH_GENERATED_GLOBALS_H
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 00402140
|
||||
// setupWindow
|
||||
extern "C" int setupWindow(HINSTANCE instance, undefined4 param_2, int windowedParam) {
|
||||
return gh_stub_impl_stdcall<int>((void*)0x00402140, instance, param_2, windowedParam);
|
||||
// 004022f0
|
||||
// fn_bCreateMainDisplayScreen
|
||||
extern "C" undefined fn_bCreateMainDisplayScreen(void) {
|
||||
return gh_stub_impl_cdecl<undefined>((void*)0x004022f0);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 00402450
|
||||
// loadSplashBitmap
|
||||
extern "C" void loadSplashBitmap(HWND unused) {
|
||||
gh_stub_impl_stdcall<void>((void*)0x00402450, unused);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 004704e0
|
||||
// r3_config_setGLIMode
|
||||
extern "C" undefined r3_config_setGLIMode(char * param_1) {
|
||||
return gh_stub_impl_cdecl<undefined>((void*)0x004704e0, param_1);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 00470570
|
||||
// r3_config_setIdentifier
|
||||
extern "C" undefined r3_config_setIdentifier(char * param_1) {
|
||||
return gh_stub_impl_cdecl<undefined>((void*)0x00470570, param_1);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 00470f30
|
||||
// r3_config_setTexturesMem
|
||||
extern "C" void r3_config_setTexturesMem(char * param_1) {
|
||||
gh_stub_impl_cdecl<void>((void*)0x00470f30, param_1);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 00445fc0
|
||||
// r3_read_game_config_modem_quality
|
||||
extern "C" undefined r3_read_game_config_modem_quality(void) {
|
||||
return gh_stub_impl_cdecl<undefined>((void*)0x00445fc0);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 00446040
|
||||
// r3_read_game_config_udp_port
|
||||
extern "C" undefined r3_read_game_config_udp_port(void) {
|
||||
return gh_stub_impl_cdecl<undefined>((void*)0x00446040);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 0055a8d0
|
||||
// r3_set_GameDataPath
|
||||
extern "C" void r3_set_GameDataPath(char * param_1) {
|
||||
gh_stub_impl_cdecl<void>((void*)0x0055a8d0, param_1);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 004013a0
|
||||
// r3_windowUnlockCursor
|
||||
extern "C" undefined r3_windowUnlockCursor(void) {
|
||||
return gh_stub_impl_cdecl<undefined>((void*)0x004013a0);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// AUTO-GENERATED FILE!!!!
|
||||
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
|
||||
// with possible manualy fixes
|
||||
|
||||
#include <r3/binders/auto.h>
|
||||
#include <r3/binders/stub.h>
|
||||
#include <gh_global.h>
|
||||
|
||||
// 0043e620
|
||||
// setGameHWND3
|
||||
extern "C" void setGameHWND3(HWND wnd) {
|
||||
gh_stub_impl_stdcall<void>((void*)0x0043e620, wnd);
|
||||
}
|
|
@ -33,6 +33,12 @@ struct R3Bin {
|
|||
g_gh_translationOffset = translationOffset =
|
||||
uintptr_t(module) - GH_BASE_ADDR;
|
||||
|
||||
std::string msg = fmt::format("Rayman3.exe Base address: 0x{:x}\n", uintptr_t(module));
|
||||
OutputDebugStringA(msg.c_str());
|
||||
|
||||
msg = fmt::format("Rayman3.exe Translation offset: 0x{:x}\n", translationOffset);
|
||||
OutputDebugStringA(msg.c_str());
|
||||
|
||||
// Now we have to relocate the module to the new base address
|
||||
relocateModule();
|
||||
patchFunctions();
|
||||
|
|
|
@ -33,6 +33,7 @@ struct R3Config {
|
|||
int cameraHorizontalAxis = 2;
|
||||
int cameraVerticalAxis = 5;
|
||||
std::string gameDataBinPath;
|
||||
std::string iniPath;
|
||||
};
|
||||
|
||||
inline R3Config createDefaultConfig() {
|
||||
|
@ -51,6 +52,7 @@ inline R3Config createDefaultConfig() {
|
|||
config.gfxTnl = true;
|
||||
config.gfxTexturesCompressed = false;
|
||||
config.gameDataBinPath = "Gamedatabin";
|
||||
config.iniPath = config.gameRootDir + "\\" + "ubi.ini";
|
||||
return config;
|
||||
}
|
||||
|
||||
|
@ -59,4 +61,8 @@ inline R3Config &getDefaultConfig() {
|
|||
return config;
|
||||
}
|
||||
|
||||
inline const char *getIniPath() {
|
||||
return getDefaultConfig().iniPath.c_str();
|
||||
}
|
||||
|
||||
#endif /* D9171C14_8ED0_407B_A289_4C75D30D9DCC */
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/bash
|
||||
script_dir=$(readlink -f $(dirname "$0"))
|
||||
tool=$script_dir/../tooling/bin/r3_gh_tool
|
||||
tool=$script_dir/../tooling/bin/gh_tool
|
||||
|
||||
set -e
|
||||
set -ex
|
||||
shopt -s nullglob
|
||||
|
||||
pushd $script_dir
|
||||
|
@ -19,12 +19,12 @@ for type in "${types[@]}"; do
|
|||
any_files=true
|
||||
done
|
||||
if [ "$any_files" = true ]; then
|
||||
$tool "@$file_list" -v --type=$type --log-file=logs/log-functions-${type}.txt
|
||||
$tool -v --log-file=logs/log-functions-${type}.txt functions "@$file_list" --type=$type
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
$tool gh_global.h -mglobals -v --log-file=logs/log-globals.txt
|
||||
$tool -mduplicates -v --log-file=logs/log-duplicates.txt
|
||||
$tool -v --log-file=logs/log-globals.txt globals gh_global.h
|
||||
$tool -v --log-file=logs/log-verify.txt verify
|
||||
|
||||
popd
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
// Script to export decompiled C code from Ghidra
|
||||
// @category _Reman3
|
||||
// @menupath Reman3.Decompile All
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Arrays;
|
||||
import java.util.Dictionary;
|
||||
|
||||
import ghidra.app.decompiler.ClangFieldToken;
|
||||
import ghidra.app.decompiler.ClangLine;
|
||||
import ghidra.app.decompiler.ClangSyntaxToken;
|
||||
import ghidra.app.decompiler.ClangToken;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.decompiler.PrettyPrinter;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.AbstractStringDataType;
|
||||
import ghidra.program.model.data.Array;
|
||||
import ghidra.program.model.data.ArrayDataType;
|
||||
import ghidra.program.model.data.BitFieldDataType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.EnumDataType;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.ProgramBasedDataTypeManager;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.TypedefDataType;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.VariableStorage;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.HighSymbol;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import re3lib.*;
|
||||
|
||||
public class Decompile extends GhidraScript {
|
||||
|
||||
|
||||
// void headerGuardPre(PrintWriter writer, String tag) {
|
||||
// writer.println("#ifndef GH_GENERATED_" + tag + "_H");
|
||||
// writer.println("#define GH_GENERATED_" + tag + "_H");
|
||||
// writer.println();
|
||||
// }
|
||||
|
||||
// void headerGuardPost(PrintWriter writer, String tag) {
|
||||
// writer.println("#endif // GH_GENERATED_" + tag + "_H");
|
||||
// }
|
||||
|
||||
// void dumpGlobals(Hashtable<String, GlobalRec> globalSymbols) throws Exception {
|
||||
// File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h");
|
||||
// PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8");
|
||||
// hwriter.println("// AUTO-GENERATED FILE ");
|
||||
// headerGuardPre(hwriter, "GLOBALS");
|
||||
// hwriter.println("#include <r3/binder/global.h>");
|
||||
// hwriter.println();
|
||||
|
||||
// File globalSymbolsListC = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.cxx");
|
||||
// PrintWriter cwriter = new PrintWriter(globalSymbolsListC, "UTF-8");
|
||||
// cwriter.println("// AUTO-GENERATED FILE ");
|
||||
// cwriter.println("#include <r3/binder/global.h>");
|
||||
// hwriter.println();
|
||||
|
||||
// for (GlobalRec sym : globalSymbols.values()) {
|
||||
// HighSymbol highSym = sym.highSymbol;
|
||||
// DataType dt = highSym.getDataType();
|
||||
// String dataType = dt.getDisplayName();
|
||||
// String sanitizedName = sanitizeFunctionName(highSym.getName());
|
||||
// String name = highSym.getName();
|
||||
// if (!sanitizedName.equals(name)) {
|
||||
// println("Invalid global symbol name: " + name);
|
||||
// name = sanitizedName;
|
||||
// }
|
||||
// Address addr = sym.address;
|
||||
// // println("Symbol: " + symbol + " Addr: " + addr + " Size:" + symSize + " " +
|
||||
// // storage.getSerializationString());
|
||||
// try {
|
||||
// String initBlk = " = ";
|
||||
// boolean fullyDefinedType = false;
|
||||
// if (dt instanceof AbstractStringDataType) {
|
||||
// AbstractStringDataType sdt = (AbstractStringDataType) dt;
|
||||
// dataType = "const char*";
|
||||
// // String type
|
||||
// initBlk += "\"" + escapeCString(readCString(addr, 2048)) + "\"";
|
||||
// fullyDefinedType = true;
|
||||
// } else if (dt instanceof PointerDataType) {
|
||||
// PointerDataType pdt = (PointerDataType) dt;
|
||||
// DataType baseType = pdt.getDataType();
|
||||
// dataType = baseType.getDisplayName() + "*";
|
||||
// initBlk += "(" + dataType + ")&GH_MEM(0x" + addr + ")";
|
||||
// fullyDefinedType = true;
|
||||
// }
|
||||
// if (fullyDefinedType) {
|
||||
// hwriter.println("extern " + dataType + " " + name + "; // " + addr);
|
||||
// cwriter.println(dataType + " " + name + initBlk + "; // " + addr);
|
||||
// } else {
|
||||
// if (dt instanceof Array) {
|
||||
// // println("Array: " + dt.getDisplayName() + " - " + addr + " - " +
|
||||
// // dt.getClass().getSimpleName());
|
||||
// Array adt = (Array) dt;
|
||||
// DataType baseType = adt.getDataType();
|
||||
// hwriter.println(
|
||||
// "extern " + 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 + ");");
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// println("Error processing global symbol: " + e);
|
||||
// println("Symbol: " + highSym.getName() + " - " + addr + " - "
|
||||
// + highSym.getHighFunction().getFunction().getName());
|
||||
// }
|
||||
// }
|
||||
|
||||
// headerGuardPost(hwriter, "GLOBALS");
|
||||
// hwriter.close();
|
||||
// cwriter.close();
|
||||
// }
|
||||
|
||||
void decompileAll(List<Function> functions) throws Exception {
|
||||
// Hashtable<String, GlobalRec> globalSymbols = new Hashtable<>();
|
||||
|
||||
// for (Function function : functions) {
|
||||
// decompileFunction(globalSymbols, function);
|
||||
// }
|
||||
|
||||
// dumpStructureTypes();
|
||||
// dumpGlobals(globalSymbols);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
if (currentProgram == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RemanConfig.INSTANCE = new RemanConfig(this);
|
||||
|
||||
if (!new File(RemanConfig.INSTANCE.outputDir).exists()) {
|
||||
throw new Exception("Output directory does not exist: " + RemanConfig.INSTANCE.outputDir);
|
||||
}
|
||||
|
||||
// Make sure to create output folders
|
||||
RemanConfig.INSTANCE.dirDecompFix.mkdirs();
|
||||
RemanConfig.INSTANCE.dirDecompAuto.mkdirs();
|
||||
RemanConfig.INSTANCE.dirDecompRef.mkdirs();
|
||||
|
||||
// buildFunctionBlacklist();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
decompileAll(functions);
|
||||
}
|
||||
|
||||
String sanitizeFunctionName(String name) {
|
||||
return name.replaceAll("[^a-zA-Z0-9_]", "_");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Script to regenerate all dumped stub functions
|
||||
// @category _Reman3
|
||||
// @menupath Reman3.Redump Stub Functions
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import re3lib.GlobalDumper;
|
||||
import re3lib.RemanConfig;
|
||||
import re3lib.TypeDumper;
|
||||
import re3lib.FunctionDatabase;
|
||||
import re3lib.FunctionDumper;
|
||||
|
||||
public class RedumpStubFunctions extends GhidraScript {
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
RemanConfig.INSTANCE = new RemanConfig(this);
|
||||
RemanConfig.INSTANCE.createDirectories();
|
||||
|
||||
try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) {
|
||||
List<FunctionDatabase.FunctionEntry> entries = functionDatabase.loadAllEntries();
|
||||
FunctionDumper dumper = new FunctionDumper(this, functionDatabase, null);
|
||||
for (FunctionDatabase.FunctionEntry entry : entries) {
|
||||
if (entry.type == FunctionDatabase.Type.Stub) {
|
||||
Function function = getFunctionAt(entry.address);
|
||||
if (function == null) {
|
||||
printerr("Function not found at address: " + entry.address);
|
||||
continue;
|
||||
}
|
||||
println("Dumping stub function: " + function.getName());
|
||||
dumper.dumpStubFunction(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,6 +108,91 @@ public class FunctionDumper {
|
|||
}
|
||||
}
|
||||
|
||||
public void dumpStubFunction(Function externalFunction) throws Exception {
|
||||
String sanitizedExtFunctionName = Utils.sanitizeIdentifier(externalFunction.getName());
|
||||
|
||||
List<FunctionDatabase.FunctionEntry> entries1 = functionDatabase
|
||||
.findEntriesByAddress(externalFunction.getEntryPoint());
|
||||
boolean needStub = true;
|
||||
for (FunctionDatabase.FunctionEntry entry : entries1) {
|
||||
if (entry.type == FunctionDatabase.Type.Auto || entry.type == FunctionDatabase.Type.Fix) {
|
||||
needStub = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!needStub)
|
||||
return;
|
||||
|
||||
String fileName = sanitizedExtFunctionName + ".cxx";
|
||||
File f4 = new File(RemanConfig.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 <r3/binders/auto.h>");
|
||||
writer2.println("#include <r3/binders/stub.h>");
|
||||
writer2.println("#include <gh_global.h>");
|
||||
writer2.println();
|
||||
writer2.println("// " + externalFunction.getEntryPoint());
|
||||
writer2.println("// " + externalFunction.getName());
|
||||
|
||||
// Parse function signature to extract calling convention, return type, and
|
||||
// parameters
|
||||
String signature = externalFunction.getSignature().getPrototypeString(false);
|
||||
signature = signature.replace(externalFunction.getName(), sanitizedExtFunctionName);
|
||||
script.println("Santized Signature: " + signature);
|
||||
String callingConvention = externalFunction.getCallingConventionName();
|
||||
String returnType = externalFunction.getReturnType().toString();
|
||||
|
||||
// Generate function stub using appropriate forwarding function
|
||||
writer2.println("extern \"C\" " + signature + " {");
|
||||
|
||||
// Determine which stub function to use based on calling convention
|
||||
String stubFunction;
|
||||
if (callingConvention != null && callingConvention.equals("__stdcall")) {
|
||||
stubFunction = "gh_stub_impl_stdcall";
|
||||
} else {
|
||||
// Default to cdecl for most cases
|
||||
stubFunction = "gh_stub_impl_cdecl";
|
||||
}
|
||||
|
||||
// Generate parameter list for the call
|
||||
StringBuilder paramList = new StringBuilder();
|
||||
var params = externalFunction.getParameters();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (i > 0)
|
||||
paramList.append(", ");
|
||||
paramList.append(params[i].getName());
|
||||
}
|
||||
|
||||
// Generate the stub call
|
||||
String addrString = "0x" +
|
||||
externalFunction.getEntryPoint().toString().replace("0x", "");
|
||||
if (returnType.equals("void")) {
|
||||
writer2.println(" " + stubFunction + "<" + addrString + ", void>(" +
|
||||
(paramList.length() > 0 ? ", " + paramList.toString() : "") + ");");
|
||||
} else {
|
||||
writer2.println(" return " + stubFunction + "<" + addrString + ", " + returnType + ">(" +
|
||||
externalFunction.getEntryPoint().toString().replace("0x", "") +
|
||||
(paramList.length() > 0 ? ", " + paramList.toString() : "") + ");");
|
||||
}
|
||||
|
||||
writer2.println("}");
|
||||
}
|
||||
|
||||
if (!f4.exists()) {
|
||||
createdFile = true;
|
||||
}
|
||||
|
||||
// Add stub function to database
|
||||
FunctionDatabase.FunctionEntry newEntry = new FunctionDatabase.FunctionEntry(externalFunction.getEntryPoint(),
|
||||
externalFunction.getName(), f4, FunctionDatabase.Type.Stub);
|
||||
functionDatabase.addEntryAt(newEntry);
|
||||
}
|
||||
|
||||
public void dump(Function function)
|
||||
throws Exception {
|
||||
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
|
||||
|
@ -346,82 +431,7 @@ public class FunctionDumper {
|
|||
|
||||
// Possibly generate stubs for external functions
|
||||
for (Function externalFunction : externalFunctionCalls) {
|
||||
String sanitizedExtFunctionName = Utils.sanitizeIdentifier(externalFunction.getName());
|
||||
|
||||
List<FunctionDatabase.FunctionEntry> entries1 = functionDatabase
|
||||
.findEntriesByAddress(externalFunction.getEntryPoint());
|
||||
boolean needStub = true;
|
||||
for (FunctionDatabase.FunctionEntry entry : entries1) {
|
||||
if (entry.type == FunctionDatabase.Type.Auto || entry.type == FunctionDatabase.Type.Fix) {
|
||||
needStub = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!needStub)
|
||||
continue;
|
||||
|
||||
fileName = sanitizedExtFunctionName + ".cxx";
|
||||
File f4 = new File(RemanConfig.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 <r3/binders/auto.h>");
|
||||
writer2.println("#include <r3/binders/stub.h>");
|
||||
writer2.println("#include <gh_global.h>");
|
||||
writer2.println();
|
||||
writer2.println("// " + externalFunction.getEntryPoint());
|
||||
writer2.println("// " + externalFunction.getName());
|
||||
|
||||
// Parse function signature to extract calling convention, return type, and
|
||||
// parameters
|
||||
String signature = externalFunction.getSignature().getPrototypeString(false);
|
||||
signature = signature.replace(externalFunction.getName(), sanitizedExtFunctionName);
|
||||
script.println("Santiziaed Signature: " + signature);
|
||||
String callingConvention = externalFunction.getCallingConventionName();
|
||||
String returnType = externalFunction.getReturnType().toString();
|
||||
|
||||
// Generate function stub using appropriate forwarding function
|
||||
writer2.println("extern \"C\" " + signature + " {");
|
||||
|
||||
// Determine which stub function to use based on calling convention
|
||||
String stubFunction;
|
||||
if (callingConvention != null && callingConvention.equals("__stdcall")) {
|
||||
stubFunction = "gh_stub_impl_stdcall";
|
||||
} else {
|
||||
// Default to cdecl for most cases
|
||||
stubFunction = "gh_stub_impl_cdecl";
|
||||
}
|
||||
|
||||
// Generate parameter list for the call
|
||||
StringBuilder paramList = new StringBuilder();
|
||||
var params = externalFunction.getParameters();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (i > 0)
|
||||
paramList.append(", ");
|
||||
paramList.append(params[i].getName());
|
||||
}
|
||||
|
||||
// Generate the stub call
|
||||
if (returnType.equals("void")) {
|
||||
writer2.println(" " + stubFunction + "<void>((void*)0x" +
|
||||
externalFunction.getEntryPoint().toString().replace("0x", "") +
|
||||
(paramList.length() > 0 ? ", " + paramList.toString() : "") + ");");
|
||||
} else {
|
||||
writer2.println(" return " + stubFunction + "<" + returnType + ">((void*)0x" +
|
||||
externalFunction.getEntryPoint().toString().replace("0x", "") +
|
||||
(paramList.length() > 0 ? ", " + paramList.toString() : "") + ");");
|
||||
}
|
||||
|
||||
writer2.println("}");
|
||||
}
|
||||
|
||||
if (!f4.exists()) {
|
||||
createdFile = true;
|
||||
}
|
||||
dumpStubFunction(externalFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,15 @@
|
|||
#include <CLI11.hpp>
|
||||
|
||||
bool processDuplicates(DatabaseManager &db) {
|
||||
// Scan all files in the database, and for non-existing files, remove them from the database
|
||||
auto files = db.getAllFiles();
|
||||
for (auto &file : files) {
|
||||
if (!std::filesystem::exists(file)) {
|
||||
spdlog::warn("File not found, removing from database: {}", file);
|
||||
db.removeFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
spdlog::info("=== Checking for duplicate addresses ===");
|
||||
bool found_address_duplicates = db.checkDuplicateAddresses();
|
||||
if (found_address_duplicates) {
|
||||
|
|
|
@ -12,6 +12,9 @@ public:
|
|||
sqlite3_stmt *insert_imports_stmt;
|
||||
sqlite3_stmt *delete_globals_stmt;
|
||||
sqlite3_stmt *insert_globals_stmt;
|
||||
sqlite3_stmt *delete_file_functions_stmt;
|
||||
sqlite3_stmt *delete_file_imports_stmt;
|
||||
sqlite3_stmt *delete_file_globals_stmt;
|
||||
|
||||
void prepareStatement(const char *sql, sqlite3_stmt **stmt,
|
||||
const std::string &error_msg);
|
||||
|
@ -38,6 +41,15 @@ public:
|
|||
"VALUES (?, ?, ?)",
|
||||
&insert_globals_stmt,
|
||||
"Failed to prepare insert globals statement");
|
||||
prepareStatement("DELETE FROM Functions WHERE filepath = ?",
|
||||
&delete_file_functions_stmt,
|
||||
"Failed to prepare delete file functions statement");
|
||||
prepareStatement("DELETE FROM Imports WHERE filepath = ?",
|
||||
&delete_file_imports_stmt,
|
||||
"Failed to prepare delete file imports statement");
|
||||
prepareStatement("DELETE FROM Globals WHERE filepath = ?",
|
||||
&delete_file_globals_stmt,
|
||||
"Failed to prepare delete file globals statement");
|
||||
}
|
||||
|
||||
~PreparedStatements() {
|
||||
|
@ -47,6 +59,9 @@ public:
|
|||
sqlite3_finalize(insert_imports_stmt);
|
||||
sqlite3_finalize(delete_globals_stmt);
|
||||
sqlite3_finalize(insert_globals_stmt);
|
||||
sqlite3_finalize(delete_file_functions_stmt);
|
||||
sqlite3_finalize(delete_file_imports_stmt);
|
||||
sqlite3_finalize(delete_file_globals_stmt);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -253,3 +268,50 @@ std::vector<FunctionInfo> DatabaseManager::getFunctionsByType(FileType type) {
|
|||
sqlite3_finalize(stmt);
|
||||
return functions;
|
||||
}
|
||||
|
||||
std::vector<std::string> DatabaseManager::getAllFiles() {
|
||||
std::vector<std::string> files;
|
||||
|
||||
const char *sql = R"(
|
||||
SELECT DISTINCT filepath FROM (
|
||||
SELECT filepath FROM Functions
|
||||
UNION
|
||||
SELECT filepath FROM Imports
|
||||
UNION
|
||||
SELECT filepath FROM Globals
|
||||
) ORDER BY filepath;
|
||||
)";
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
|
||||
spdlog::error("Failed to prepare getAllFiles query: {}", sqlite3_errmsg(db));
|
||||
return files;
|
||||
}
|
||||
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
const char *filepath = (const char *)sqlite3_column_text(stmt, 0);
|
||||
if (filepath) {
|
||||
files.push_back(std::string(filepath));
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return files;
|
||||
}
|
||||
|
||||
void DatabaseManager::removeFile(const std::string &filepath) {
|
||||
// Use prepared statements for efficient deletion
|
||||
sqlite3_stmt *stmts[] = {
|
||||
prepared_stmts->delete_file_functions_stmt,
|
||||
prepared_stmts->delete_file_imports_stmt,
|
||||
prepared_stmts->delete_file_globals_stmt
|
||||
};
|
||||
|
||||
for (auto stmt : stmts) {
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_bind_text(stmt, 1, filepath.c_str(), -1, SQLITE_STATIC);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
spdlog::debug("Removed all entries for file: {}", filepath);
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
});
|
||||
app.add_flag("--log-file", options.log_file, "Enable logging to file")
|
||||
->each([&](std::string) {
|
||||
->each([&](const std::string& arg) {
|
||||
auto log_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(
|
||||
options.log_file, true);
|
||||
arg, true);
|
||||
console->sinks().push_back(log_sink);
|
||||
});
|
||||
app.require_subcommand();
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
bool checkDuplicateAddresses();
|
||||
bool checkDuplicateNames();
|
||||
std::vector<FunctionInfo> getFunctionsByType(FileType type);
|
||||
std::vector<std::string> getAllFiles();
|
||||
void removeFile(const std::string &filepath);
|
||||
};
|
||||
|
||||
// File processing functions
|
||||
|
|
Loading…
Reference in New Issue