#!/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" "$2" "$3"\ -process default.xbe\ -noanalysis\ -postScript DelinkProgram.java\ /exporter 'COFF relocatable object'\ $(printf "/include-range %s " $4)\ /export "target/$5" } main "$@"