Compare commits

...

17 Commits

Author SHA1 Message Date
Guus Waals 2c104648cd WIP setup CRT 2025-05-30 02:02:43 +08:00
Guus Waals acb9d47e0e Ray3 main debug stub 2025-05-30 00:18:17 +08:00
Guus Waals ea677e6de7 WIP 2025-05-29 23:59:16 +08:00
Guus Waals 4a669d86b7 Cleanup 2025-05-29 23:59:05 +08:00
Guus Waals 35a220de3f WIP 2025-05-29 22:18:55 +08:00
Guus Waals b0b4683f7d WIP 2025-05-29 20:36:01 +08:00
Guus Waals e7417745fd WIP 2025-05-29 20:09:23 +08:00
Guus Waals 31ee70e8c0 Wip new dtw 2025-05-29 19:44:08 +08:00
Guus Waals 55438d7380 WIP 2025-05-29 19:16:33 +08:00
Guus Waals edf6cc5a67 Add ghidra eclipse project 2025-05-29 19:16:20 +08:00
Guus Waals ebfc4bf4f4 WIP 2025-05-29 19:15:52 +08:00
Guus Waals 5ce1a399b1 Update stub dumping routines 2025-05-29 18:05:55 +08:00
Guus Waals e19a123b94 WIP 2025-05-29 18:03:37 +08:00
Guus Waals 16e5456079 WIP 2025-05-29 17:36:15 +08:00
Guus Waals 2791a66b1f Ignore logs 2025-05-29 17:32:17 +08:00
Guus Waals 45344e2e52 Ignore db 2025-05-29 17:31:54 +08:00
Guus Waals 647e3668a0 Update readme and rename config java 2025-05-29 17:31:42 +08:00
63 changed files with 8696 additions and 15070 deletions

4
game_re/.gitignore vendored
View File

@ -5,4 +5,6 @@ gh_cmake_timestamp
functions.dat
*.zip
.tmp
.txt
.txt
*.db
logs/

View File

