From fe20d64d278dd650d5da00e705989075ed4c4c45 Mon Sep 17 00:00:00 2001 From: KeybadeBlox Date: Sun, 14 Dec 2025 22:53:33 -0500 Subject: [PATCH] Add delink POSIX script Also reworked the directory structure a little. --- objdiff/Makefile => Makefile | 0 delink.sh | 63 ++++++++++++++++++++++++++++ objdiff/objdiff.json => objdiff.json | 0 objects.csv | 28 ++++++------- readme.md | 4 ++ {objdiff/src => src}/Core.cpp | 0 {objdiff/src => src}/Core.hpp | 0 {objdiff/src => src}/D3D.hpp | 0 {objdiff/src => src}/Jet2.cpp | 0 {objdiff/src => src}/MMatrix.cpp | 0 {objdiff/src => src}/MMatrix.hpp | 0 {objdiff/src => src}/Std.hpp | 0 {objdiff/src => src}/Win32.hpp | 0 {objdiff/target => target}/.gitkeep | 0 14 files changed, 81 insertions(+), 14 deletions(-) rename objdiff/Makefile => Makefile (100%) create mode 100755 delink.sh rename objdiff/objdiff.json => objdiff.json (100%) rename {objdiff/src => src}/Core.cpp (100%) rename {objdiff/src => src}/Core.hpp (100%) rename {objdiff/src => src}/D3D.hpp (100%) rename {objdiff/src => src}/Jet2.cpp (100%) rename {objdiff/src => src}/MMatrix.cpp (100%) rename {objdiff/src => src}/MMatrix.hpp (100%) rename {objdiff/src => src}/Std.hpp (100%) rename {objdiff/src => src}/Win32.hpp (100%) rename {objdiff/target => target}/.gitkeep (100%) diff --git a/objdiff/Makefile b/Makefile similarity index 100% rename from objdiff/Makefile rename to Makefile diff --git a/delink.sh b/delink.sh new file mode 100755 index 0000000..6f4ab57 --- /dev/null +++ b/delink.sh @@ -0,0 +1,63 @@ +#!/bin/sh -eu +# Script to produce delinked object files in target/ directory from objects.csv +# and a Ghidra project via boricj's delinker extension + +main() { + if [ $# -ne 3 ]; then usage; fi + + ghidra_path=$1 + project_path=$2 + project_name=$3 + + printf '=== Delinking object files ===\n' + + while IFS= read -r line; do # Read objects.csv line by line + # Split columns (col 1 in $1, col 2 in $2, etc.) + set -f; IFS_PREV=$IFS; IFS=, + set -- $line + set +f; IFS=$IFS_PREV + + if [ "$2" == true ]; then # If object is marked for extraction + object_name=$1 + printf '\n--- %s ---\n' "$object_name" + + # Delete object name and delink toggle positional + # arguments, leaving only address ranges + shift 2 + + # Call Ghidra delinker script + delink "$ghidra_path" "$project_path" "$project_name" "$*" "$object_name" + fi + done < objects.csv +} + +usage() { + printf '%s\n'\ + 'Usage: delink.sh GHIDRA_PATH PROJECT_PATH PROJECT_NAME'\ + ' GHIDRA_PATH is the path to your Ghidra installation'\ + ' PROJECT_PATH is the path to your JSRF Ghidra project'\ + ' PROJECT_NAME is the name of your JSRF Ghidra project'\ + ''\ + 'Populates the target/ directory with delinked object files using the address'\ + 'ranges given in objects.csv.' >& 2 + exit 2 +} + +delink() { +# Invoke headless Ghidra with the delinker script to produce an object file +# $1: Ghidra installation path +# $2: Ghidra project path +# $3: Ghidra project name +# $4: Whitespace-separated address ranges to include in object +# $5: Output path (inside /target) + "$1/support/analyzeHeadless.bat" "$2" "$3"\ + -process default.xbe\ + -noanalysis\ + -postScript DelinkProgram.java\ + /exporter 'COFF relocatable object'\ + $(printf "/include-range %s " $4)\ + /export "target/$5" +} + + +main "$@" diff --git a/objdiff/objdiff.json b/objdiff.json similarity index 100% rename from objdiff/objdiff.json rename to objdiff.json diff --git a/objects.csv b/objects.csv index 1e92406..4589f51 100644 --- a/objects.csv +++ b/objects.csv @@ -1,14 +1,14 @@ -Object,.text,.text$x,D3D,DSOUND,MMATRIX,XGRPH,XPP,.rdata,.rdata$x,.data,DOLBY -Core.obj,0x00011000-0x00013FF0,0x00186BA0-0x00186C1F,,,,,,0x001C4390-0x001C44FF,0x001E4D20-0x001E4DAB,0x00251D40-0x00251DAB, -Jet2.obj,0x0006F9E0-0x0006FA6F,0x00187710-0x0018772F,,,,,,,0x001E620C-0x001E622F,0x0022FCE0-0x0022FCE7, -ADX (need to decompose),0x0013A570-0x0014555F,?,,,,,,?,?,?, -XDK Core (need to decompose),0x00145560-0x0014B79F,?,,,,,,?,?,?, -Smilebit libs (need to decompose),0x0014B7A0-0x0017BF3F,?,,,,,,?,?,?-0x0022ED2B, -C runtime,0x0017BF40-0x00182B80,?,,,,,,?,?,0x0022ED2C-?, -Unknown MS math lib,0x00182B81-0x0018694F,?,,,,,,?,?,?, -Another (tiny) Smilebit math lib,0x00186950-0x00186B7F,?,,,,,,?,?,?, -Direct3D8 (need to decompose),,,0x0018CB40-0x0019E334,,,,,?,?,?, -DirectSound8 (need to decompose),,,,0x0019E340-0x001BA89B,,,,?,?,?,0x0027E080-0x00284E17 -MMatrix.obj,,,,,0x001BA8A0-0x001BBAAF,,,,,0x00264BD8-0x00264C13, -Xgraphics (need to decompose),,,,,,0x001BBAC0-0x001BC7BB,,,,, -XDK Peripherals,,,,,,,0x001BC7C0-0x001C3F57,,,, +Object,Delink?,.text,.text$x,D3D,DSOUND,MMATRIX,XGRPH,XPP,.rdata,.rdata$x,.data,DOLBY +Core.obj,false,0x00011000-0x00013FF0,0x00186BA0-0x00186C1F,,,,,,0x001C4390-0x001C44FF,0x001E4D20-0x001E4DAB,0x00251D40-0x00251DAB, +Jet2.obj,true,0x0006F9E0-0x0006FA6F,0x00187710-0x00187724,,,,,,,0x001E620C-0x001E622F,0x0022FCE0-0x0022FCE7, +ADX (need to decompose),false,0x0013A570-0x0014555F,?,,,,,,?,?,?, +XDK Core (need to decompose),false,0x00145560-0x0014B79F,?,,,,,,?,?,?, +Smilebit libs (need to decompose),false,0x0014B7A0-0x0017BF3F,?,,,,,,?,?,?-0x0022ED2B, +C runtime,false,0x0017BF40-0x00182B80,?,,,,,,?,?,0x0022ED2C-?, +Unknown MS math lib,false,0x00182B81-0x0018694F,?,,,,,,?,?,?, +Another (tiny) Smilebit math lib,false,0x00186950-0x00186B7F,?,,,,,,?,?,?, +Direct3D8 (need to decompose),false,,,0x0018CB40-0x0019E334,,,,,?,?,?, +DirectSound8 (need to decompose),false,,,,0x0019E340-0x001BA89B,,,,?,?,?,0x0027E080-0x00284E17 +MMatrix.obj,false,,,,,0x001BA8A0-0x001BBAAF,,,,,0x00264BD8-0x00264C13, +Xgraphics (need to decompose),false,,,,,,0x001BBAC0-0x001BC7BB,,,,, +XDK Peripherals,false,,,,,,,0x001BC7C0-0x001C3F57,,,, diff --git a/readme.md b/readme.md index 99f1b74..7fcee00 100644 --- a/readme.md +++ b/readme.md @@ -6,6 +6,10 @@ the JSRF decompilation effort. The addresses given in each section are runtime memory addresses (as one would see in e.g. Ghidra). +`delink.sh` and `delink.ps1` are scripts for Unix-like and Windows systems +respectively to produced delinked object files in `target/` from a Ghidra +project. + The `src/` directory contains decompiled code and data. Each symbol is annotated with its corresponding memory address in the original binary, and functions are marked as perfectly or imperfectly matching. It's not diff --git a/objdiff/src/Core.cpp b/src/Core.cpp similarity index 100% rename from objdiff/src/Core.cpp rename to src/Core.cpp diff --git a/objdiff/src/Core.hpp b/src/Core.hpp similarity index 100% rename from objdiff/src/Core.hpp rename to src/Core.hpp diff --git a/objdiff/src/D3D.hpp b/src/D3D.hpp similarity index 100% rename from objdiff/src/D3D.hpp rename to src/D3D.hpp diff --git a/objdiff/src/Jet2.cpp b/src/Jet2.cpp similarity index 100% rename from objdiff/src/Jet2.cpp rename to src/Jet2.cpp diff --git a/objdiff/src/MMatrix.cpp b/src/MMatrix.cpp similarity index 100% rename from objdiff/src/MMatrix.cpp rename to src/MMatrix.cpp diff --git a/objdiff/src/MMatrix.hpp b/src/MMatrix.hpp similarity index 100% rename from objdiff/src/MMatrix.hpp rename to src/MMatrix.hpp diff --git a/objdiff/src/Std.hpp b/src/Std.hpp similarity index 100% rename from objdiff/src/Std.hpp rename to src/Std.hpp diff --git a/objdiff/src/Win32.hpp b/src/Win32.hpp similarity index 100% rename from objdiff/src/Win32.hpp rename to src/Win32.hpp diff --git a/objdiff/target/.gitkeep b/target/.gitkeep similarity index 100% rename from objdiff/target/.gitkeep rename to target/.gitkeep