Begin contributing.md

This commit is contained in:
KeybadeBlox 2025-12-17 10:26:34 -05:00
parent 1a48d4323e
commit 21c3864bb7
2 changed files with 140 additions and 1 deletions

137
contributing.md Normal file
View file

@ -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

View file

@ -9,7 +9,7 @@ main() {
project_path=$2 project_path=$2
project_name=$3 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 while IFS= read -r line; do # Read objects.csv line by line
# Split columns (col 1 in $1, col 2 in $2, etc.) # 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" delink "$ghidra_path" "$project_path" "$project_name" "$*" "$object_name"
fi fi
done < objects.csv done < objects.csv
printf '\nDelinking complete!\n'
} }
usage() { usage() {