@ -1,7 +1,6 @@
function(setup_target TARGET)
function(setup_target TARGET DBG_MODE)
add_executable(${TARGET}
r3/main.cpp
r3/binders/static_mem.cxx
r3/main.cxx
gh_global.cxx
)
@ -14,6 +13,7 @@ function(setup_target TARGET)
)
if(WIN32 AND R3_32BIT)
target_link_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../third_party/bink)
target_link_libraries(${TARGET} PRIVATE
binkw32
d3d8
@ -63,9 +63,36 @@ function(setup_target TARGET)
target_precompile_headers(${TARGET} PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/r3/binders/auto_pch.cxx>"
)
# Potentially might want 1/1 translation for code
# For now it has the following values:
# 0 = 100% original (as possible)
# 1 = Runtime QOL (no cd checks, windowed mode, etc.)
target_compile_definitions(${TARGET} PRIVATE
RE_AUTHENTIC=1
)
if(DBG_MODE)
target_sources(${TARGET} PRIVATE
r3/binders/dbg_mem.cxx
)
target_compile_definitions(game_dbg PRIVATE RE_DBG_INJECTED=1)
# We load the original binary at it's original location, so offset the base address
target_link_options(${TARGET} PRIVATE
-Wl,/BASE:0x20000000
-Wl,/DYNAMICBASE:NO
)
target_link_libraries(${TARGET} PRIVATE
DbgHelp
)
else()
target_sources(${TARGET} PRIVATE
r3/binders/static_mem.cxx
)
endif()
endfunction()
setup_target(game_re)
setup_target(game_dbg)
target_compile_definitions(game_dbg PRIVATE RE_DBG_INJECTED=1)
setup_target(game_re OFF)
setup_target(game_dbg ON)

BIN
game_re/gh_datasegment.bin (Stored with Git LFS)

Binary file not shown.

View File

@ -3,9 +3,9 @@
#pragma once
#include <cstddef>
#define GH_DATA_START 0x00597000
#define GH_DATA_START 0x00400000
#define GH_DATA_END 0x00843fff
#define GH_DATA_SIZE (GH_DATA_END - GH_DATA_START)
constexpr size_t gh_data_start = 0x00597000;
constexpr size_t gh_data_start = 0x00400000;
constexpr size_t gh_data_end = 0x00843fff;
constexpr size_t gh_data_size = gh_data_end - gh_data_start;

89
game_re/gh_fix/entry.cxx Normal file
View File

@ -0,0 +1,89 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <r3/binders/stub.h>
#include <gh_global.h>
#include <spdlog/spdlog.h>
extern "C" {
undefined4 crt_createProgramHeap(undefined4 param_1) {
return gh_stub_impl_cdecl<undefined4>((void *)0x00404902, param_1);
}
undefined4 ioinit(void) {
return gh_stub_impl_cdecl<undefined4>((void *)0x004046bf);
}
void crt_initConsole(void) {
return gh_stub_impl_cdecl<void>((void *)0x00404503);
}
LPSTR crt_setupEnv(void) {
return gh_stub_impl_cdecl<LPSTR>((void *)0x004043d1);
}
undefined4 crt_main2(void) {
return gh_stub_impl_cdecl<undefined4>((void *)0x00404184);
}
undefined4 crt_main1(void) {
return gh_stub_impl_cdecl<undefined4>((void *)0x004040cb);
}
void c_static_init(void) {
return gh_stub_impl_cdecl<void>((void *)0x004027be);
}
char* crt_0(void) {
return gh_stub_impl_cdecl<char*>((void *)0x00404073);
}
void gh_pre_main(void) {
DWORD DVar1;
int iVar2;
LPSTR *cmdline;
uint showCmd;
HMODULE hInstance;
HINSTANCE hPrevInstance;
_STARTUPINFOA local_60;
undefined1 *local_1c;
void *pvStack_14;
undefined1 *puStack_10;
undefined *puStack_c;
undefined4 local_8;
local_8 = 0xffffffff;
// This sets up the unhandled exception handler i think?
// puStack_c = &DAT_00597ca0;
// puStack_10 = &LAB_00404a58;
// pvStack_14 = ExceptionList;
// local_1c = &stack0xffffff88;
// ExceptionList = &pvStack_14;
DVar1 = GetVersion();
DWORD_005cf980 = DVar1 >> 8 & 0xff;
DWORD_005cf97c = DVar1 & 0xff;
DWORD_005cf978 = DWORD_005cf97c * 0x100 + DWORD_005cf980;
DWORD_005cf974 = DVar1 >> 0x10;
iVar2 = crt_createProgramHeap(1);
if (iVar2 == 0) {
SPDLOG_ERROR("crt_createProgramHeap failed");
exit(0);
}
iVar2 = ioinit();
if (iVar2 == 0) {
SPDLOG_ERROR("_ioinit failed");
exit(0);
}
local_8 = 0;
crt_initConsole();
g_crt_cmdLine = GetCommandLineA();
PTR_005cf9b4 = crt_setupEnv();
crt_main2();
crt_main1();
c_static_init();
local_60.dwFlags = 0;
GetStartupInfoA(&local_60);
cmdline = (LPSTR *)crt_0();
if ((local_60.dwFlags & 1) == 0) {
showCmd = 10;
} else {
showCmd = (uint)local_60.wShowWindow;
}
hPrevInstance = (HINSTANCE)0x0;
hInstance = GetModuleHandleA((LPCSTR)0x0);
}
}

628
game_re/gh_fix/r3_main.cxx Normal file
View File

@ -0,0 +1,628 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
int setupWindow(HINSTANCE instance, undefined4 param_2, int windowedParam); // 00402140 // setupWindow
undefined FUN_00470db0(void); // 00470db0 // FUN_00470db0
undefined r3_checkDisc(void); // 004464f0 // r3_checkDisc
undefined FUN_00503710(void); // 00503710 // FUN_00503710
undefined r3_initAllModules(void); // 00401000 // r3_initAllModules
undefined FUN_00472150(void); // 00472150 // FUN_00472150
undefined r3_wait_for_dvd(char * param_1, char * param_2, undefined4 param_3); // 0043e540 // r3_wait_for_dvd
undefined FUN_004725a0(void); // 004725a0 // FUN_004725a0
int r3_get_gli_width1(void); // 0047baf0 // r3_get_gli_width1
undefined gfx_init2(void); // 00470be0 // gfx_init2
void g_setInitVar0(void); // 00401310 // g_setInitVar0
int r3_get_gli_height1(void); // 0047bb00 // r3_get_gli_height1
undefined FUN_004010b0(void); // 004010b0 // FUN_004010b0
undefined FUN_00401320(void); // 00401320 // FUN_00401320
void r3_noop(void * p_cTxt1, void * p_cTxt2); // 00401100 // r3_noop
undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0
undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300
undefined spawnThread(void); // 004477d0 // spawnThread
undefined r3_engineLoop(void); // 00401220 // r3_engineLoop
// 00401630
int r3_main(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR *cmdline,int showCmd)
{
undefined4 uVar1;
undefined2 uVar2;
undefined2 uVar3;
LPSTR pCVar3;
char *pcVar4;
FILE *pFVar5;
LONG LVar6;
HMODULE hLibModule;
DWORD DVar7;
HANDLE hTargetProcessHandle;
HANDLE hSourceHandle;
HANDLE hSourceProcessHandle;
uint *ppCVar8;
HWND hWnd;
int iVar10;
int iVar11;
int iVar12;
int iVar13;
uint uVar14;
HKEY unaff_ESI;
char *pcVar17;
void *p_cTxt1;
void *p_cTxt2;
undefined4 uStack_85c;
undefined4 uStack_858;
LPSTR lpBuffer;
UINT uiParam;
BYTE uStack_83c [4];
DWORD pHStack_838;
DWORD pvStack_834;
char UStack_830 [16];
char tStack_820 [260];
CHAR aCStack_71c [256];
char acStack_61c [16];
CHAR pathToUbi_ini [228];
char acStack_528 [16];
char acStack_518 [244];
char acStack_424 [16];
CHAR aCStack_414 [244];
char acStack_320 [16];
char acStack_310 [240];
char acStack_220 [256];
char acStack_120 [260];
HINSTANCE instance;
uint *puStack_14;
undefined4 uStack_10;
int iStack_8;
BOOL BVar18;
char cVar1;
undefined4 chars;
DWORD dwOptions;
LPRECT lpRect;
LPHANDLE lpTargetHandle;
undefined4 uVar22;
#if RE_AUTHENTIC == 0
lpBuffer = pathToUbi_ini;
uiParam = 0x104;
/* Append windows dir / ubi.ini */
uStack_858 = 0x40164d;
GetWindowsDirectoryA(lpBuffer,0x104);
iVar13 = -1;
pcVar4 = acStack_61c;
do {
pcVar17 = pcVar4;
if (iVar13 == 0) break;
iVar13 = iVar13 + -1;
pcVar17 = pcVar4 + 1;
cVar1 = *pcVar4;
pcVar4 = pcVar17;
} while (cVar1 != '\0');
*(undefined4 *)(pcVar17 + -1) = s_UbiSoft_Ubi_ini + Field<0, 4>();
*(undefined4 *)(pcVar17 + 3) = s_UbiSoft_Ubi_ini + Field<4, 4>();
*(undefined4 *)(pcVar17 + 7) = s_UbiSoft_Ubi_ini + Field<8, 4>();
*(undefined4 *)(pcVar17 + 0xb) = s_UbiSoft_Ubi_ini + Field<12, 4>();
pcVar17[0xf] = s_UbiSoft_Ubi_ini[0x10];
pCVar3 = GetCommandLineA();
pcVar4 = pCVar3 + 1;
iVar13 = -(int)pcVar4;
do {
cVar1 = *pcVar4;
pcVar4[(int)(tStack_820 + iVar13)] = cVar1;
pcVar4 = pcVar4 + 1;
} while (cVar1 != '\0');
pcVar4 = strrchr(tStack_820,0x5c); // Get the exe path
if (pcVar4 == (char *)0x0) {
/* Read from ubi.ini */
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Directory_005b68f8,s_None,tStack_820,0xff,acStack_61c);
iVar13 = strcmpi(tStack_820,s_None);
}
else { // We have the .exe path
pcVar4 = strrchr(tStack_820,0x5c);
*pcVar4 = '\0'; // Split into the binary path (strip .exe)
iVar13 = chdir(tStack_820); // Change into the binary path
if (iVar13 != -1) goto LAB_00401765;
/* Read from ubi.ini */
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Directory_005b68f8,s_None,tStack_820,0xff,acStack_61c);
iVar13 = strcmpi(tStack_820,s_None);
}
if (iVar13 != 0) {
chdir(tStack_820);
}
LAB_00401765:
/* strcpy */
iVar13 = 0;
do {
cVar1 = tStack_820[iVar13];
r3_main_data_005d28b6.gameDataDir[iVar13] = cVar1;
iVar13 = iVar13 + 1;
} while (cVar1 != '\0');
strlwr(r3_main_data_005d28b6.gameDataDir);
iVar13 = -1;
pcVar4 = r3_main_data_005d28b6.gameDataDir;
do {
if (iVar13 == 0) break;
iVar13 = iVar13 + -1;
cVar1 = *pcVar4;
pcVar4 = pcVar4 + 1;
} while (cVar1 != '\0');
joined_r0x00401792:
if (iVar13 != -2) {
uVar14 = 0xffffffff;
pcVar4 = r3_main_data_005d28b6.gameDataDir;
do {
if (uVar14 == 0) break;
uVar14 = uVar14 - 1;
cVar1 = *pcVar4;
pcVar4 = pcVar4 + 1;
} while (cVar1 != '\0');
if (r3_main_data_005d28b6.gameDataDir[~uVar14 - 2] != '\\') goto LAB_004017ce;
uVar14 = 0xffffffff;
pcVar4 = r3_main_data_005d28b6.gameDataDir;
do {
if (uVar14 == 0) break;
uVar14 = uVar14 - 1;
cVar1 = *pcVar4;
pcVar4 = pcVar4 + 1;
} while (cVar1 != '\0');
r3_main_data_005d28b6.gameDataDir[~uVar14 - 2] = '\0';
iVar13 = -1;
pcVar4 = r3_main_data_005d28b6.gameDataDir;
do {
if (iVar13 == 0) break;
iVar13 = iVar13 + -1;
cVar1 = *pcVar4;
pcVar4 = pcVar4 + 1;
} while (cVar1 != '\0');
goto joined_r0x00401792;
}
LAB_004017ce:
pFVar5 = fopen(acStack_61c,fopen_mode_r_text);
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Adapter_005b68e4,(LPCSTR)&lpDefault_005cf96c,acStack_310,0xff,
acStack_61c);
if ((pFVar5 == (FILE *)0x0) || (acStack_310[0] == '\0')) {
/* Concat game data dir with r3 setup exe */
iVar13 = 0;
do {
cVar1 = r3_main_data_005d28b6.gameDataDir[iVar13];
acStack_518[iVar13] = cVar1;
iVar13 = iVar13 + 1;
} while (cVar1 != '\0');
iVar13 = -1;
pcVar4 = acStack_518;
do {
pcVar17 = pcVar4;
if (iVar13 == 0) break;
iVar13 = iVar13 + -1;
pcVar17 = pcVar4 + 1;
cVar1 = *pcVar4;
pcVar4 = pcVar17;
} while (cVar1 != '\0');
*(undefined4 *)(pcVar17 + -1) = s__R3_Setup_DX8_exe_005b68d0 + Field<0, 4>();
*(undefined4 *)(pcVar17 + 3) = s__R3_Setup_DX8_exe_005b68d0 + Field<4, 4>();
*(undefined4 *)(pcVar17 + 7) = s__R3_Setup_DX8_exe_005b68d0 + Field<8, 4>();
*(undefined4 *)(pcVar17 + 0xb) = s__R3_Setup_DX8_exe_005b68d0 + Field<12, 4>();
*(undefined2 *)(pcVar17 + 0xf) = s__R3_Setup_DX8_exe_005b68d0 + Field<16, 2>();
pFVar5 = fopen(acStack_518,fopen_mode_r_binary);
if (pFVar5 == (FILE *)0x0) {
MessageBoxA((HWND)0x0,s_Unable_to_find_R3_Setup_DX8_exe__005b6880,s_Rayman_3_Error_005b68bc,
0x10);
return -1;
}
fclose(pFVar5);
spawnl(0,acStack_518,acStack_518,0);
pFVar5 = fopen(acStack_61c,fopen_mode_r_text);
if (pFVar5 == (FILE *)0x0) {
return -1;
}
}
fclose(pFVar5);
/* Open reg key
HKEY_LOCAL_MACHINE\\SOFTWARE\\UBI SOFT\\RAYMAN 3 */
HKEY key;
LVar6 = RegOpenKeyExA(HKEY_LOCAL_MACHINE,s_SOFTWARE_UBI_SOFT_RAYMAN_3_005b6864,0,0x20019,
&key);
if (LVar6 == 0) {
LVar6 = RegQueryValueExA(key,s_CompleteInstall_005b6854,(LPDWORD)0x0,&pvStack_834,
uStack_83c,&pHStack_838);
DAT_007d9cc4 = (uint)(LVar6 == 0);
if (key != (HKEY)0x0) {
RegCloseKey(key);
}
}
else {
DAT_007d9cc4 = 0;
}
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Language_005b6840,s_English_005b684c,aCStack_71c,0xff,acStack_61c)
;
sprintf(g_mutexName_Rayman3,s_percents,lpAppName_005b68f0);
sprintf(g_windowTitle,s_percents,s_windowTitle);
/* Setup localized quiting/restoring strings */
iVar13 = strcmpi(aCStack_71c,s_French_005b6828);
if (iVar13 == 0) {
sprintf(g_windowTitleRestoring,s_Restauration_fmt,s_windowTitle);
chars = s_QUITTER + Field<4, 4>();
pcVar4 = s_ou_appuyez_sur_Echap_pour_quitte_005b67d0;
pcVar17 = s_quitting1;
for (iVar13 = 0xb; uVar22 = s_QUITTER + Field<4, 4>(), iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
s_wndStrQuiting[0] = s_QUITTER[0];
s_wndStrQuiting[1] = s_QUITTER[1];
s_wndStrQuiting[2] = s_QUITTER[2];
s_wndStrQuiting[3] = s_QUITTER[3];
/* Wrong decompilation? */
s_QUITTER[4] = (char)chars;
s_QUITTER[5] = SUB41(chars,1);
s_QUITTER[6] = SUB41(chars,2);
s_QUITTER[7] = SUB41(chars,3);
s_wndStrQuiting[4] = s_QUITTER[4];
s_wndStrQuiting[5] = s_QUITTER[5];
s_wndStrQuiting[6] = s_QUITTER[6];
s_wndStrQuiting[7] = s_QUITTER[7];
s_QUITTER + Field<4, 4>() = uVar22;
sprintf(g_windowTitle1,s__s___Pause_005b67c4,s_windowTitle);
pcVar4 = s_Restauration;
pcVar17 = s_wndStrRestoring;
for (iVar13 = 7; iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
}
else {
iVar13 = strcmpi(aCStack_71c,s_Spanish_005b67a0);
if (iVar13 == 0) {
sprintf(g_windowTitleRestoring,s__s___Restablecer_datos____005b6784,s_windowTitle);
uVar2 = s_SALIR_005b675c + Field<4, 2>();
pcVar4 = s_Pulsa_ESC_para_salir_Rayman_3__005b6764;
pcVar17 = s_quitting1;
for (iVar13 = 7; chars = s_SALIR_005b675c + Field<0, 4>(), iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
*(undefined2 *)pcVar17 = *(undefined2 *)pcVar4;
pcVar17[2] = pcVar4[2];
uVar3 = s_SALIR_005b675c + Field<4, 2>();
uVar22 = s_SALIR_005b675c + Field<0, 4>();
s_SALIR_005b675c[0] = (char)chars;
s_SALIR_005b675c[1] = SUB41(chars,1);
s_SALIR_005b675c[2] = SUB41(chars,2);
s_SALIR_005b675c[3] = SUB41(chars,3);
s_wndStrQuiting[0] = s_SALIR_005b675c[0];
s_wndStrQuiting[1] = s_SALIR_005b675c[1];
s_wndStrQuiting[2] = s_SALIR_005b675c[2];
s_wndStrQuiting[3] = s_SALIR_005b675c[3];
s_SALIR_005b675c[4] = (char)uVar2;
s_SALIR_005b675c[5] = SUB21(uVar2,1);
s_wndStrQuiting[4] = s_SALIR_005b675c[4];
s_wndStrQuiting[5] = s_SALIR_005b675c[5];
s_SALIR_005b675c + Field<0, 4>() = uVar22;
s_SALIR_005b675c + Field<4, 2>() = uVar3;
sprintf(g_windowTitle1,s__s___Rotura_005b6750,s_windowTitle);
pcVar4 = s_Restablecer_datos____005b6738;
pcVar17 = s_wndStrRestoring;
for (iVar13 = 5; iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
*pcVar17 = *pcVar4;
}
else {
iVar13 = strcmpi(aCStack_71c,s_Italian_005b6730);
if (iVar13 == 0) {
sprintf(g_windowTitleRestoring,s__s___Ripristino_dati____005b6718,s_windowTitle);
uVar2 = s_USCIRE_005b66ec + Field<4, 2>();
pcVar4 = s_Premi_ESC_per_uscire_da_Rayman_3_005b66f4;
pcVar17 = s_quitting1;
for (iVar13 = 8; cVar1 = s_USCIRE_005b66ec[6], iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
s_wndStrQuiting[0] = s_USCIRE_005b66ec[0];
s_wndStrQuiting[1] = s_USCIRE_005b66ec[1];
s_wndStrQuiting[2] = s_USCIRE_005b66ec[2];
s_wndStrQuiting[3] = s_USCIRE_005b66ec[3];
*(undefined2 *)pcVar17 = *(undefined2 *)pcVar4;
uVar3 = s_USCIRE_005b66ec + Field<4, 2>();
s_wndStrQuiting[6] = cVar1;
s_USCIRE_005b66ec[4] = (char)uVar2;
s_USCIRE_005b66ec[5] = SUB21(uVar2,1);
s_wndStrQuiting[4] = s_USCIRE_005b66ec[4];
s_wndStrQuiting[5] = s_USCIRE_005b66ec[5];
s_USCIRE_005b66ec + Field<4, 2>() = uVar3;
sprintf(g_windowTitle1,s__s___Pausa_005b66e0,s_windowTitle);
s_wndStrRestoring[0] = s_Ripristino_dati____005b66cc[0];
s_wndStrRestoring[1] = s_Ripristino_dati____005b66cc[1];
s_wndStrRestoring[2] = s_Ripristino_dati____005b66cc[2];
s_wndStrRestoring[3] = s_Ripristino_dati____005b66cc[3];
s_wndStrRestoring[4] = s_Ripristino_dati____005b66cc[4];
s_wndStrRestoring[5] = s_Ripristino_dati____005b66cc[5];
s_wndStrRestoring[6] = s_Ripristino_dati____005b66cc[6];
s_wndStrRestoring[7] = s_Ripristino_dati____005b66cc[7];
s_wndStrRestoring[8] = s_Ripristino_dati____005b66cc[8];
s_wndStrRestoring[9] = s_Ripristino_dati____005b66cc[9];
s_wndStrRestoring[10] = s_Ripristino_dati____005b66cc[10];
s_wndStrRestoring[0xb] = s_Ripristino_dati____005b66cc[0xb];
s_wndStrRestoring + Field<12, 4>() = s_Ripristino_dati____005b66cc + Field<12, 4>();
s_wndStrRestoring + Field<16, 2>() = s_Ripristino_dati____005b66cc + Field<16, 2>();
s_wndStrRestoring[0x12] = s_Ripristino_dati____005b66cc[0x12];
}
else {
iVar13 = strcmpi(aCStack_71c,s_German_005b66c4);
if (iVar13 == 0) {
sprintf(g_windowTitleRestoring,s__s___Daten_Reparatur____005b66ac,s_windowTitle);
chars = s_BEENDIGEN_005b6678 + Field<0, 4>();
pcVar4 = &CHAR_E_005b6684;
pcVar17 = s_quitting1;
for (iVar13 = 9; uVar2 = s_BEENDIGEN_005b6678 + Field<8, 2>(), uVar22 = s_BEENDIGEN_005b6678 + Field<4, 4>(),
iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
*(undefined2 *)pcVar17 = *(undefined2 *)pcVar4;
uVar1 = s_BEENDIGEN_005b6678 + Field<0, 4>();
s_BEENDIGEN_005b6678[0] = (char)chars;
s_BEENDIGEN_005b6678[1] = SUB41(chars,1);
s_BEENDIGEN_005b6678[2] = SUB41(chars,2);
s_BEENDIGEN_005b6678[3] = SUB41(chars,3);
s_wndStrQuiting[0] = s_BEENDIGEN_005b6678[0];
s_wndStrQuiting[1] = s_BEENDIGEN_005b6678[1];
s_wndStrQuiting[2] = s_BEENDIGEN_005b6678[2];
s_wndStrQuiting[3] = s_BEENDIGEN_005b6678[3];
s_BEENDIGEN_005b6678 + Field<0, 4>() = uVar1;
pcVar17[2] = pcVar4[2];
uVar3 = s_BEENDIGEN_005b6678 + Field<8, 2>();
chars = s_BEENDIGEN_005b6678 + Field<4, 4>();
s_BEENDIGEN_005b6678[4] = (char)uVar22;
s_BEENDIGEN_005b6678[5] = SUB41(uVar22,1);
s_BEENDIGEN_005b6678[6] = SUB41(uVar22,2);
s_BEENDIGEN_005b6678[7] = SUB41(uVar22,3);
s_wndStrQuiting[4] = s_BEENDIGEN_005b6678[4];
s_wndStrQuiting[5] = s_BEENDIGEN_005b6678[5];
s_wndStrQuiting[6] = s_BEENDIGEN_005b6678[6];
s_wndStrQuiting[7] = s_BEENDIGEN_005b6678[7];
s_BEENDIGEN_005b6678[8] = (char)uVar2;
s_BEENDIGEN_005b6678[9] = SUB21(uVar2,1);
s_wndStrQuiting[8] = s_BEENDIGEN_005b6678[8];
s_wndStrQuiting[9] = s_BEENDIGEN_005b6678[9];
s_BEENDIGEN_005b6678 + Field<4, 4>() = chars;
s_BEENDIGEN_005b6678 + Field<8, 2>() = uVar3;
sprintf(g_windowTitle1,s__s___Pause_005b67c4,s_windowTitle);
s_wndStrRestoring[0] = s_Daten_Reparatur____005b6664[0];
s_wndStrRestoring[1] = s_Daten_Reparatur____005b6664[1];
s_wndStrRestoring[2] = s_Daten_Reparatur____005b6664[2];
s_wndStrRestoring[3] = s_Daten_Reparatur____005b6664[3];
s_wndStrRestoring[4] = s_Daten_Reparatur____005b6664[4];
s_wndStrRestoring[5] = s_Daten_Reparatur____005b6664[5];
s_wndStrRestoring[6] = s_Daten_Reparatur____005b6664[6];
s_wndStrRestoring[7] = s_Daten_Reparatur____005b6664[7];
s_wndStrRestoring[8] = s_Daten_Reparatur____005b6664[8];
s_wndStrRestoring[9] = s_Daten_Reparatur____005b6664[9];
s_wndStrRestoring[10] = s_Daten_Reparatur____005b6664[10];
s_wndStrRestoring[0xb] = s_Daten_Reparatur____005b6664[0xb];
s_wndStrRestoring[0xc] = s_Daten_Reparatur____005b6664[0xc];
s_wndStrRestoring[0xd] = s_Daten_Reparatur____005b6664[0xd];
s_wndStrRestoring[0xe] = s_Daten_Reparatur____005b6664[0xe];
s_wndStrRestoring[0xf] = s_Daten_Reparatur____005b6664[0xf];
s_wndStrRestoring[0x10] = s_Daten_Reparatur____005b6664[0x10];
s_wndStrRestoring[0x11] = s_Daten_Reparatur____005b6664[0x11];
s_wndStrRestoring[0x12] = s_Daten_Reparatur____005b6664[0x12];
}
else {
sprintf(g_windowTitleRestoring,s__s___Restoring_data____005b664c,s_windowTitle);
chars = s_QUIT + Field<0, 4>();
pcVar4 = s_or_press_ESC_to_quit_Rayman_3__005b662c;
pcVar17 = s_quitting1;
for (iVar13 = 7; cVar1 = s_QUIT[4], iVar13 != 0; iVar13 = iVar13 + -1) {
*(undefined4 *)pcVar17 = *(undefined4 *)pcVar4;
pcVar4 = pcVar4 + 4;
pcVar17 = pcVar17 + 4;
}
*(undefined2 *)pcVar17 = *(undefined2 *)pcVar4;
pcVar17[2] = pcVar4[2];
uVar22 = s_QUIT + Field<0, 4>();
s_QUIT[0] = (char)chars;
s_QUIT[1] = SUB41(chars,1);
s_QUIT[2] = SUB41(chars,2);
s_QUIT[3] = SUB41(chars,3);
s_wndStrQuiting[0] = s_QUIT[0];
s_wndStrQuiting[1] = s_QUIT[1];
s_wndStrQuiting[2] = s_QUIT[2];
s_wndStrQuiting[3] = s_QUIT[3];
s_wndStrQuiting[4] = cVar1;
s_QUIT + Field<0, 4>() = uVar22;
sprintf(g_windowTitle1,s__s___Pause_005b67c4,s_windowTitle);
s_wndStrRestoring[0] = s_Restoring_data_____005b6610[0];
s_wndStrRestoring[1] = s_Restoring_data_____005b6610[1];
s_wndStrRestoring[2] = s_Restoring_data_____005b6610[2];
s_wndStrRestoring[3] = s_Restoring_data_____005b6610[3];
s_wndStrRestoring[4] = s_Restoring_data_____005b6610[4];
s_wndStrRestoring[5] = s_Restoring_data_____005b6610[5];
s_wndStrRestoring[6] = s_Restoring_data_____005b6610[6];
s_wndStrRestoring[7] = s_Restoring_data_____005b6610[7];
s_wndStrRestoring[8] = s_Restoring_data_____005b6610[8];
s_wndStrRestoring[9] = s_Restoring_data_____005b6610[9];
s_wndStrRestoring[10] = s_Restoring_data_____005b6610[10];
s_wndStrRestoring[0xb] = s_Restoring_data_____005b6610[0xb];
s_wndStrRestoring + Field<12, 4>() = s_Restoring_data_____005b6610 + Field<12, 4>();
s_wndStrRestoring + Field<16, 2>() = s_Restoring_data_____005b6610 + Field<16, 2>();
s_wndStrRestoring[0x12] = s_Restoring_data_____005b6610[0x12];
}
}
}
}
#else
strcpy(g_windowTitle, "Reman3");
strcpy(g_windowTitle1, "Reman3 - Paused");
strcpy(g_windowTitleRestoring, "Restoring data");
#endif
/* Create draw semaphore
Initial count = 1
Maximum count = 1 */
g_drawSemaphore = CreateSemaphoreA((LPSECURITY_ATTRIBUTES)0x0,1,1,s_DRAWSEM_005b6608);
if (iStack_8 != 0) {
return -1;
}
/* Load DirectPlay probably unused */
hLibModule = LoadLibraryA(s_dpnhpast_dll_005b65f8);
if (hLibModule == (HMODULE)0x0) {
iVar13 = strcmpi(aCStack_71c,s_French_005b6828);
if (iVar13 == 0) {
MessageBoxA((HWND)0x0,lpText_005b6598,s_Erreur_Rayman_3_005b65e4,0x10);
return -1;
}
iVar13 = strcmpi(aCStack_71c,s_Spanish_005b67a0);
if (iVar13 == 0) {
MessageBoxA((HWND)0x0,lpText_005b6540,s_Rayman_3_005b6588,0x10);
return -1;
}
iVar13 = strcmpi(aCStack_71c,s_Italian_005b6730);
if (iVar13 == 0) {
MessageBoxA((HWND)0x0,lpText_005b64f0,s_Rayman_3_005b6588,0x10);
return -1;
}
iVar13 = strcmpi(aCStack_71c,s_German_005b66c4);
if (iVar13 != 0) {
MessageBoxA((HWND)0x0,s_Check_your_version_of_DirectX__V_005b6430,s_Rayman_3_Error_005b68bc,
0x10);
return -1;
}
MessageBoxA((HWND)0x0,lpText_005b6478,s_Rayman_3_005b6588,0x10);
return -1;
}
FreeLibrary(hLibModule);
p_cTxt1 = (void *)0x401e2a;
CreateMutexA((LPSECURITY_ATTRIBUTES)0x0,1,g_mutexName_Rayman3);
DVar7 = GetLastError();
if (DVar7 == 0xb7) {
/* Mutex already exists */
return -1;
}
p_cTxt2 = (void *)0x401e5a;
GetWindowsDirectoryA(aCStack_414,0x104);
iVar13 = -1;
/* Append ubi.ini */
pcVar4 = acStack_424;
do {
pcVar17 = pcVar4;
if (iVar13 == 0) break;
iVar13 = iVar13 + -1;
pcVar17 = pcVar4 + 1;
cVar1 = *pcVar4;
pcVar4 = pcVar17;
} while (cVar1 != '\0');
*(undefined4 *)(pcVar17 + -1) = s_UbiSoft_Ubi_ini + Field<0, 4>();
*(undefined4 *)(pcVar17 + 3) = s_UbiSoft_Ubi_ini + Field<4, 4>();
*(undefined4 *)(pcVar17 + 7) = s_UbiSoft_Ubi_ini + Field<8, 4>();
*(undefined4 *)(pcVar17 + 0xb) = s_UbiSoft_Ubi_ini + Field<12, 4>();
pcVar17[0xf] = s_UbiSoft_Ubi_ini[0x10];
/* Read graphics settings */
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Adapter_005b68e4,(LPCSTR)&lpDefault_005cf96c,acStack_320,0xff,
acStack_424);
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Identifier_005b6420,(LPCSTR)&lpDefault_005cf96c,acStack_120,0xff,
acStack_424);
GetPrivateProfileStringA
(lpAppName_005b68f0,s_Gli_Mode_005b6414,(LPCSTR)&lpDefault_005cf96c,acStack_220,0xff,
acStack_424);
/* If they're all set */
if (((acStack_320[0] != '\0') && (acStack_120[0] != '\0')) && (acStack_220[0] != '\0')) {
/* For GLIMode
1 = maximize
0 = windowed */
g_runMaximized = (int)(acStack_220[0] != '0');
r3_checkDisc();
dwOptions = 0;
BVar18 = 0;
HANDLE duplicatedHandle;
DVar7 = 0x1f03ff;
g_hinstance = instance;
hTargetProcessHandle = GetCurrentProcess();
hSourceHandle = GetCurrentThread();
hSourceProcessHandle = GetCurrentProcess();
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 */
SetErrorMode(1);
pcVar4 = strstr(cmdline, s_dashCC);
if (pcVar4 == (char *)0x0) {
r3_initAllModules();
iVar13 = setupWindow(instance,uStack_10,g_runMaximized);
if (iVar13 == 0) {
return -1;
}
g_setInitVar0();
FUN_00401320();
spawnThread();
r3_noop(p_cTxt1,p_cTxt2);
gfx_init2();
RECT rect;
hWnd = GetDesktopWindow();
GetWindowRect(hWnd,&rect);
BVar18 = 1;
iVar13 = r3_get_gli_height1();
iVar13 = iVar13 + 0x20;
iVar10 = r3_get_gli_width1();
iVar10 = iVar10 + 0xc;
iVar11 = r3_get_gli_height1();
iVar11 = (int)(rect.top - iVar11) / 2;
iVar12 = r3_get_gli_width1();
MoveWindow(g_gameHWND,(int)(rect.right - iVar12) / 2,iVar11,iVar10,iVar13,BVar18);
FUN_004010b0();
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);
g_engineRunning = 1;
r3_engineLoop();
/* cleanup starts here */
FUN_004725a0();
FUN_005038e0();
FUN_00503710();
FUN_004fb300();
FUN_00472150();
FUN_00470db0();
uStack_85c = 0;
SystemParametersInfoA(0x61,0,&uStack_85c,0);
ShowCursor(1);
SystemParametersInfoA(0x11,uiParam,(PVOID)0x0,0);
CloseHandle(lpBuffer);
}
return 0;
}
sprintf(UStack_830,s_Please_run_the__s_setup__005b63f4,s_windowTitle);
sprintf(acStack_528,s__s_not_initialized__005b63e0,s_windowTitle);
r3_wait_for_dvd(UStack_830,acStack_528,0);
/* WARNING: Subroutine does not return */
exit(-1);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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>
// 004010b0
// FUN_004010b0
extern "C" undefined FUN_004010b0(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x004010b0);
}

View File

@ -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>
// 00401320
// FUN_00401320
extern "C" undefined FUN_00401320(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00401320);
}

View File

@ -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>
// 00470db0
// FUN_00470db0
extern "C" undefined FUN_00470db0(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00470db0);
}

