Skip to content

Commit

Permalink
ghidra: update readme with single/all mode and list function options
Browse files Browse the repository at this point in the history
  • Loading branch information
kumarak authored and xlauko committed Sep 20, 2024
1 parent 0285d81 commit e2de71a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 19 deletions.
5 changes: 1 addition & 4 deletions scripts/ghidra/PatchestryDecompileFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,10 @@ private List<Function> getAllFunctions() {

private void decompileSingleFunction() throws Exception {
if (getScriptArgs().length < 3) {
throw new IllegalArgumentException("Insufficient arguments. Expected: <function_name> <output_file>");
throw new IllegalArgumentException("Insufficient arguments. Expected: <function_name> <output_file> as argument");
}
String functionNameArg = getScriptArgs()[1];
String outputFilePath = getScriptArgs()[2];
println("OutputFilePath: " + outputFilePath);
final var functions = getGlobalFunctions(functionNameArg);
if (functions.isEmpty()) {
println("Function not found: " + functionNameArg);
Expand Down Expand Up @@ -275,8 +274,6 @@ private void decompileSingleFunctionInGUI() throws Exception {
println("Warning: Found more than one function named: " + functionNameArg);
}

println("Serializing function: " + functions.get(0).getName() + " @ " + functions.get(0).getEntryPoint());

// Serialize to the file
serializeToFile(outputFilePath.toPath(), functions);
}
Expand Down
21 changes: 16 additions & 5 deletions scripts/ghidra/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Decompilation Framework

The directory includes a decompilation script that runs Ghidra in headless mode to extract pcode for specific functions from binary files.
The directory contains a script that runs Ghidra in headless mode to
decompile binary files, identifying and listing all functions while
extracting their corresponding pcode.

We support two decompilation modes:

Expand All @@ -17,12 +19,19 @@ To perform headless decompilation, you need to build a Docker container (`decomp

## Running Headless Decompilation Script

To decompile and extract pcode for a specific function from a binary file, use
the `decompile-headless.sh` script. This script extracts the pcode for the
specified function and writes the json output to a file named `<output-file>`.
The `decompile-headless.sh` script decompiles a binary file using Ghidra
in headless mode, extracting pcode for either a specific function or all
functions by default, and saving the output as json to a specified file `<output-file>`.

To extract P-code for a particular function, use the `--function` flag; otherwise,
it decompiles all functions if no function name is specified.

```sh ./decompile-headless.sh --input <binary> --function <function-name> --output <output-file> ```

The script also list all functions in the binary using the `--list-functions` flag.

```sh ./decompile-headless.sh --input <binary> --list-functions --output <output-file> ```

## Running Patchestry via Ghidra GUI

1. Ensure Patchestry is available via PATH:
Expand All @@ -37,6 +46,8 @@ specified function and writes the json output to a file named `<output-file>`.

3. Create a project and import a binary file.

4. Run `PatchestryScript.java`.
4. Run `PatchestryDecompileFunctions.java` in `single` or `all` mode to decompile single or all functions from a binary file.

5. Run `PatchestryListFunctions.java` script to list all the functions in a binary file.

**Note:** Ghidra scripts must be installed. See the [build](build.md) section for details.
2 changes: 1 addition & 1 deletion scripts/ghidra/decompile-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,4 @@ function main {
}

main "$@"
exit $?
exit $?
34 changes: 25 additions & 9 deletions scripts/ghidra/decompile-headless.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ validate_paths() {
fi

# Expect both input and output file to exist
if [! -f "$INPUT_PATH" ]; then
if [ ! -f "$INPUT_PATH" ]; then
echo "Input file $INPUT_PATH doesn't exist. Exiting!"
exit 1
fi

if [! -f "$OUTPUT_PATH" ]; then
if [ ! -f "$OUTPUT_PATH" ]; then
echo "Output file $OUTPUT_PATH doesn't exist. Exiting!"
exit 1
fi
Expand All @@ -136,12 +136,28 @@ build_docker_command() {
if [ -n "$CI_OUTPUT_FOLDER" ]; then
INPUT_PATH=$(basename "$INPUT_PATH")
OUTPUT_PATH=$(basename "$OUTPUT_PATH")
RUN="docker run --rm \
-v $CI_OUTPUT_FOLDER:/mnt/output:rw \
trailofbits/patchestry-decompilation:latest \
--input /mnt/output/$INPUT_PATH \
--command decompile --function \"$FUNCTION_NAME\" \
--output /mnt/output/$OUTPUT_PATH"
if [ -n "$LIST_FUNCTIONS" ]; then
RUN="docker run --rm \
-v $CI_OUTPUT_FOLDER:/mnt/output:rw \
trailofbits/patchestry-decompilation:latest \
--input /mnt/output/$INPUT_PATH \
--command list-functions \
--output /mnt/output/$OUTPUT_PATH"
elif [ -n "$FUNCTION_NAME" ]; then
RUN="docker run --rm \
-v $CI_OUTPUT_FOLDER:/mnt/output:rw \
trailofbits/patchestry-decompilation:latest \
--input /mnt/output/$INPUT_PATH \
--command decompile --function \"$FUNCTION_NAME\" \
--output /mnt/output/$OUTPUT_PATH"
else
RUN="docker run --rm \
-v $CI_OUTPUT_FOLDER:/mnt/output:rw \
trailofbits/patchestry-decompilation:latest \
--input /mnt/output/$INPUT_PATH \
--command decompile-all \
--output /mnt/output/$OUTPUT_PATH"
fi

elif [ -n "$LIST_FUNCTIONS" ]; then
RUN="docker run --rm \
Expand Down Expand Up @@ -193,4 +209,4 @@ main() {
eval "$RUN"
}

main "$@"
main "$@"

0 comments on commit e2de71a

Please sign in to comment.