From 21c3864bb77e256d5046f93634eaae8720f2dcbb Mon Sep 17 00:00:00 2001 From: KeybadeBlox Date: Wed, 17 Dec 2025 10:26:34 -0500 Subject: [PATCH] Begin contributing.md --- contributing.md | 137 +++++++++++++++++++++++++++++++++++++++++++++++ delink/delink.sh | 4 +- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 contributing.md diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..aa0ed4f --- /dev/null +++ b/contributing.md @@ -0,0 +1,137 @@ +# Getting Started +Anybody is welcome to contribute to the decompilation effort! There are two +main roles a contributor can fulfill: + +- *Delinking*, which entails analyzing the JSRF executable in-situ to figure + out how to break it up into small chunks of code and data, and +- *Decompiling*, which is writing C++ code that compiles down to the same code + and data found in those chunks. + +Of these two tasks, the latter is more accessible and benefits more from a +large group of volunteers, so we'll begin there. Those who want to participate +in the delinking effort can follow the decompilation guide and then continue on +to the delinking guide afterwards. + + +## Setting Up Decompilation +You'll need a few things to get a decompilation workflow ready: + +- The JSRF executable (`default.xbe` in the root directory of the game disc) to + provide the target compiled code to match +- The Microsoft Visual C++ 7.0 (AKA Visual C++ .NET 2002) compiler to compile + your C++ code + - You'll also want to add its `Bin/` directory to your `PATH` so that objdiff + can find it +- The [Git](https://git-scm.com/) version control tool to clone and work on + this repository +- The [Ghidra](https://github.com/NationalSecurityAgency/ghidra) reverse + engineering tool to analyze and browse the executable +- The [XBE extension](https://github.com/XboxDev/ghidra-xbe) for Ghidra to + import and analyze the JSRF executable +- The [delinker extension](https://github.com/boricj/ghidra-delinker-extension) + for Ghidra to export object files from the executable +- The [objdiff](https://github.com/encounter/objdiff) code diffing tool to + compare your C++ code's compiled output to the delinked object files + +Keep in mind that Ghidra and its extensions need to have their versions +coordinated. The safest thing to do is to get the same version of each, e.g. +11.4. The general flow for installing extensions is to download a release +`.zip` for the extension from the linked repository's releases page, open +Ghidra, open the `File > Install Extensions` menu, click the green plus at the +top right of the extensions window, and then select the `.zip` you just +downloaded. Make sure the box to the left of the extension's name is checked +to enable it before clicking "OK" to close the extensions window. + +With all these tools acquired, the last thing to get is this repository. Clone +it with `git` in the usual fashion: +``` +git clone https://codeberg.org/KeybadeBlox/JSRF-Decomp-Notes.git +``` + +The following sections detail how to use all these tools to start writing +decompiled code. + + +### Creating a JSRF Ghidra Project +Even if you have no intention of analyzing the executable in Ghidra otherwise, +Ghidra is needed to produce the object files that objdiff will compare your +recompiled code against. This section will only cover the steps needed to get +to that point. + +Open Ghidra and create a new project (`File > New Project...`). Select the +"Non-Shared Project" option, and set whatever location and name you'd like. +With the project created, open the file import dialogue +(`File > Import File...`) and select the `default.xbe` from JSRF. Ensure that +the format in the next window is set to "Xbox Executable Format (XBE)" (if this +isn't an option, you need to install/enable the XBE extension), and that the +name is "default.xbe" (our tooling depends on it having this specific name). +Click "OK," and you should see a window with a successful import results +summary after a moment (you'll probably see the message +`[xboxkrnl.exe] -> not found in project`, but this is fine and expected). + +`default.xbe` should now be visible in the file listing for the project. +Double click it to open it in the CodeBrowser. The window that opens is where +you'll do all your in-situ analysis, should you choose to do so. You'll be +asked whether you want to run analyzers, which is strongly recommended unless +you're certain you won't be using Ghidra for anything else. If you do run the +analyzers, simply clicking "Analyze" in the analysis options window without +changing anything is fine, and the analysis will probably take a couple +minutes. + +Now we'll import symbols from the JSRF decompilation repository. After running +or skipping the analysis, open the script manager (`Window > Script Manager`) +and select the "Data" folder in the left pane. Double click the script titled +`ImportSymbolsScript.py`, and a file picker will open after a moment. Select +`symboltable.tsv` from the `delink/` directory of your cloned JSRF +decompilation repository, and you should see a bunch of `Created function...` +and `Created label...` in the scripting console window. Save your changes +(save icon in the top left of the CodeBrowser window), and your Ghidra project +should be all ready for creating object files for objdiff. + + +### Producing Object Files +Close all of your Ghidra windows and open a shell in the decompilation +repository's `delink/` directory. The `delink.sh` script is our automated tool +for extracting all the object files that have been identified so far. Invoke +it with three arguments: + +- The path to your Ghidra installation (the directory with files like + `ghidraRun` and `ghidraRun.bat`, and directories like `docs/` and + `Extensions/` +- The path to your JSRF Ghidra project (the directory with a `.gpr` file and a + directory with a name ending in `.rep`) +- The name of your JSRF Ghidra project + +There are two common errors you might get here: + +- `Unable to lock project!`: This means that Ghidra isn't fully closed. Make + sure you've completely closed every Ghidra window before running `delink.sh`. +- `Script not found: DelinkProgram.java` and + `Invalid script: DelinkProgram.java`: This means that the Ghidra delinker + extension isn't properly installed. Ensure it's installed and enabled first. + +If all goes well, you'll see the message `Delinking complete!` at the end of +the script's output, and the extracted object files will be in the +`decompile/target/` directory of the repository. Now we're ready to start +recompiling and diffing code with objdiff. + + +### Setting Up objdiff +Open the objdiff GUI program (by default named something like +`objdiff-os-arch`, e.g. `objdiff-windows-x86_64.exe`). Click "Settings" in the +left sidebar and then "Select" next to "Project directory" in the popup window. +In the file picker, select the `decompile/` directory in the JSRF decompilation +repository. + +The sidebar will now have a listing of all the extracted object files. Click +on one, and you should see two panes: one on the left labelled "Target object" +that lists the contents of the extracted object file, and one on the right +listing the contents of the recompiled object file. If the right pane displays +an error like "program not found," the Visual C++ 7.0 compiler probably wasn't +correctly set up on your `PATH`. + + +### Using objdiff + + +## Contrbuting to Delinking diff --git a/delink/delink.sh b/delink/delink.sh index c15691a..56a4d65 100755 --- a/delink/delink.sh +++ b/delink/delink.sh @@ -9,7 +9,7 @@ main() { project_path=$2 project_name=$3 - printf '=== Delinking object files ===\n' + printf '=== Delinking object files into ../decompile/target/ ===\n' while IFS= read -r line; do # Read objects.csv line by line # Split columns (col 1 in $1, col 2 in $2, etc.) @@ -29,6 +29,8 @@ main() { delink "$ghidra_path" "$project_path" "$project_name" "$*" "$object_name" fi done < objects.csv + + printf '\nDelinking complete!\n' } usage() {