View File

@ -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>
// 00472150
// FUN_00472150
extern "C" undefined FUN_00472150(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00472150);
}

View File

@ -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>
// 004725a0
// FUN_004725a0
extern "C" undefined FUN_004725a0(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x004725a0);
}

View File

@ -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>
// 004fb300
// FUN_004fb300
extern "C" undefined FUN_004fb300(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x004fb300);
}

View File

@ -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>
// 00503710
// FUN_00503710
extern "C" undefined FUN_00503710(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00503710);
}

View File

@ -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>
// 005038e0
// FUN_005038e0
extern "C" undefined FUN_005038e0(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x005038e0);
}

View File

@ -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>
// 00401310
// g_setInitVar0
extern "C" void g_setInitVar0(void) {
gh_stub_impl_stdcall<void>((void*)0x00401310);
}

View File

@ -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>
// 00470be0
// gfx_init2
extern "C" undefined gfx_init2(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00470be0);
}

View File

@ -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>
// 004464f0
// r3_checkDisc
extern "C" undefined r3_checkDisc(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x004464f0);
}

View File

@ -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>
// 00401220
// r3_engineLoop
extern "C" undefined r3_engineLoop(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00401220);
}

View File

@ -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>
// 0047bb00
// r3_get_gli_height1
extern "C" int r3_get_gli_height1(void) {
return gh_stub_impl_stdcall<int>((void*)0x0047bb00);
}

View File

@ -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>
// 0047baf0
// r3_get_gli_width1
extern "C" int r3_get_gli_width1(void) {
return gh_stub_impl_stdcall<int>((void*)0x0047baf0);
}

View File

@ -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>
// 00401000
// r3_initAllModules
extern "C" undefined r3_initAllModules(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x00401000);
}

View File

@ -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>
// 00401100
// r3_noop
extern "C" void r3_noop(void * p_cTxt1, void * p_cTxt2) {
gh_stub_impl_stdcall<void>((void*)0x00401100, p_cTxt1, p_cTxt2);
}

View File

@ -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>
// 0043e540
// r3_wait_for_dvd
extern "C" undefined r3_wait_for_dvd(char * param_1, char * param_2, undefined4 param_3) {
return gh_stub_impl_cdecl<undefined>((void*)0x0043e540, param_1, param_2, param_3);
}

View File

@ -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>
// 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);
}

View File

@ -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>
// 004477d0
// spawnThread
extern "C" undefined spawnThread(void) {
return gh_stub_impl_cdecl<undefined>((void*)0x004477d0);
}

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,12 @@
#ifndef B8D59B54_1674_4C0F_AA2C_611385FF5D03
#define B8D59B54_1674_4C0F_AA2C_611385FF5D03
#if RE_DBG_INJECTED
#include "dbg_mem.h"
#else
#include "static_mem.h"
#endif
#include "base.h"
#include <gh_types.h>
@ -108,6 +113,6 @@ inline longlong r3_ftol(float a) { return (longlong)a; }
constexpr byte R3ModId_not_initialized = 0xff;
#include "stubexcept.h"
#include "stub.h"
#endif /* B8D59B54_1674_4C0F_AA2C_611385FF5D03 */

View File

@ -6,6 +6,7 @@
#if _WIN32
#include <Windows.h>
#include <d3d8.h>
#include <dinput.h>
#else
#include "win32_shim.h"
#endif
@ -19,6 +20,10 @@ typedef uint32_t undefined4;
typedef uint16_t undefined2;
typedef uint16_t word;
typedef uint32_t dword;
typedef unsigned long ulong;
typedef unsigned char uchar;
typedef unsigned long uint;
struct undefined3 {
uint8_t _0;
uint8_t _1;

View File

@ -0,0 +1,147 @@
#include "r3/config/static.hpp"
#include <spdlog/spdlog.h>
#include <windows.h>
#include <DbgHelp.h>
#define GH_BASE_ADDR 0x00400000
static uintptr_t g_gh_translationOffset{};
struct R3Bin {
R3Bin() { loadOriginal(); }
void loadOriginal() {
SPDLOG_DEBUG("Loading original binary");
auto &config = getDefaultConfig();
std::string path = config.gameRootDir + "/Rayman3.exe";
module = LoadLibraryA(path.c_str());
if (!module)
throw std::runtime_error("Failed to load original binary");
fixupImports(module);
g_gh_translationOffset = translationOffset =
uintptr_t(module) - GH_BASE_ADDR;
}
// Translate address relative from the original image base address
void *translateAddress(void *original) {
uint8_t *runtime_addr =
reinterpret_cast<uint8_t *>(original) + translationOffset;
return reinterpret_cast<void *>(runtime_addr);
}
void fixupImports(HINSTANCE h) {
// Find the IAT size
DWORD ulsize = 0;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
h, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulsize);
if (!pImportDesc)
return;
// Loop names
for (; pImportDesc->Name; pImportDesc++) {
PSTR pszModName = (PSTR)((PBYTE)h + pImportDesc->Name);
if (!pszModName)
break;
HINSTANCE hImportDLL = LoadLibraryA(pszModName);
if (!hImportDLL) {
// ... (error)
}
// Get caller's import address table (IAT) for the callee's functions
PIMAGE_THUNK_DATA pThunk =
(PIMAGE_THUNK_DATA)((PBYTE)h + pImportDesc->FirstThunk);
// Replace current function address with new function address
for (; pThunk->u1.Function; pThunk++) {
FARPROC pfnNew = 0;
size_t rva = 0;
#ifdef _WIN64
if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
#else
if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
#endif
{
// Ordinal
#ifdef _WIN64
size_t ord = IMAGE_ORDINAL64(pThunk->u1.Ordinal);
#else
size_t ord = IMAGE_ORDINAL32(pThunk->u1.Ordinal);
#endif
PROC *ppfn = (PROC *)&pThunk->u1.Function;
if (!ppfn) {
// ... (error)
}
rva = (size_t)pThunk;
char fe[100] = {0};
sprintf_s(fe, 100, "#%u", ord);
pfnNew = GetProcAddress(hImportDLL, (LPCSTR)ord);
if (!pfnNew) {
// ... (error)
}
} else {
// Get the address of the function address
PROC *ppfn = (PROC *)&pThunk->u1.Function;
if (!ppfn) {
// ... (error)
}
rva = (size_t)pThunk;
PSTR fName = (PSTR)h;
fName += pThunk->u1.Function;
fName += 2;
if (!fName)
break;
pfnNew = GetProcAddress(hImportDLL, fName);
if (!pfnNew) {
// ... (error)
}
}
// Patch it now...
auto hp = GetCurrentProcess();
if (!WriteProcessMemory(hp, (LPVOID *)rva, &pfnNew, sizeof(pfnNew),
NULL) &&
(ERROR_NOACCESS == GetLastError())) {
DWORD dwOldProtect;
if (VirtualProtect((LPVOID)rva, sizeof(pfnNew), PAGE_WRITECOPY,
&dwOldProtect)) {
if (!WriteProcessMemory(GetCurrentProcess(), (LPVOID *)rva, &pfnNew,
sizeof(pfnNew), NULL)) {
// ... (error)
}
if (!VirtualProtect((LPVOID)rva, sizeof(pfnNew), dwOldProtect,
&dwOldProtect)) {
// ... (error)
}
}
}
}
}
}
HINSTANCE module;
uintptr_t translationOffset;
static R3Bin &get() {
static R3Bin instance;
return instance;
}
};
uint8_t *gh_map_dbg_mem(size_t addr) {
R3Bin::get();
SPDLOG_DEBUG("Mapping debug memory at {}", addr);
return (uint8_t *)R3Bin::get().translateAddress((void *)addr);
}
void *gh_stub_impl_ptr(void *ptr) {
R3Bin::get();
SPDLOG_DEBUG("Forwarding implementation at {}", ptr);
return (void *)R3Bin::get().translateAddress((void *)ptr);
}
void gh_init_dbg_loader() { R3Bin::get(); }

View File

@ -0,0 +1,17 @@
#ifndef BD364AE6_AD96_4DEA_9D6B_B237BC1E2C6A
#define BD364AE6_AD96_4DEA_9D6B_B237BC1E2C6A
#include <cstdint>
#include <gh_datasegment.h>
template <size_t addr> inline constexpr void checkMappedMemory() {
static_assert(addr >= GH_DATA_START, "Address outside lower bound");
static_assert(addr < GH_DATA_END, "Address outside upper bound");
}
uint8_t *gh_map_dbg_mem(size_t addr);
void gh_init_dbg_loader();
#define GH_MEM(addr) (checkMappedMemory<addr>(), *gh_map_dbg_mem(addr))
#endif /* BD364AE6_AD96_4DEA_9D6B_B237BC1E2C6A */

View File

@ -4,7 +4,13 @@
#define EDBE48FC_B879_4985_9274_B7ACF24AD024
#include "base.h"
#if RE_DBG_INJECTED
#include "dbg_mem.h"
#else
#include "static_mem.h"
#endif
#include <gh_types.h>
#endif /* EDBE48FC_B879_4985_9274_B7ACF24AD024 */

View File

@ -0,0 +1,5 @@
#include <spdlog/spdlog.h>
GHStubException::GHStubException(const char *msg) : std::exception(msg) {
SPDLOG_ERROR("{}", msg);
}

34
game_re/r3/binders/stub.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef AE625BF8_B0F9_452E_8772_8819F311CB57
#define AE625BF8_B0F9_452E_8772_8819F311CB57
#include <stdexcept>
struct GHStubException : public std::exception {
GHStubException(const char *msg);
};
void *gh_stub_impl_ptr(void *ptr);
template <typename T, typename... Args>
T gh_stub_impl_cdecl(void *ptr_, Args... args) {
#if RE_DBG_INJECTED
using Callable = __cdecl T (*)(Args...);
static Callable fn = (Callable)gh_stub_impl_ptr(ptr_);
return fn(args...);
#else
throw GHStubException("Function not implemented");
#endif
}
template <typename T, typename... Args>
T gh_stub_impl_stdcall(void *ptr_, Args... args) {
#if RE_DBG_INJECTED
using Callable = __stdcall T (*)(Args...);
static Callable fn = (Callable)gh_stub_impl_ptr(ptr_);
return fn(args...);
#else
throw GHStubException("Function not implemented");
#endif
}
#endif /* AE625BF8_B0F9_452E_8772_8819F311CB57 */

View File

@ -1,10 +0,0 @@
#ifndef AE625BF8_B0F9_452E_8772_8819F311CB57
#define AE625BF8_B0F9_452E_8772_8819F311CB57
#include <stdexcept>
struct GHStubException : public std::exception {
GHStubException(const char *msg);
};
#endif /* AE625BF8_B0F9_452E_8772_8819F311CB57 */

View File

@ -2,22 +2,30 @@
#include <spdlog/spdlog.h>
#include <stdexcept>
#include <stdio.h>
#include <r3/binders/static_mem.h>
#include <r3/binders/stubexcept.h>
#include <r3/binders/stub.h>
// Error reporting and such
extern "C" void r3_noop(void*, void*) {}
#if RE_DBG_INJECTED
#include <r3/binders/dbg_mem.h>
extern "C" {
// This is the part of Rayman3.exe main CRT setup that runs before main, but
// doesn't call it
void gh_pre_main(void);
}
#else
#include <r3/binders/static_mem.h>
#endif
extern "C" int r3_main(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR *cmdline, int showCmd);
GHStubException::GHStubException(const char *msg) : std::exception(msg) {
SPDLOG_ERROR("{}", msg);
}
int main(int argc, char **argv) {
try {
#if RE_DBG_INJECTED
gh_init_dbg_loader();
gh_pre_main();
#else
gh_init_data_segment();
#endif
r3_main(GetModuleHandle(NULL), NULL, argv, SW_SHOW);
} catch (const std::exception &e) {

View File

@ -3,20 +3,24 @@ script_dir=$(readlink -f $(dirname "$0"))
tool=$script_dir/../tooling/bin/r3_gh_tool
set -e
shopt -s nullglob
pushd $script_dir
mkdir -p logs
types=(auto ref fix stub)
for type in "${types[@]}"; do
file_list="logs/files_${type}.txt"
rm -f "$file_list"
if [ -d "gh_${type}" ]; then
file_list="logs/files_${type}.txt"
rm -f "$file_list"
any_files=false
for file in "gh_${type}"/*.cxx; do
echo "$file" >>"$file_list"
any_files=true
done
$tool "@$file_list" -v --type=$type --log-file=logs/log-functions-${type}.txt
if [ "$any_files" = true ]; then
$tool "@$file_list" -v --type=$type --log-file=logs/log-functions-${type}.txt
fi
fi
done

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@ dlgs.h
excpt.h
float.h
guiddef.h
Guiddef.h
imm.h
io.h
jmorecfg.h
@ -48,7 +49,6 @@ rpcnsip.h
rpcnterr.h
servprov.h
shellapi.h
snddef.h
stdarg.h
stdint.h
stdio.h
@ -82,4 +82,6 @@ winspool.h
winsvc.h
winuser.h
winver.h
wtypes.h
wtypes.h
dinput.h
lzexpand.h

760
java/ghidra/.classpath Normal file
View File

@ -0,0 +1,760 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="Ghidra 8051 scripts"/>
<classpathentry kind="src" path="Ghidra Atmel scripts"/>
<classpathentry kind="src" path="Ghidra BSim scripts"/>
<classpathentry kind="src" path="Ghidra Base scripts"/>
<classpathentry kind="src" path="Ghidra BytePatterns scripts"/>
<classpathentry kind="src" path="Ghidra DATA scripts"/>
<classpathentry kind="src" path="Ghidra Debugger scripts"/>
<classpathentry kind="src" path="Ghidra Debugger-rmi-trace scripts"/>
<classpathentry kind="src" path="Ghidra Decompiler scripts"/>
<classpathentry kind="src" path="Ghidra DecompilerDependent scripts"/>
<classpathentry kind="src" path="Ghidra FileFormats scripts"/>
<classpathentry kind="src" path="Ghidra FunctionID scripts"/>
<classpathentry kind="src" path="Ghidra GnuDemangler scripts"/>
<classpathentry kind="src" path="Ghidra JVM scripts"/>
<classpathentry kind="src" path="Ghidra Jython scripts"/>
<classpathentry kind="src" path="Ghidra MicrosoftCodeAnalyzer scripts"/>
<classpathentry kind="src" path="Ghidra PDB scripts"/>
<classpathentry kind="src" path="Ghidra PIC scripts"/>
<classpathentry kind="src" path="Ghidra PyGhidra scripts"/>
<classpathentry kind="src" path="Ghidra SwiftDemangler scripts"/>
<classpathentry kind="src" path="Ghidra SystemEmulation scripts"/>
<classpathentry kind="src" path="Ghidra VersionTracking scripts"/>
<classpathentry kind="src" path="Ghidra WildcardAssembler scripts"/>
<classpathentry kind="src" path="Ghidra XEXLoaderWV scripts"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-21.0.7.6-hotspot"/>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/68000/lib/68000.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/68000/lib/68000-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/8051/lib/8051.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/AARCH64/lib/AARCH64.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/AARCH64/lib/AARCH64-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/ARM/lib/ARM.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/ARM/lib/ARM-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/AnnotationValidator/lib/AnnotationValidator.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/AnnotationValidator/lib/AnnotationValidator-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Atmel/lib/Atmel.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Atmel/lib/Atmel-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/BSim.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/BSim-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/commons-dbcp2-2.9.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/commons-logging-1.2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/commons-pool2-2.11.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/h2-2.2.220.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/lib/postgresql-42.7.3.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSimFeatureVisualizer/lib/BSimFeatureVisualizer.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSimFeatureVisualizer/lib/BSimFeatureVisualizer-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/Base.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/Base-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/biz.aQute.bnd.util-7.0.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/biz.aQute.bndlib-7.0.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/org.apache.felix.framework-7.0.5.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/org.osgi.util.promise-1.3.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/phidias-0.3.7.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/slf4j-api-1.7.25.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/lib/slf4j-nop-1.7.25.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BytePatterns/lib/BytePatterns.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BytePatterns/lib/BytePatterns-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/ByteViewer/lib/ByteViewer.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/ByteViewer/lib/ByteViewer-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/CodeCompare/lib/CodeCompare.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/CodeCompare/lib/CodeCompare-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/DATA/lib/DATA.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/DATA/lib/DATA-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/DB/lib/DB.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/DB/lib/DB-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Dalvik/lib/Dalvik.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Dalvik/lib/Dalvik-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/DebugUtils/lib/DebugUtils.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/DebugUtils/lib/DebugUtils-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger/lib/Debugger.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger/lib/Debugger-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-api/lib/Debugger-api.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-api/lib/Debugger-api-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-isf/lib/Debugger-isf.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-isf/lib/Debugger-isf-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-jpda/lib/Debugger-jpda.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-jpda/lib/Debugger-jpda-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-rmi-trace/lib/Debugger-rmi-trace.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-rmi-trace/lib/Debugger-rmi-trace-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Decompiler/lib/Decompiler.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Decompiler/lib/Decompiler-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/DecompilerDependent/lib/DecompilerDependent.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/DecompilerDependent/lib/DecompilerDependent-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Docking/lib/Docking.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Docking/lib/Docking-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/asm-9.7.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/asm-analysis-9.7.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/asm-commons-9.7.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/asm-tree-9.7.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/asm-util-9.7.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/Emulation.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Emulation/lib/Emulation-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/AXMLPrinter2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/baksmali-2.5.2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/dex-ir-2.4.24.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/dex-reader-2.4.24.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/dex-reader-api-2.4.24.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/dex-translator-2.4.24.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/dexlib2-2.5.2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/FileFormats.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/FileFormats-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/sevenzipjbinding-16.02-2.01.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/sevenzipjbinding-all-platforms-16.02-2.01.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/lib/util-2.5.2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/FileSystem/lib/FileSystem.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/FileSystem/lib/FileSystem-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Framework-AsyncComm/lib/Framework-AsyncComm.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Framework-AsyncComm/lib/Framework-AsyncComm-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Framework-AsyncComm/lib/protobuf-java-3.21.8.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Framework-TraceModeling/lib/Framework-TraceModeling.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Framework-TraceModeling/lib/Framework-TraceModeling-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionGraph/lib/FunctionGraph.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionGraph/lib/FunctionGraph-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionGraphDecompilerExtension/lib/FunctionGraphDecompilerExtension.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionGraphDecompilerExtension/lib/FunctionGraphDecompilerExtension-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionID/lib/FunctionID.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionID/lib/FunctionID-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/bcpkix-jdk15on-1.69.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/bcprov-jdk15on-1.69.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/bcutil-jdk15on-1.69.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/commons-collections4-4.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/commons-compress-1.21.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/commons-io-2.11.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/commons-lang3-3.12.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/commons-text-1.10.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/failureaccess-1.0.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/Generic.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/Generic-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/gson-2.9.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/guava-32.1.3-jre.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/jdom-legacy-1.1.3.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/log4j-api-2.17.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Generic/lib/log4j-core-2.17.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GhidraGo/lib/GhidraGo.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GhidraGo/lib/GhidraGo-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GhidraServer/lib/GhidraServer.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GhidraServer/lib/GhidraServer-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GnuDemangler/lib/GnuDemangler.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GnuDemangler/lib/GnuDemangler-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/Graph.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/Graph-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/jgrapht-core-1.5.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/jgrapht-io-1.5.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/jung-algorithms-2.1.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/jung-api-2.1.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/jung-graph-impl-2.1.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Graph/lib/jung-visualization-2.1.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphFunctionCalls/lib/GraphFunctionCalls.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphFunctionCalls/lib/GraphFunctionCalls-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/GraphServices.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/GraphServices-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/jgrapht-core-1.5.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/jgrapht-io-1.5.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/jheaps-0.13.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/jungrapht-layout-1.4.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GraphServices/lib/jungrapht-visualization-1.4.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Gui/lib/flatlaf-3.5.4.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Gui/lib/Gui.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Gui/lib/Gui-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/HCS12/lib/HCS12.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/HCS12/lib/HCS12-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Help/lib/Help.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Help/lib/Help-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Help/lib/javahelp-2.0.05.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Help/lib/timingframework-1.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/JVM/lib/JVM.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/JVM/lib/JVM-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Jython/lib/jython-standalone-2.7.4.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Jython/lib/Jython.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Jython/lib/Jython-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Loongarch/lib/Loongarch.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Loongarch/lib/Loongarch-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/MIPS/lib/MIPS.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/MIPS/lib/MIPS-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftCodeAnalyzer/lib/MicrosoftCodeAnalyzer.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftCodeAnalyzer/lib/MicrosoftCodeAnalyzer-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftDemangler/lib/MicrosoftDemangler.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftDemangler/lib/MicrosoftDemangler-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftDmang/lib/MicrosoftDmang.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftDmang/lib/MicrosoftDmang-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/PDB/lib/PDB.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/PDB/lib/PDB-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/PIC/lib/PIC.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/PIC/lib/PIC-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/PowerPC/lib/PowerPC.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/PowerPC/lib/PowerPC-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/ProgramDiff/lib/ProgramDiff.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/ProgramDiff/lib/ProgramDiff-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/ProgramGraph/lib/ProgramGraph.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/ProgramGraph/lib/ProgramGraph-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Project/lib/Project.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Project/lib/Project-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Project/lib/xz-1.9.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/ProposedUtils/lib/ProposedUtils.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/ProposedUtils/lib/ProposedUtils-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Pty/lib/jna-5.14.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Pty/lib/jna-platform-5.14.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Pty/lib/Pty.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Pty/lib/Pty-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Configurations/Public_Release/lib/Public_Release.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/PyGhidra/lib/PyGhidra.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/PyGhidra/lib/PyGhidra-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/RISCV/lib/RISCV.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/RISCV/lib/RISCV-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Recognizers/lib/Recognizers.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Recognizers/lib/Recognizers-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Sarif/lib/java-sarif-2.1-modified.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Sarif/lib/Sarif.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Sarif/lib/Sarif-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/antlr-runtime-3.5.2.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/isorelax-20050913.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/msv-20050913.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/relaxngDatatype-20050913.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/SoftwareModeling.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/SoftwareModeling-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/SoftwareModeling/lib/xsdlib-20050913.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SourceCodeLookup/lib/SourceCodeLookup.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SourceCodeLookup/lib/SourceCodeLookup-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Sparc/lib/Sparc.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Sparc/lib/Sparc-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/SuperH4/lib/SuperH4.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/SuperH4/lib/SuperH4-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SwiftDemangler/lib/SwiftDemangler.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SwiftDemangler/lib/SwiftDemangler-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SystemEmulation/lib/SystemEmulation.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SystemEmulation/lib/SystemEmulation-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/TI_MSP430/lib/TI_MSP430.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/TI_MSP430/lib/TI_MSP430-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/TaintAnalysis/lib/TaintAnalysis.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/TaintAnalysis/lib/TaintAnalysis-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Utility/lib/Utility.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Framework/Utility/lib/Utility-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/V850/lib/V850.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/VersionTracking/lib/VersionTracking.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/VersionTracking/lib/VersionTracking-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/VersionTrackingBSim/lib/VersionTrackingBSim.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/VersionTrackingBSim/lib/VersionTrackingBSim-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/WildcardAssembler/lib/WildcardAssembler.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/WildcardAssembler/lib/WildcardAssembler-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Users/Guus/AppData/Roaming/ghidra/ghidra_11.3.2_PUBLIC/Extensions/XEXLoaderWV/lib/XEXLoaderWV.jar" sourcepath="C:/Users/Guus/AppData/Roaming/ghidra/ghidra_11.3.2_PUBLIC/Extensions/XEXLoaderWV/lib/XEXLoaderWV-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Xtensa/lib/Xtensa.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Xtensa/lib/Xtensa-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/eBPF/lib/eBPF.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/eBPF/lib/eBPF-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/tricore/lib/tricore.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/tricore/lib/tricore-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/x86/lib/x86.jar" sourcepath="C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/x86/lib/x86-src.zip">
<attributes>
<attribute name="javadoc_location" value="jar:file:/C:\Projects\ghidra_11.3.2_PUBLIC\docs\GhidraAPI_javadoc.zip!/api/"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin/default"/>
</classpath>

1
java/ghidra/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
bin

144
java/ghidra/.project Normal file
View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>GhidraScripts</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>Ghidra</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC</location>
</link>
<link>
<name>Ghidra 8051 scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/8051/ghidra_scripts</location>
</link>
<link>
<name>Ghidra Atmel scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/Atmel/ghidra_scripts</location>
</link>
<link>
<name>Ghidra BSim scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BSim/ghidra_scripts</location>
</link>
<link>
<name>Ghidra Base scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Base/ghidra_scripts</location>
</link>
<link>
<name>Ghidra BytePatterns scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/BytePatterns/ghidra_scripts</location>
</link>
<link>
<name>Ghidra DATA scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/DATA/ghidra_scripts</location>
</link>
<link>
<name>Ghidra Debugger scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger/ghidra_scripts</location>
</link>
<link>
<name>Ghidra Debugger-rmi-trace scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts</location>
</link>
<link>
<name>Ghidra Decompiler scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Decompiler/ghidra_scripts</location>
</link>
<link>
<name>Ghidra DecompilerDependent scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/DecompilerDependent/ghidra_scripts</location>
</link>
<link>
<name>Ghidra FileFormats scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FileFormats/ghidra_scripts</location>
</link>
<link>
<name>Ghidra FunctionID scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/FunctionID/ghidra_scripts</location>
</link>
<link>
<name>Ghidra GnuDemangler scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/GnuDemangler/ghidra_scripts</location>
</link>
<link>
<name>Ghidra JVM scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/JVM/ghidra_scripts</location>
</link>
<link>
<name>Ghidra Jython scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/Jython/ghidra_scripts</location>
</link>
<link>
<name>Ghidra MicrosoftCodeAnalyzer scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/MicrosoftCodeAnalyzer/ghidra_scripts</location>
</link>
<link>
<name>Ghidra PDB scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/PDB/ghidra_scripts</location>
</link>
<link>
<name>Ghidra PIC scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Processors/PIC/ghidra_scripts</location>
</link>
<link>
<name>Ghidra PyGhidra scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/PyGhidra/ghidra_scripts</location>
</link>
<link>
<name>Ghidra SwiftDemangler scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SwiftDemangler/ghidra_scripts</location>
</link>
<link>
<name>Ghidra SystemEmulation scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/SystemEmulation/ghidra_scripts</location>
</link>
<link>
<name>Ghidra VersionTracking scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/VersionTracking/ghidra_scripts</location>
</link>
<link>
<name>Ghidra WildcardAssembler scripts</name>
<type>2</type>
<location>C:/Projects/ghidra_11.3.2_PUBLIC/Ghidra/Features/WildcardAssembler/ghidra_scripts</location>
</link>
<link>
<name>Ghidra XEXLoaderWV scripts</name>
<type>2</type>
<location>C:/Users/Guus/AppData/Roaming/ghidra/ghidra_11.3.2_PUBLIC/Extensions/XEXLoaderWV/ghidra_scripts</location>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,47 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.compliance=21
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=21

View File

@ -150,16 +150,16 @@ public class Decompile extends GhidraScript {
return;
}
RecompileConfig.INSTANCE = new RecompileConfig(this);
RemanConfig.INSTANCE = new RemanConfig(this);
if (!new File(RecompileConfig.INSTANCE.outputDir).exists()) {
throw new Exception("Output directory does not exist: " + RecompileConfig.INSTANCE.outputDir);
if (!new File(RemanConfig.INSTANCE.outputDir).exists()) {
throw new Exception("Output directory does not exist: " + RemanConfig.INSTANCE.outputDir);
}
// Make sure to create output folders
RecompileConfig.INSTANCE.dirDecompFix.mkdirs();
RecompileConfig.INSTANCE.dirDecompAuto.mkdirs();
RecompileConfig.INSTANCE.dirDecompRef.mkdirs();
RemanConfig.INSTANCE.dirDecompFix.mkdirs();
RemanConfig.INSTANCE.dirDecompAuto.mkdirs();
RemanConfig.INSTANCE.dirDecompRef.mkdirs();
// buildFunctionBlacklist();

View File

@ -6,29 +6,32 @@ import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.Function;
import re3lib.FunctionDumper;
import re3lib.GlobalDumper;
import re3lib.RecompileConfig;
import re3lib.RemanConfig;
import re3lib.FunctionDatabase;
public class DumpCurrentFunction extends GhidraScript {
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
RecompileConfig.INSTANCE.createDirectories();
RemanConfig.INSTANCE = new RemanConfig(this);
RemanConfig.INSTANCE.createDirectories();
GlobalDumper globalDumper = new GlobalDumper(this);
globalDumper.loadGlobalManifest();
FunctionDumper functionDumper = new FunctionDumper(this, globalDumper);
try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) {
GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase);
globalDumper.loadGlobalManifest();
FunctionDumper functionDumper = new FunctionDumper(this, functionDatabase, globalDumper);
Function currentFunction = getFunctionContaining(currentAddress);
if (currentFunction != null) {
functionDumper.dump(currentFunction);
} else {
println("No function found at the current address.");
Function currentFunction = getFunctionContaining(currentAddress);
if (currentFunction != null) {
functionDumper.dump(currentFunction);
} else {
println("No function found at the current address.");
}
if (functionDumper.createdFile)
RemanConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
}
if (functionDumper.createdFile)
RecompileConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
}
}

View File

@ -9,99 +9,104 @@ import java.util.List;
import ghidra.app.script.GhidraScript;
import ghidra.pcodeCPort.address.Address;
import ghidra.program.model.listing.Function;
import re3lib.FunctionDatabase;
import re3lib.FunctionDumper;
import re3lib.GlobalDumper;
import re3lib.PCallTracer;
import re3lib.RecompileConfig;
import re3lib.RemanConfig;
import re3lib.TypeDumper;
public class DumpCurrentFunctionN extends GhidraScript {
final int NumFunctions = 8;
// class Entry {
// Function function;
// Function function;
// }
// class QueueEntry {
// Function function;
// List<Function> callees;
// Function function;
// List<Function> callees;
// }
// HashSet<Address> visited = new HashSet<>();
// QueueEntry enter(Function function) {
// if (visited.contains(function.getEntryPoint()))
// return null;
// if (visited.contains(function.getEntryPoint()))
// return null;
// visited.add(function.getEntryPoint());
// visited.add(function.getEntryPoint());
// QueueEntry entry = new QueueEntry();
// entry.function = function;
// QueueEntry entry = new QueueEntry();
// entry.function = function;
// function.getCalledFunctions(monitor);
// function.getCalledFunctions(monitor);
// }
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
RecompileConfig.INSTANCE.createDirectories();
RemanConfig.INSTANCE = new RemanConfig(this);
RemanConfig.INSTANCE.createDirectories();
GlobalDumper globalDumper = new GlobalDumper(this);
globalDumper.loadGlobalManifest();
try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) {
FunctionDumper functionDumper = new FunctionDumper(this, globalDumper);
GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase);
globalDumper.loadGlobalManifest();
PCallTracer tracer = new PCallTracer();
tracer.setBlacklist(functionDumper.functionAddrBlackList);
tracer.traceCalls(getFunctionContaining(currentAddress));
FunctionDumper functionDumper = new FunctionDumper(this, functionDatabase, globalDumper);
List<Address> queue = new ArrayList<>();
PCallTracer tracer = new PCallTracer();
tracer.setBlacklist(functionDumper.functionAddrBlackList);
tracer.traceCalls(getFunctionContaining(currentAddress));
// List<Function> functionsToDump = new ArrayList<>();
// List<Function> functionsToDumpNew = new ArrayList<>();
// for (Function func : tracer.out) {
// if (FunctionDumper.isDumpedFix(func))
// continue;
List<Address> queue = new ArrayList<>();
// println("Dump: " + func.getName());
// functionsToDump.add(func);
// List<Function> functionsToDump = new ArrayList<>();
// List<Function> functionsToDumpNew = new ArrayList<>();
// for (Function func : tracer.out) {
// if (FunctionDumper.isDumpedFix(func))
// continue;
// if (!FunctionDumper.isDumpedAuto(func))
// functionsToDumpNew.add(func);
// }
// println("Dump: " + func.getName());
// functionsToDump.add(func);
// if (!functionsToDump.isEmpty()) {
// String newOpt = "Only new (" + functionsToDumpNew.size() + ")";
// String okOpt = "Yes (" + functionsToDump.size() + ")";
// String choice = askChoice("Confirmation", "About to generate " + functionsToDump.size() + " functions ("
// + functionsToDumpNew.size() + " new), continue?",
// new ArrayList<String>() {
// {
// add(okOpt);
// add(newOpt);
// add("No");
// }
// }, okOpt);
// if (choice == okOpt) {
// } else if (choice == newOpt) {
// functionsToDump = functionsToDumpNew;
// } else {
// return;
// }
// if (!FunctionDumper.isDumpedAuto(func))
// functionsToDumpNew.add(func);
// }
// for (Function func : functionsToDump) {
// functionDumper.dump(func);
// }
// if (!functionsToDump.isEmpty()) {
// String newOpt = "Only new (" + functionsToDumpNew.size() + ")";
// String okOpt = "Yes (" + functionsToDump.size() + ")";
// String choice = askChoice("Confirmation", "About to generate " +
// functionsToDump.size() + " functions ("
// + functionsToDumpNew.size() + " new), continue?",
// new ArrayList<String>() {
// {
// add(okOpt);
// add(newOpt);
// add("No");
// }
// }, okOpt);
// if (choice == okOpt) {
// } else if (choice == newOpt) {
// functionsToDump = functionsToDumpNew;
// } else {
// return;
// }
// if (functionDumper.createdFile)
// RecompileConfig.INSTANCE.touchCMakeTimestamp();
// for (Function func : functionsToDump) {
// functionDumper.dump(func);
// }
// globalDumper.dumpGlobals();
// globalDumper.saveGlobalManifest();
// }
// if (functionDumper.createdFile)
// RecompileConfig.INSTANCE.touchCMakeTimestamp();
// // Dump types
// TypeDumper dumper = new TypeDumper(this);
// dumper.run();
// globalDumper.dumpGlobals();
// globalDumper.saveGlobalManifest();
// }
// // Dump types
// TypeDumper dumper = new TypeDumper(this);
// dumper.run();
}
}
}

View File

@ -7,72 +7,75 @@ import java.util.List;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.Function;
import re3lib.FunctionDatabase;
import re3lib.FunctionDumper;
import re3lib.GlobalDumper;
import re3lib.PCallTracer;
import re3lib.RecompileConfig;
import re3lib.RemanConfig;
import re3lib.TypeDumper;
public class DumpCurrentFunctionRecursive extends GhidraScript {
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
RecompileConfig.INSTANCE.createDirectories();
RemanConfig.INSTANCE = new RemanConfig(this);
RemanConfig.INSTANCE.createDirectories();
GlobalDumper globalDumper = new GlobalDumper(this);
globalDumper.loadGlobalManifest();
try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) {
GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase);
globalDumper.loadGlobalManifest();
FunctionDumper functionDumper = new FunctionDumper(this, globalDumper);
FunctionDumper functionDumper = new FunctionDumper(this, functionDatabase, globalDumper);
PCallTracer tracer = new PCallTracer();
tracer.setBlacklist(functionDumper.functionAddrBlackList);
tracer.traceCalls(getFunctionContaining(currentAddress));
PCallTracer tracer = new PCallTracer();
tracer.setBlacklist(functionDumper.functionAddrBlackList);
tracer.traceCalls(getFunctionContaining(currentAddress));
List<Function> functionsToDump = new ArrayList<>();
List<Function> functionsToDumpNew = new ArrayList<>();
for (Function func : tracer.out) {
if (FunctionDumper.isDumpedFix(func))
continue;
List<Function> functionsToDump = new ArrayList<>();
List<Function> functionsToDumpNew = new ArrayList<>();
for (Function func : tracer.out) {
if (FunctionDumper.isDumpedFix(func))
continue;
println("Dump: " + func.getName());
functionsToDump.add(func);
println("Dump: " + func.getName());
functionsToDump.add(func);
if (!FunctionDumper.isDumpedAuto(func))
functionsToDumpNew.add(func);
}
if (!functionsToDump.isEmpty()) {
String newOpt = "Only new (" + functionsToDumpNew.size() + ")";
String okOpt = "Yes (" + functionsToDump.size() + ")";
String choice = askChoice("Confirmation", "About to generate " + functionsToDump.size() + " functions ("
+ functionsToDumpNew.size() + " new), continue?",
new ArrayList<String>() {
{
add(okOpt);
add(newOpt);
add("No");
}
}, okOpt);
if (choice == okOpt) {
} else if (choice == newOpt) {
functionsToDump = functionsToDumpNew;
} else {
return;
if (!FunctionDumper.isDumpedAuto(func))
functionsToDumpNew.add(func);
}
for (Function func : functionsToDump) {
functionDumper.dump(func);
if (!functionsToDump.isEmpty()) {
String newOpt = "Only new (" + functionsToDumpNew.size() + ")";
String okOpt = "Yes (" + functionsToDump.size() + ")";
String choice = askChoice("Confirmation", "About to generate " + functionsToDump.size() + " functions ("
+ functionsToDumpNew.size() + " new), continue?",
new ArrayList<String>() {
{
add(okOpt);
add(newOpt);
add("No");
}
}, okOpt);
if (choice == okOpt) {
} else if (choice == newOpt) {
functionsToDump = functionsToDumpNew;
} else {
return;
}
for (Function func : functionsToDump) {
functionDumper.dump(func);
}
if (functionDumper.createdFile)
RemanConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
}
if (functionDumper.createdFile)
RecompileConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
// Dump types
TypeDumper dumper = new TypeDumper(this);
dumper.run();
}
// Dump types
TypeDumper dumper = new TypeDumper(this);
dumper.run();
}
}

View File

@ -0,0 +1,28 @@
// Script to refresh all custom globals & types from Ghidra
// @category _Reman3
// @menupath Reman3.Redump Globals and Types
import ghidra.app.script.GhidraScript;
import re3lib.GlobalDumper;
import re3lib.RemanConfig;
import re3lib.TypeDumper;
import re3lib.FunctionDatabase;
public class DumpGlobals extends GhidraScript {
@Override
protected void run() throws Exception {
RemanConfig.INSTANCE = new RemanConfig(this);
RemanConfig.INSTANCE.createDirectories();
try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) {
GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase);
globalDumper.loadGlobalManifest();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
TypeDumper dumper = new TypeDumper(this);
dumper.run();
}
}
}

View File

@ -1,13 +1,13 @@
// Exports binary read only and data segments to a binary + header file
// @category _Reman3
// @menupath Tools.Reman3.Export Data
// @menupath Reman3.Export Data Segment
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import re3lib.RecompileConfig;
import re3lib.RemanConfig;
public class ExportData extends GhidraScript {
@ -16,16 +16,16 @@ public class ExportData extends GhidraScript {
if (currentProgram == null) {
return;
}
RecompileConfig.INSTANCE = new RecompileConfig(this);
RemanConfig.INSTANCE = new RemanConfig(this);
String dataFile = new File(RecompileConfig.INSTANCE.outputDir, "gh_datasegment.bin").toString();
String headerFile = new File(RecompileConfig.INSTANCE.outputDir, "gh_datasegment.h").toString();
String dataFile = new File(RemanConfig.INSTANCE.outputDir, "gh_datasegment.bin").toString();
String headerFile = new File(RemanConfig.INSTANCE.outputDir, "gh_datasegment.h").toString();
FileOutputStream dataOutputStream = new FileOutputStream(dataFile);
PrintWriter headerWriter = new PrintWriter(headerFile, "UTF-8");
Address startAddr = RecompileConfig.INSTANCE.staticMemoryBlockStart;
Address endAddr = RecompileConfig.INSTANCE.staticMemoryBlockEnd;
Address startAddr = RemanConfig.INSTANCE.staticMemoryBlockStart;
Address endAddr = RemanConfig.INSTANCE.staticMemoryBlockEnd;
// Dump all the memory to the bin file
int numBytes = (int) endAddr.subtract(startAddr);

View File

@ -4,13 +4,13 @@
import ghidra.app.script.GhidraScript;
import re3lib.GlobalDumper;
import re3lib.RecompileConfig;
import re3lib.RemanConfig;
public class SanitizeGlobalSymbols extends GhidraScript {
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
RecompileConfig.INSTANCE.createDirectories();
RemanConfig.INSTANCE = new RemanConfig(this);
RemanConfig.INSTANCE.createDirectories();
GlobalDumper globalDumper = new GlobalDumper(this);
globalDumper.loadGlobalManifest();

View File

@ -2,83 +2,23 @@
// @menupath Reman3.Test
// @importpackage org.sqlite
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.StandAloneDataTypeManager;
import re3lib.RecompileConfig;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// SQLite imports
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.sqlite.JDBC;
import ghidra.app.script.GhidraScript;
import re3lib.FunctionDatabase;
import re3lib.RemanConfig;
public class Test extends GhidraScript {
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
java.sql.DriverManager.registerDriver(new JDBC());
RemanConfig.INSTANCE = new RemanConfig(this);
// Example SQLite usage
testSQLite();
}
private void testSQLite() throws Exception {
String dbPath = "jdbc:sqlite:" + RecompileConfig.INSTANCE.outputDir + "/functions.db";
try (Connection conn = DriverManager.getConnection(dbPath)) {
println("Connected to SQLite database: " + dbPath);
// Create a simple table
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE IF NOT EXISTS functions (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"address TEXT NOT NULL, " +
"name TEXT NOT NULL, " +
"file_path TEXT)");
println("Functions table created/verified");
try (FunctionDatabase db = new FunctionDatabase(this)) {
List<FunctionDatabase.FunctionEntry> entries = db.loadAllEntries();
for (FunctionDatabase.FunctionEntry entry : entries) {
println("entry.name: " + entry.name + " entry.address: " + entry.address + " entry.type: " + entry.type);
}
// Insert example data
String insertSQL = "INSERT INTO functions (address, name, file_path) VALUES (?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {
pstmt.setString(1, "0x00401000");
pstmt.setString(2, "main");
pstmt.setString(3, "/path/to/main.cxx");
pstmt.executeUpdate();
println("Inserted example function");
}
// Query data
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM functions")) {
while (rs.next()) {
println("Function: " + rs.getString("name") +
" at " + rs.getString("address") +
" in " + rs.getString("file_path"));
}
}
} catch (SQLException e) {
println("SQLite error: " + e.getMessage());
throw e;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,11 @@
package re3lib;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -8,111 +13,408 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.sqlite.JDBC;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
public class FunctionDatabase {
public enum Type {
Auto,
Fix,
Stub,
Ref
}
public class FunctionDatabase implements AutoCloseable {
public static enum Type {
Auto(0),
Fix(1),
Stub(2),
Ref(3);
public class Dependency implements java.io.Serializable {
private static final long serialVersionUID = 1L;
public Address address;
public String name;
private final int value;
public Dependency(Address address, String name) {
this.address = address;
this.name = name;
Type(int value) {
this.value = value;
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
out.writeObject(address != null ? address.toString() : null);
out.writeObject(name);
public int getValue() {
return value;
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
String addressString = (String) in.readObject();
if (addressString != null) {
address = RecompileConfig.INSTANCE.script.getCurrentProgram().getAddressFactory().getAddress(addressString);
public static Type fromValue(int value) {
for (Type type : Type.values()) {
if (type.value == value) {
return type;
}
}
name = (String) in.readObject();
throw new IllegalArgumentException("Unknown type value: " + value);
}
}
public class Entry implements java.io.Serializable {
private static final long serialVersionUID = 1L;
public static class FunctionEntry {
public Address address;
public String name;
public File file;
public Type type;
public List<Dependency> dependencies = new ArrayList<>();
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
out.writeObject(address != null ? address.toString() : null);
out.writeObject(name);
out.writeObject(file != null ? file.toString() : null);
out.writeObject(type);
out.writeObject(dependencies);
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
String addressString = (String) in.readObject();
if (addressString != null) {
address = RecompileConfig.INSTANCE.script.getCurrentProgram().getAddressFactory().getAddress(addressString);
}
name = (String) in.readObject();
String fileString = (String) in.readObject();
if (fileString != null) {
file = new File(fileString);
}
type = (Type) in.readObject();
dependencies = (List<Dependency>) in.readObject();
public FunctionEntry(Address address, String name, File file, Type type) {
this.address = address;
this.name = name;
this.file = file;
this.type = type;
}
}
public List<Entry> entries = new ArrayList<>();
private File file;
public static class GlobalEntry {
public Address address;
public String name;
public String dataType;
public File file;
public GlobalEntry(Address address, String name, String dataType, File file) {
this.address = address;
this.name = name;
this.dataType = dataType;
this.file = file;
}
}
private File dbFile;
private transient GhidraScript script;
private Connection connection;
// Prepared statements for better performance
private PreparedStatement findByNameFunctions;
private PreparedStatement findByNameImports;
private PreparedStatement findByAddressFunctions;
private PreparedStatement findByAddressImports;
private PreparedStatement insertOrReplaceFunctions;
private PreparedStatement deleteByFilepathFunctions;
private PreparedStatement deleteByFilepathImports;
private PreparedStatement loadAllFunctions;
private PreparedStatement loadAllImports;
// Add these prepared statements after the existing ones
private PreparedStatement findByNameGlobals;
private PreparedStatement findByAddressGlobals;
private PreparedStatement insertOrReplaceGlobals;
private PreparedStatement deleteByFilepathGlobals;
private PreparedStatement loadAllGlobals;
public FunctionDatabase(GhidraScript script) {
this.script = script;
file = new File(RecompileConfig.INSTANCE.outputDir, "functions.dat");
}
public void load() throws Exception {
if (!file.exists()) {
return;
}
try (java.io.ObjectInputStream ois = new java.io.ObjectInputStream(new java.io.FileInputStream(file))) {
entries = (List<Entry>) ois.readObject();
script.println("Loaded " + entries.size() + " function entries from " + file);
} catch (java.io.IOException | ClassNotFoundException e) {
script.println("Error loading function database: " + e.getMessage());
dbFile = RemanConfig.INSTANCE.databasePath;
try {
java.sql.DriverManager.registerDriver(new JDBC());
} catch (SQLException e) {
script.printerr("Error registering JDBC driver: " + e.getMessage());
}
}
public void save() throws Exception {
try (java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(new java.io.FileOutputStream(file))) {
oos.writeObject(entries);
script.println("Saved " + entries.size() + " function entries to " + file);
} catch (java.io.IOException e) {
script.println("Error saving function database: " + e.getMessage());
public void connect() throws Exception {
if (connection != null && !connection.isClosed()) {
return; // Already connected
}
if (!dbFile.exists()) {
script.println("Database file not found: " + dbFile);
// Create parent directories if they don't exist
dbFile.getParentFile().mkdirs();
}
try {
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath());
createTablesIfNotExist();
prepareCachedStatements();
script.println("Connected to database: " + dbFile);
} catch (SQLException e) {
script.println("Error connecting to database: " + e.getMessage());
throw new Exception("Failed to connect to database", e);
}
}
public void add(Entry entry) {
entries.add(entry);
public void disconnect() throws Exception {
if (connection != null && !connection.isClosed()) {
try {
// Close prepared statements
closePreparedStatements();
connection.close();
script.println("Disconnected from database");
} catch (SQLException e) {
script.println("Error disconnecting from database: " + e.getMessage());
throw new Exception("Failed to disconnect from database", e);
}
}
}
private void ensureConnection() throws Exception {
if (connection == null || connection.isClosed()) {
connect();
}
}
private void prepareCachedStatements() throws SQLException {
// Find by name
findByNameFunctions = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Functions WHERE name = ?");
findByNameImports = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Imports WHERE name = ?");
// Find by address
findByAddressFunctions = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Functions WHERE address = ?");
findByAddressImports = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Imports WHERE address = ?");
// Insert or replace
insertOrReplaceFunctions = connection.prepareStatement(
"INSERT OR REPLACE INTO Functions (filepath, name, address, type) VALUES (?, ?, ?, ?)");
// Delete by filepath
deleteByFilepathFunctions = connection.prepareStatement(
"DELETE FROM Functions WHERE filepath = ?");
deleteByFilepathImports = connection.prepareStatement(
"DELETE FROM Imports WHERE filepath = ?");
// Load all entries
loadAllFunctions = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Functions");
loadAllImports = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Imports");
// Global statements
findByNameGlobals = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Globals WHERE name = ?");
findByAddressGlobals = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Globals WHERE address = ?");
insertOrReplaceGlobals = connection.prepareStatement(
"INSERT OR REPLACE INTO Globals (filepath, name, address, type) VALUES (?, ?, ?, ?)");
deleteByFilepathGlobals = connection.prepareStatement(
"DELETE FROM Globals WHERE filepath = ?");
loadAllGlobals = connection.prepareStatement(
"SELECT filepath, name, address, type FROM Globals");
}
private void closePreparedStatements() throws SQLException {
if (findByNameFunctions != null)
findByNameFunctions.close();
if (findByNameImports != null)
findByNameImports.close();
if (findByAddressFunctions != null)
findByAddressFunctions.close();
if (findByAddressImports != null)
findByAddressImports.close();
if (insertOrReplaceFunctions != null)
insertOrReplaceFunctions.close();
if (deleteByFilepathFunctions != null)
deleteByFilepathFunctions.close();
if (deleteByFilepathImports != null)
deleteByFilepathImports.close();
if (loadAllFunctions != null)
loadAllFunctions.close();
if (loadAllImports != null)
loadAllImports.close();
if (findByNameGlobals != null)
findByNameGlobals.close();
if (findByAddressGlobals != null)
findByAddressGlobals.close();
if (insertOrReplaceGlobals != null)
insertOrReplaceGlobals.close();
if (deleteByFilepathGlobals != null)
deleteByFilepathGlobals.close();
if (loadAllGlobals != null)
loadAllGlobals.close();
}
public List<FunctionEntry> loadAllEntries() throws Exception {
ensureConnection();
List<FunctionEntry> entries = new ArrayList<>();
try {
// Load from Functions table
try (ResultSet rs = loadAllFunctions.executeQuery()) {
while (rs.next()) {
FunctionEntry entry = createEntryFromResultSet(rs);
if (entry != null) {
entries.add(entry);
}
}
}
script.println("Loaded " + entries.size() + " function entries from database");
return entries;
} catch (SQLException e) {
script.println("Error loading entries: " + e.getMessage());
throw new Exception("Failed to load entries", e);
}
}
private FunctionEntry createEntryFromResultSet(ResultSet rs) throws SQLException {
String filepath = rs.getString("filepath");
String name = rs.getString("name");
String addressStr = rs.getString("address");
int typeValue = rs.getInt("type");
if (addressStr != null && !addressStr.isEmpty()) {
Address address = script.getCurrentProgram().getAddressFactory().getAddress(addressStr);
File file = new File(RemanConfig.INSTANCE.outputDir, filepath);
Type type = Type.fromValue(typeValue);
return new FunctionEntry(address, name, file, type);
}
return null;
}
private void createTablesIfNotExist() throws SQLException {
String createFunctions = """
CREATE TABLE IF NOT EXISTS Functions (
filepath TEXT,
name TEXT,
address TEXT,
type INTEGER,
PRIMARY KEY (name, filepath)
)""";
String createImports = """
CREATE TABLE IF NOT EXISTS Imports (
filepath TEXT,
name TEXT,
address TEXT,
type INTEGER,
PRIMARY KEY (name, filepath)
)""";
String createGlobals = """
CREATE TABLE IF NOT EXISTS Globals (
filepath TEXT,
name TEXT,
address TEXT,
type TEXT,
PRIMARY KEY (name, filepath)
)""";
connection.prepareStatement(createFunctions).executeUpdate();
connection.prepareStatement(createImports).executeUpdate();
connection.prepareStatement(createGlobals).executeUpdate();
}
// Helper method to find entries by name
public List<FunctionEntry> findEntriesByName(String name) throws Exception {
ensureConnection();
List<FunctionEntry> results = new ArrayList<>();
try {
// Search Functions table
findByNameFunctions.setString(1, name);
try (ResultSet rs = findByNameFunctions.executeQuery()) {
while (rs.next()) {
FunctionEntry entry = createEntryFromResultSet(rs);
if (entry != null) {
results.add(entry);
}
}
}
// Search Imports table
findByNameImports.setString(1, name);
try (ResultSet rs = findByNameImports.executeQuery()) {
while (rs.next()) {
FunctionEntry entry = createEntryFromResultSet(rs);
if (entry != null) {
results.add(entry);
}
}
}
return results;
} catch (SQLException e) {
script.println("Error finding entries by name: " + e.getMessage());
throw new Exception("Failed to find entries by name", e);
}
}
// Helper method to find entries by address
public List<FunctionEntry> findEntriesByAddress(Address address) throws Exception {
ensureConnection();
List<FunctionEntry> results = new ArrayList<>();
String addressStr = address.toString();
try {
// Search Functions table
findByAddressFunctions.setString(1, addressStr);
try (ResultSet rs = findByAddressFunctions.executeQuery()) {
while (rs.next()) {
FunctionEntry entry = createEntryFromResultSet(rs);
if (entry != null) {
results.add(entry);
}
}
}
// Search Imports table
findByAddressImports.setString(1, addressStr);
try (ResultSet rs = findByAddressImports.executeQuery()) {
while (rs.next()) {
FunctionEntry entry = createEntryFromResultSet(rs);
if (entry != null) {
results.add(entry);
}
}
}
return results;
} catch (SQLException e) {
script.println("Error finding entries by address: " + e.getMessage());
throw new Exception("Failed to find entries by address", e);
}
}
// Helper method to add/update entry (insert or replace based on filename)
public void addEntryAt(FunctionEntry entry) throws Exception {
ensureConnection();
String relativePath = new File(RemanConfig.INSTANCE.outputDir).toPath()
.relativize(entry.file.toPath()).toString().replace('\\', '/');
try {
insertOrReplaceFunctions.setString(1, relativePath);
insertOrReplaceFunctions.setString(2, entry.name);
insertOrReplaceFunctions.setString(3, entry.address.toString());
insertOrReplaceFunctions.setInt(4, entry.type.getValue());
insertOrReplaceFunctions.executeUpdate();
script.println("Added/updated entry: " + entry.name + " at " + entry.address + " in " + relativePath);
} catch (SQLException e) {
script.println("Error adding entry: " + e.getMessage());
throw new Exception("Failed to add entry", e);
}
}
// Helper method to remove entry by file path
public void removeEntryAt(String filePath) throws Exception {
ensureConnection();
String relativePath = new File(RemanConfig.INSTANCE.outputDir).toPath()
.relativize(new File(filePath).toPath()).toString().replace('\\', '/');
try {
deleteByFilepathFunctions.setString(1, relativePath);
int deletedCount = deleteByFilepathFunctions.executeUpdate();
deleteByFilepathImports.setString(1, relativePath);
deletedCount += deleteByFilepathImports.executeUpdate();
script.println("Removed " + deletedCount + " entries for file: " + relativePath);
} catch (SQLException e) {
script.println("Error removing entries: " + e.getMessage());
throw new Exception("Failed to remove entries", e);
}
}
public void add(FunctionEntry entry) throws Exception {
// Add entry directly to database
addEntryAt(entry);
}
public void applyDefaultFilters(boolean rebuildAllGlobals) throws Exception {
GlobalDumper globalDumper = new GlobalDumper(script);
FunctionDumper dumper = new FunctionDumper(script, globalDumper);
GlobalDumper globalDumper = new GlobalDumper(script, this);
FunctionDumper dumper = new FunctionDumper(script, this, globalDumper);
if (rebuildAllGlobals) {
globalDumper.removeGlobalManifest();
@ -120,13 +422,15 @@ public class FunctionDatabase {
boolean madeAnyChanges = false;
// Load all entries from database
List<FunctionEntry> entries = loadAllEntries();
// Create a hash map to store symbol names
Map<Address, String> symbolNames = new HashMap<>();
Map<String, File> exportedFunctionNames = new HashMap<>();
for (Entry entry : entries) {
for (FunctionEntry entry : entries) {
Function function = script.getFunctionAt(entry.address);
if (function != null) {
String dirComponent = entry.file.getParent().toString();
boolean isAuto = entry.type == Type.Auto;
boolean isFix = entry.type == Type.Fix;
// Get the actual symbol name and store it in the hash map
@ -148,9 +452,9 @@ public class FunctionDatabase {
HashSet<Function> functionsToRegenerate = new HashSet<>();
Iterator<Entry> iterator = entries.iterator();
Iterator<FunctionEntry> iterator = entries.iterator();
while (iterator.hasNext()) {
Entry entry = iterator.next();
FunctionEntry entry = iterator.next();
Function function = script.getFunctionAt(entry.address);
boolean pendingDelete = false;
@ -197,21 +501,6 @@ public class FunctionDatabase {
}
}
// Check if dependencies are valid
for (Dependency dependency : entry.dependencies) {
Function depFunction = script.getFunctionAt(dependency.address);
if (depFunction == null) {
script.println(
"Dependency not found: " + dependency.name + " at " + dependency.address + " in " + entry.file);
pendingRegenerate = true;
} else if (!dumper.isValidFunction(depFunction) || !depFunction.getName().equals(dependency.name)) {
script
.println("Invalid dependency: " + dependency.name + " at " + dependency.address + " in " + entry.file
+ " should be " + dependency.name);
pendingRegenerate = true;
}
}
entry.name = actualSymbolName; // Update the entry name to match the actual symbol
madeAnyChanges = true;
}
@ -220,11 +509,15 @@ public class FunctionDatabase {
iterator.remove();
if (!dryMode) {
entry.file.delete();
// Remove from database
removeEntryAt(entry.file.getAbsolutePath());
madeAnyChanges = true;
}
} else if (pendingRegenerate && entry.type != Type.Stub) {
if (!dryMode) {
functionsToRegenerate.add(function);
// Update entry in database with corrected name
addEntryAt(entry);
madeAnyChanges = true;
}
}
@ -237,7 +530,7 @@ public class FunctionDatabase {
if (madeAnyChanges) {
// Update CMake timestamp
RecompileConfig.INSTANCE.touchCMakeTimestamp();
RemanConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
@ -245,4 +538,145 @@ public class FunctionDatabase {
typeDumper.run();
}
}
// Global-specific methods
public List<GlobalEntry> loadAllGlobals() throws Exception {
ensureConnection();
List<GlobalEntry> globals = new ArrayList<>();
try {
try (ResultSet rs = loadAllGlobals.executeQuery()) {
while (rs.next()) {
GlobalEntry entry = createGlobalEntryFromResultSet(rs);
if (entry != null) {
globals.add(entry);
}
}
}
script.println("Loaded " + globals.size() + " global entries from database");
return globals;
} catch (SQLException e) {
script.println("Error loading globals: " + e.getMessage());
throw new Exception("Failed to load globals", e);
}
}
private GlobalEntry createGlobalEntryFromResultSet(ResultSet rs) throws SQLException {
String filepath = rs.getString("filepath");
String name = rs.getString("name");
String addressStr = rs.getString("address");
String typeStr = rs.getString("type");
if (addressStr != null && !addressStr.isEmpty()) {
Address address = script.getCurrentProgram().getAddressFactory().getAddress(addressStr);
File file = new File(RemanConfig.INSTANCE.outputDir, filepath);
return new GlobalEntry(address, name, typeStr, file);
}
return null;
}
public List<GlobalEntry> findGlobalsByName(String name) throws Exception {
ensureConnection();
List<GlobalEntry> results = new ArrayList<>();
try {
findByNameGlobals.setString(1, name);
try (ResultSet rs = findByNameGlobals.executeQuery()) {
while (rs.next()) {
GlobalEntry entry = createGlobalEntryFromResultSet(rs);
if (entry != null) {
results.add(entry);
}
}
}
return results;
} catch (SQLException e) {
script.println("Error finding globals by name: " + e.getMessage());
throw new Exception("Failed to find globals by name", e);
}
}
public List<GlobalEntry> findGlobalsByAddress(Address address) throws Exception {
ensureConnection();
List<GlobalEntry> results = new ArrayList<>();
String addressStr = address.toString();
try {
findByAddressGlobals.setString(1, addressStr);
try (ResultSet rs = findByAddressGlobals.executeQuery()) {
while (rs.next()) {
GlobalEntry entry = createGlobalEntryFromResultSet(rs);
if (entry != null) {
results.add(entry);
}
}
}
return results;
} catch (SQLException e) {
script.println("Error finding globals by address: " + e.getMessage());
throw new Exception("Failed to find globals by address", e);
}
}
public void addGlobal(Address address, String name, String dataType) throws Exception {
ensureConnection();
String filepath = RemanConfig.GLOBAL_H_FILE; // Default filepath for globals
String addressStr = address.toString();
try {
insertOrReplaceGlobals.setString(1, filepath);
insertOrReplaceGlobals.setString(2, name);
insertOrReplaceGlobals.setString(3, addressStr);
insertOrReplaceGlobals.setString(4, dataType);
insertOrReplaceGlobals.executeUpdate();
script.println("Added/updated global: " + name + " at " + address + " with type " + dataType);
} catch (SQLException e) {
script.println("Error adding global: " + e.getMessage());
throw new Exception("Failed to add global", e);
}
}
public void removeGlobalsByFilepath(String filePath) throws Exception {
ensureConnection();
String relativePath;
// Check if filePath is already a relative path or just a filename
File inputFile = new File(filePath);
if (inputFile.isAbsolute()) {
// Convert absolute path to relative
try {
relativePath = new File(RemanConfig.INSTANCE.outputDir).toPath()
.relativize(inputFile.toPath()).toString().replace('\\', '/');
} catch (IllegalArgumentException e) {
// Fallback if paths can't be relativized (different drives, etc.)
script.println("Warning: Could not relativize path: " + filePath + ", using as-is");
relativePath = filePath.replace('\\', '/');
}
} else {
// Already relative or just a filename, use as-is
relativePath = filePath.replace('\\', '/');
}
try {
deleteByFilepathGlobals.setString(1, relativePath);
int deletedCount = deleteByFilepathGlobals.executeUpdate();
script.println("Removed " + deletedCount + " global entries for file: " + relativePath);
} catch (SQLException e) {
script.println("Error removing global entries: " + e.getMessage());
throw new Exception("Failed to remove global entries", e);
}
}
@Override
public void close() throws Exception {
this.disconnect();
}
}

View File

@ -5,7 +5,6 @@ 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;
@ -23,11 +22,11 @@ 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 re3lib.GlobalDumper.GlobalRec;
public class FunctionDumper {
GhidraScript script;
GlobalDumper globalDumper;
FunctionDatabase functionDatabase;
public HashSet<Address> functionAddrBlackList = new HashSet<>();
@ -37,8 +36,9 @@ public class FunctionDumper {
static final Pattern fieldAccessRegex = Pattern.compile("^_([0-9]+)_([0-9]+)_$");
public FunctionDumper(GhidraScript script, GlobalDumper globalDumper) {
public FunctionDumper(GhidraScript script, FunctionDatabase functionDatabase, GlobalDumper globalDumper) {
this.script = script;
this.functionDatabase = functionDatabase;
this.globalDumper = globalDumper;
initFunctionBlacklist();
}
@ -58,7 +58,7 @@ public class FunctionDumper {
}
void initFunctionBlacklist() {
functionAddrBlackList = Utils.loadFunctionBlacklist(RecompileConfig.INSTANCE.functionBlacklistPath);
functionAddrBlackList = Utils.loadFunctionBlacklist(RemanConfig.INSTANCE.functionBlacklistPath);
// Build blacklist if not loaded
if (functionAddrBlackList == null) {
@ -99,7 +99,7 @@ public class FunctionDumper {
}
if (modified) {
Utils.saveFunctionBlacklist(functionAddrBlackList, RecompileConfig.INSTANCE.functionBlacklistPath);
Utils.saveFunctionBlacklist(functionAddrBlackList, RemanConfig.INSTANCE.functionBlacklistPath);
}
}
}
@ -107,14 +107,14 @@ public class FunctionDumper {
public static boolean isDumpedFix(Function function) {
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
String fileName = sanitizedFunctionName + ".cxx";
File f0 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName);
File f0 = new File(RemanConfig.INSTANCE.dirDecompFix, fileName);
return f0.exists();
}
public static boolean isDumpedAuto(Function function) {
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
String fileName = sanitizedFunctionName + ".cxx";
File f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName);
File f0 = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName);
return f0.exists();
}
@ -123,32 +123,52 @@ public class FunctionDumper {
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
String fileName = sanitizedFunctionName + ".cxx";
// Remove the stub file, since we now use the decompiled file
File stubFile = new File(RecompileConfig.INSTANCE.dirDecompStub, fileName);
if (stubFile.exists()) {
script.println("Removing function stub " + stubFile);
stubFile.delete();
createdFile = true;
}
File f0 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName);
if (f0.exists()) {
script.println("Func " + function.getName() + " skipped (gh_fix)");
f0 = new File(RecompileConfig.INSTANCE.dirDecompRef, fileName);
} else {
f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName);
if (f0.exists()) {
f0.delete();
} else {
createdFile = true;
Address entrypoint = function.getEntryPoint();
List<FunctionDatabase.FunctionEntry> entries = functionDatabase.findEntriesByAddress(entrypoint);
FunctionDatabase.Type targetType = FunctionDatabase.Type.Auto;
for (FunctionDatabase.FunctionEntry entry : entries) {
script.println("Found existing decompiled entry at " + entry.file + " - " + entry.name);
if (targetType != FunctionDatabase.Type.Ref) {
if (entry.type == FunctionDatabase.Type.Fix) {
targetType = FunctionDatabase.Type.Ref;
}
}
if (entry.type == FunctionDatabase.Type.Stub) {
// Remove the stub file, since we now use the decompiled file
File stubFile = entry.file;
if (stubFile.exists()) {
script.println("Removing function stub " + stubFile);
stubFile.delete();
createdFile = true;
functionDatabase.removeEntryAt(entry.file.toString());
}
}
}
File targetFilename = null;
if (targetType == FunctionDatabase.Type.Ref) {
targetFilename = new File(RemanConfig.INSTANCE.dirDecompRef, fileName);
} else {
targetFilename = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName);
}
if (targetFilename.exists()) {
targetFilename.delete();
script.println("Overwriting existing file " + targetFilename);
} else {
createdFile = true;
}
File f0 = targetFilename;
script.println("Processing " + function.getName() + " => " + f0.toString());
// Update database
FunctionDatabase.FunctionEntry newEntry = new FunctionDatabase.FunctionEntry(entrypoint, function.getName(), f0,
targetType);
functionDatabase.addEntryAt(newEntry);
List<Function> externalFunctionCalls = new ArrayList<>();
DecompileResults decompRes = RecompileConfig.INSTANCE.decompCache.getOrInsert(function);
DecompileResults decompRes = RemanConfig.INSTANCE.decompCache.getOrInsert(function);
try (PrintWriter writer2 = new PrintWriter(f0, "UTF-8")) {
writer2.println("// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!! ");
writer2.println();
@ -290,16 +310,21 @@ public class FunctionDumper {
// Possibly generate stubs for external functions
for (Function externalFunction : externalFunctionCalls) {
String sanitizedExtFunctionName = Utils.sanitizeIdentifier(externalFunction.getName());
fileName = sanitizedExtFunctionName + ".cxx";
File f2 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName);
File f3 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName);
if (f2.exists() || f3.exists()) {
// script.println("Skipping external function: " + externalFunction.getName() +
// " - " + externalFunction.getEntryPoint());
continue;
}
File f4 = new File(RecompileConfig.INSTANCE.dirDecompStub, fileName);
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")) {
@ -308,15 +333,48 @@ public class FunctionDumper {
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("#include <stdexcept>");
writer2.println();
writer2.println("// " + externalFunction.getEntryPoint());
writer2.println("// " + externalFunction.getName());
writer2.println("extern \"C\" " + externalFunction.getSignature().getPrototypeString(false) + " {");
writer2.println(" // TODO: Implement this function");
writer2
.println(" throw GHStubException(\"Function not implemented: " + externalFunction.getName() + "\");");
// Parse function signature to extract calling convention, return type, and parameters
String signature = externalFunction.getSignature().getPrototypeString(false);
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("}");
}

View File

@ -25,7 +25,6 @@ import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.DataTypePath;
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;
@ -48,89 +47,64 @@ public class GlobalDumper {
};
GhidraScript script;
File manifestFile;
FunctionDatabase functionDatabase;
HashMap<Address, GlobalRec> globalAddrs = new HashMap<>();
public GlobalDumper(GhidraScript script) {
public GlobalDumper(GhidraScript script, FunctionDatabase functionDatabase) {
this.script = script;
manifestFile = new File(RecompileConfig.INSTANCE.outputDir, "globals.txt");
this.functionDatabase = functionDatabase;
}
public void removeGlobalManifest() {
if (manifestFile.exists()) {
manifestFile.delete();
// Remove globals from database instead of file
try {
functionDatabase.removeGlobalsByFilepath(RemanConfig.INSTANCE.GLOBAL_H_FILE);
globalAddrs.clear();
} catch (Exception e) {
script.println("Error removing global manifest: " + e.getMessage());
}
}
public boolean loadGlobalManifest() throws Exception {
// Globals are stored in the format of
// <address> || <name> || <type>
if (!manifestFile.exists()) {
script.println("Global manifest file not found: " + manifestFile);
return false;
}
// Get the dataTypeManagerService
globalAddrs.clear();
// Load globals from database
List<FunctionDatabase.GlobalEntry> dbGlobals = functionDatabase.loadAllGlobals();
// Get the dataTypeManagerService for parsing types
DataTypeManagerService dataTypeManagerService = (DataTypeManagerService) script.getState().getTool()
.getService(DataTypeManagerService.class);
DataTypeManager dtm = script.getCurrentProgram().getDataTypeManager();
DataTypeParser dtp = new DataTypeParser(dataTypeManagerService, AllowedDataTypes.ALL);
try (BufferedReader reader = new BufferedReader(new FileReader(manifestFile))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split("\\|\\|");
if (parts.length == 4) {
Address address = script.parseAddress(parts[0].trim());
String name = parts[1].trim();
String categoryPath = parts[2].trim();
String dataTypePath = parts[3].trim();
DataTypePath typePath = new DataTypePath(categoryPath, dataTypePath);
DataType type = null;
type = dtm.getDataType(typePath);
if (type == null) {
// script.println("Parsing type: " + dataTypePath);
type = dtp.parse(dataTypePath);
}
if (type == null) {
script.println("WARNING: Failed to find type: " + dataTypePath + " for global: " + name + " at " + address);
continue;
}
globalAddrs.put(address, new GlobalRec(address, name, type));
} else {
script.println("Invalid global manifest line: " + line);
}
}
}
script.println("Loaded " + globalAddrs.size() + " globals from " + manifestFile);
return true;
}
public void addGlobal(Address addr, HighSymbol sym) throws Exception {
if (addr.compareTo(RecompileConfig.INSTANCE.staticMemoryBlockStart) < 0
|| addr.compareTo(RecompileConfig.INSTANCE.staticMemoryBlockEnd) > 0) {
throw new Exception("Global address out of range: " + addr);
}
DataType dt = sym.getDataType();
// if(symb.get
if (sym.getDataType().getName() == "undefined") {
// script.println("UNDEFINED: " + addr + " - " + dt.getDisplayName() + " - " +
// dt.getClass().getName());
Data data = script.getDataAt(addr);
for (FunctionDatabase.GlobalEntry entry : dbGlobals) {
// Note: The database stores type as string, need to reconstruct DataType
// For now, we'll parse it back from the type string stored in database
// This is a limitation of moving from the manifest format
DataType type = null;
// Try to get from existing data at address
Data data = script.getDataAt(entry.address);
if (data != null) {
dt = data.getDataType();
// script.println("DATA: " + addr + " - " + dt.getDisplayName());
type = data.getDataType();
}
if (type == null) {
script.println("WARNING: Could not reconstruct type for global: " + entry.name + " at " + entry.address);
type = dtp.parse("undefined4");
}
// Retrieve the name again
Symbol sym = script.getSymbolAt(entry.address);
if (sym != null) {
entry.name = sym.getName();
}
globalAddrs.put(entry.address, new GlobalRec(entry.address, entry.name, type));
}
if (dt == null) {
script.println("WARNING: Missing type for global: " + sym.getName() + " at " + addr);
return;
}
// script.println("Global: " + addr + " - " + sym.getName() + " - " +
// dt.getDisplayName());
globalAddrs.put(addr, new GlobalRec(addr, sym.getName(), dt));
script.println("Loaded " + globalAddrs.size() + " globals from database");
return !globalAddrs.isEmpty();
}
String escapeCString(String str) {
@ -162,14 +136,14 @@ public class GlobalDumper {
}
public void dumpGlobals() throws Exception {
File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h");
File globalSymbolsListH = new File(RemanConfig.INSTANCE.outputDir, RemanConfig.GLOBAL_H_FILE);
PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8");
hwriter.println("// AUTO-GENERATED FILE ");
Utils.headerGuardPre(hwriter, "GLOBALS");
hwriter.println("#include <r3/binders/global.h>");
hwriter.println();
File globalSymbolsListC = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.cxx");
File globalSymbolsListC = new File(RemanConfig.INSTANCE.outputDir, RemanConfig.GLOBAL_CXX_FILE);
PrintWriter cwriter = new PrintWriter(globalSymbolsListC, "UTF-8");
cwriter.println("// AUTO-GENERATED FILE ");
cwriter.println("#include <r3/binders/global.h>");
@ -244,28 +218,47 @@ public class GlobalDumper {
}
public void saveGlobalManifest() throws Exception {
File backupFile = new File(manifestFile.getParentFile(), manifestFile.getName() + ".bak");
if (backupFile.exists()) {
if (!backupFile.delete()) {
throw new Exception("Failed to delete backup file: " + backupFile + ", globals will not be saved!");
}
}
// Save globals to database instead of file
script.println("Saving globals to database");
if (manifestFile.exists()) {
if (!manifestFile.renameTo(backupFile))
throw new Exception("Failed to rename manifest file: " + manifestFile + ", globals will not be saved!");
// Clear existing globals for the default filepath
functionDatabase.removeGlobalsByFilepath(RemanConfig.GLOBAL_H_FILE);
// Add all current globals to database
for (GlobalRec global : globalAddrs.values()) {
String dataTypeName = global.type.getDisplayName();
functionDatabase.addGlobal(global.address, global.name, dataTypeName);
}
}
public void addGlobal(Address addr, HighSymbol sym) throws Exception {
if (sym.getName().equals("ExceptionList")) {
return;
}
try (PrintWriter writer = new PrintWriter(manifestFile)) {
script.println("Saving global manifest to " + manifestFile);
GlobalRec[] globals = globalAddrs.values().toArray(new GlobalRec[0]);
Arrays.sort(globals, (a, b) -> a.address.compareTo(b.address));
for (GlobalRec global : globals) {
DataTypePath path = global.type.getDataTypePath();
writer.println(global.address.toString() + " || " + global.name + " || " + path.getCategoryPath() + " || "
+ path.getDataTypeName());
if (addr.compareTo(RemanConfig.INSTANCE.staticMemoryBlockStart) < 0
|| addr.compareTo(RemanConfig.INSTANCE.staticMemoryBlockEnd) > 0) {
throw new Exception("Global address out of range: " + addr);
}
DataType dt = sym.getDataType();
// if(symb.get
if (sym.getDataType().getName() == "undefined") {
// script.println("UNDEFINED: " + addr + " - " + dt.getDisplayName() + " - " +
// dt.getClass().getName());
Data data = script.getDataAt(addr);
if (data != null) {
dt = data.getDataType();
// script.println("DATA: " + addr + " - " + dt.getDisplayName());
}
}
if (dt == null) {
script.println("WARNING: Missing type for global: " + sym.getName() + " at " + addr);
return;
}
// script.println("Global: " + addr + " - " + sym.getName() + " - " +
// dt.getDisplayName());
globalAddrs.put(addr, new GlobalRec(addr, sym.getName(), dt));
}
public void sanitizeGlobalSymbols() {
@ -287,3 +280,4 @@ public class GlobalDumper {
}
}
}

View File

@ -42,7 +42,7 @@ public class PCallTracer {
Program program;
public PCallTracer() {
this.script = RecompileConfig.INSTANCE.script;
this.script = RemanConfig.INSTANCE.script;
this.program = this.script.getCurrentProgram();
// this.decomp = RecompileConfig.INSTANCE.decompCache;
}

View File

@ -10,7 +10,9 @@ import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
public class RecompileConfig {
// A general configuration for the reman project
// including all paths, specific addresses and stuff
public class RemanConfig {
private static final String RECOMPILE_PREFIX = "game_re";
// Version control project root
@ -24,6 +26,9 @@ public class RecompileConfig {
public final Address staticMemoryBlockStart;
public final Address staticMemoryBlockEnd;
// The path to the database file
public final File databasePath;
// The automatically decompiled files
public final File dirDecompAuto;
// The manually decompiled files (will not be overwritten by the auto
@ -48,10 +53,13 @@ public class RecompileConfig {
public final GhidraScript script;
public static RecompileConfig INSTANCE;
public static RemanConfig INSTANCE;
public RecompileConfig(GhidraScript script) {
staticMemoryBlockStart = script.getCurrentProgram().getAddressFactory().getAddress("00597000");
public static final String GLOBAL_H_FILE = "gh_global.h"; // Default filepath for globals
public static final String GLOBAL_CXX_FILE = "gh_global.cxx"; // Default filepath for globals
public RemanConfig(GhidraScript script) {
staticMemoryBlockStart = script.getCurrentProgram().getAddressFactory().getAddress("00400000");
staticMemoryBlockEnd = script.getCurrentProgram().getAddressFactory().getAddress("00843fff");
this.script = script;
@ -64,6 +72,8 @@ public class RecompileConfig {
categoryPathBlacklistPath = new File(outputDir, "type_path_blacklist.txt").toString();
functionBlacklistPath = new File(outputDir, "function_blacklist.txt").toString();
databasePath = new File(outputDir, "gh.db");
dirDecompAuto = new File(outputDir, "gh_auto");
dirDecompFix = new File(outputDir, "gh_fix");
dirDecompRef = new File(outputDir, "gh_ref");

View File

@ -11,11 +11,15 @@ import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.Composite;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Enum;
import ghidra.program.model.data.EnumDataType;
import ghidra.program.model.data.FunctionDefinition;
import ghidra.program.model.data.ProgramBasedDataTypeManager;
import ghidra.program.model.data.Structure;
import ghidra.program.model.data.TypeDef;
import ghidra.program.model.data.TypedefDataType;
import ghidra.program.model.data.Union;
import ghidra.program.model.data.UnionDataType;
import ghidra.program.model.listing.Program;
public class TypeDumper {
@ -25,15 +29,15 @@ public class TypeDumper {
public TypeDumper(GhidraScript script) {
this.script = script;
currentProgram = script.getCurrentProgram();
RecompileConfig.INSTANCE = new RecompileConfig(script);
RemanConfig.INSTANCE = new RemanConfig(script);
}
public void run() throws Exception {
ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager();
HashSet<String> typeBlacklist = Utils.loadSimpleBlacklist(RecompileConfig.INSTANCE.typeBlacklistPath);
HashSet<String> typeBlacklist = Utils.loadSimpleBlacklist(RemanConfig.INSTANCE.typeBlacklistPath);
HashSet<String> categoryPathBlacklist = Utils
.loadSimpleBlacklist(RecompileConfig.INSTANCE.categoryPathBlacklistPath);
.loadSimpleBlacklist(RemanConfig.INSTANCE.categoryPathBlacklistPath);
if (typeBlacklist == null) {
script.println("Building struct blacklist from existing data types");
@ -45,7 +49,7 @@ public class TypeDumper {
typeBlacklist.add(dt.getDisplayName());
}
}
Utils.saveStructBlacklist(typeBlacklist, RecompileConfig.INSTANCE.typeBlacklistPath);
Utils.saveStructBlacklist(typeBlacklist, RemanConfig.INSTANCE.typeBlacklistPath);
}
List<DataType> filteredTypes = new ArrayList<>();
@ -74,32 +78,41 @@ public class TypeDumper {
Iterator<DataType> it = dtm.getAllDataTypes();
while (it.hasNext()) {
DataType dt = it.next();
if (typeBlacklist.contains(dt.getDisplayName()))
continue;
CategoryPath catPath = dt.getCategoryPath();
if (catPath.getPathElements().length > 0 && categoryPathBlacklist.contains(catPath.getPathElements()[0]))
continue;
// script.println("Type: " + dt.getDisplayName() + " - CatPath: " + dt.getCategoryPath());
if (dt instanceof Structure || dt instanceof TypeDef || dt instanceof EnumDataType
|| dt instanceof Union || dt instanceof Enum || dt instanceof FunctionDefinition) {
// if (dt.getName().equals("ImageBaseOffset32"))
// throw new Exception("Found: " + dt.getDisplayName() + " - " + catPath.getPathElements()[0] + " - " + dt.getClass().getSimpleName());
if (dt.getDisplayName().contains("NormalizeFn") || dt.getDisplayName().contains("_M_IX86"))
script.println("DEBUG " + dt.getDisplayName() + " - " + dt.getClass().getSimpleName());
// if (dt.getDisplayName().contains("tdstObjectTypeElement_") ||
// dt.getDisplayName().contains("ObjectTypeElementHandle"))
if (dt instanceof Structure || dt instanceof TypeDef || dt instanceof EnumDataType) {
// script.println("Adding: " + dt.getDisplayName() + " - " +
// dt.getClass().getSimpleName());
filteredTypes.add(dt);
}
// }
}
try (PrintWriter writer = new PrintWriter(new File(RecompileConfig.INSTANCE.outputDir, "gh_types.h"),
// String s = "";
// for (DataType dataType : filteredTypes) {
// s += dataType.getDisplayName() + ", ";
// }
// script.println(s);
try (PrintWriter writer = new PrintWriter(new File(RemanConfig.INSTANCE.outputDir, "gh_types.h"),
"UTF-8")) {
Utils.headerGuardPre(writer, "STRUCTS");
writer.println("// AUTO-GENERATED FILE ");
writer.println("#include <r3/binders/type.h>");
DataTypeWriter dtw = new DataTypeWriter(dtm, writer);
dtw.blacklistedTypes = typeBlacklist;
dtw.write(filteredTypes, script.getMonitor());
Utils.headerGuardPost(writer, "STRUCTS");

View File

@ -51,7 +51,7 @@ public class Utils {
}
public static HashSet<Address> loadFunctionBlacklist(String path) {
GhidraScript script = RecompileConfig.INSTANCE.script;
GhidraScript script = RemanConfig.INSTANCE.script;
HashSet<Address> fnBlacklist = new HashSet<>();
File blacklistFile = new File(path);
try (Scanner scanner = new Scanner(blacklistFile)) {
@ -60,7 +60,7 @@ public class Utils {
// Strip comment
String line1 = line.split("//")[0].trim();
// Deserialize address
Address addr = RecompileConfig.INSTANCE.currentProgram.getAddressFactory().getAddress(line1);
Address addr = RemanConfig.INSTANCE.currentProgram.getAddressFactory().getAddress(line1);
fnBlacklist.add(addr);
}
script.println("Loaded blacklist with " + fnBlacklist.size() + " entries");
@ -71,7 +71,7 @@ public class Utils {
}
public static void saveFunctionBlacklist(HashSet<Address> fnBlacklist, String path) {
GhidraScript script = RecompileConfig.INSTANCE.script;
GhidraScript script = RemanConfig.INSTANCE.script;
File blacklistFile = new File(path);
try (PrintWriter writer = new PrintWriter(blacklistFile)) {
for (Address addr : fnBlacklist) {

View File

@ -11,3 +11,63 @@ The decompile database is a sqlite database that contains a list of all files th
To generate the database from the current set of files, run the scan_sources script in the /game_re folder.
Make sure you have set up the tooling by running the /tooling/setup script.
## IDE Notes
This should work with the redhat java plugin for vscode, you however need to manually add the referenced libraries to the settings, like so:
```json
{
"java.project.referencedLibraries": [
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Base\\lib\\Base.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Decompiler\\lib\\Decompiler.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\BSim\\lib\\BSim.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\BSimFeatureVisualizer\\lib\\BSimFeatureVisualizer.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Base\\lib\\Base.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\BytePatterns\\lib\\BytePatterns.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\ByteViewer\\lib\\ByteViewer.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\CodeCompare\\lib\\CodeCompare.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\DebugUtils\\lib\\DebugUtils.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Decompiler\\lib\\Decompiler.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\DecompilerDependent\\lib\\DecompilerDependent.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FileFormats\\lib\\FileFormats.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FunctionGraph\\lib\\FunctionGraph.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FunctionGraphDecompilerExtension\\lib\\FunctionGraphDecompilerExtension.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FunctionID\\lib\\FunctionID.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GhidraGo\\lib\\GhidraGo.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GhidraServer\\lib\\GhidraServer.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GnuDemangler\\lib\\GnuDemangler.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GraphFunctionCalls\\lib\\GraphFunctionCalls.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GraphServices\\lib\\GraphServices.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\MicrosoftCodeAnalyzer\\lib\\MicrosoftCodeAnalyzer.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\MicrosoftDemangler\\lib\\MicrosoftDemangler.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\MicrosoftDmang\\lib\\MicrosoftDmang.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\PDB\\lib\\PDB.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\ProgramDiff\\lib\\ProgramDiff.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\ProgramGraph\\lib\\ProgramGraph.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Python\\lib\\Python.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Recognizers\\lib\\Recognizers.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Sarif\\lib\\Sarif.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\SourceCodeLookup\\lib\\SourceCodeLookup.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\SwiftDemangler\\lib\\SwiftDemangler.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\SystemEmulation\\lib\\SystemEmulation.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\VersionTracking\\lib\\VersionTracking.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\VersionTrackingBSim\\lib\\VersionTrackingBSim.jar",
"C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\WildcardAssembler\\lib\\WildcardAssembler.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\DB\\lib\\DB.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Docking\\lib\\Docking.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Emulation\\lib\\Emulation.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\FileSystem\\lib\\FileSystem.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Generic\\lib\\Generic.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Graph\\lib\\Graph.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Gui\\lib\\Gui.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Help\\lib\\Help.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Project\\lib\\Project.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Pty\\lib\\Pty.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\SoftwareModeling\\lib\\SoftwareModeling.jar",
"c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Utility\\lib\\Utility.jar",
"c:\\Projects\\R3\\java\\ghidra\\sqlite-jdbc-3.49.1.0.jar"
]
}
```

View File

@ -13,10 +13,18 @@ CREATE TABLE Functions (
filepath TEXT,
name TEXT,
address TEXT,
type INTEGER,
PRIMARY KEY (name, filepath)
);
```
Where type is one of the following:
- 0: Auto
- 1: Fix
- 2: Stub
- 3: Ref
**Purpose**: Stores function definitions that have function bodies (actual implementations)
- `filepath`: Source file path where the function is defined
- `name`: Function name (identifier)
@ -29,6 +37,7 @@ CREATE TABLE Imports (
filepath TEXT,
name TEXT,
address TEXT,
type INTEGER,
PRIMARY KEY (name, filepath)
);
```