diff --git a/.github/workflows/export-ghidra.yml b/.github/workflows/export-ghidra.yml index 887f4e5f..c5253b8a 100644 --- a/.github/workflows/export-ghidra.yml +++ b/.github/workflows/export-ghidra.yml @@ -11,6 +11,7 @@ jobs: permissions: contents: write + pull-requests: write steps: - uses: actions/checkout@v4 @@ -32,6 +33,20 @@ jobs: curl -L https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_10.3.3_build/ghidra_10.3.3_PUBLIC_20230829.zip -o /tmp/ghidra.zip unzip -d /tmp /tmp/ghidra.zip echo /tmp/ghidra_*/support >> $GITHUB_PATH + - name: Update mapping + run: | + echo "$GHIDRA_SSH_AUTH" > ssh_key + python scripts/update_mapping.py --username github-action --ssh-key ssh_key --program th06_102h.exe 'ghidra://roblab.la/Touhou 06' + rm ssh_key + env: # Or as an environment variable + GHIDRA_SSH_AUTH: ${{ secrets.GHIDRA_SSH_AUTH }} + - name: Create PR to TH06 with updated mapping + uses: peter-evans/create-pull-request@v5 + with: + commit-message: Update mapping to latest ghidra changes + branch: update-mapping + title: Update mapping from ghidra + body: Updates the mapping to the latest changes in the ghidra database. - name: Export ghidra run: | echo "$GHIDRA_SSH_AUTH" > ssh_key @@ -39,7 +54,7 @@ jobs: rm ssh_key env: # Or as an environment variable GHIDRA_SSH_AUTH: ${{ secrets.GHIDRA_SSH_AUTH }} - - name: Push + - name: Push th06-re run: | echo "$GHIDRA_SSH_AUTH" > ssh_key chmod 0600 ssh_key diff --git a/scripts/update_mapping.py b/scripts/update_mapping.py new file mode 100755 index 00000000..bfd3c5c8 --- /dev/null +++ b/scripts/update_mapping.py @@ -0,0 +1,53 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p python311 -i python3 + +import argparse +from datetime import datetime, timezone +import json +import os +from pathlib import Path +import re +import subprocess +import tempfile +import tomllib +from typing import Optional + +SCRIPT_PATH = Path(os.path.realpath(__file__)).parent + + +def runAnalyze(args, extraArgs): + commonAnalyzeHeadlessArgs = ['analyzeHeadless', args.GHIDRA_REPO_NAME] + commonAnalyzeHeadlessArgs += ['-noanalysis', '-readOnly', '-scriptPath', str(SCRIPT_PATH / 'ghidra')] + if args.ssh_key: + commonAnalyzeHeadlessArgs += ['-keystore', args.ssh_key] + + # TODO: If program is not provided, export all files from server. + if args.program: + commonAnalyzeHeadlessArgs += ['-process', args.program] + + commonAnalyzeHeadlessEnv = os.environ.copy() + commonAnalyzeHeadlessEnv['_JAVA_OPTIONS'] = f'-Duser.name={args.username} ' + os.environ.get('_JAVA_OPTIONS', '') + + return subprocess.run(commonAnalyzeHeadlessArgs + extraArgs, env=commonAnalyzeHeadlessEnv, check=True) + +def updateMapping(args, mapping_path): + runAnalyze(args, ['-preScript', 'GenerateMappingToml.java', mapping_path]) + +def main(): + parser = argparse.ArgumentParser( + description='Export a ghidra database history to git', + ) + parser.add_argument('GHIDRA_REPO_NAME') + parser.add_argument('--username', help='Username to use when connecting to the ghidra server.') + parser.add_argument('--ssh-key', help="""SSH key to use to authenticate to a ghidra server. + Note that the ghidra server must have SSH authentication enabled for this to work. + To enable SSH auth, add -ssh in the wrapper.parameters of the Ghidra Server's server.conf""") + parser.add_argument('--program', help='Program to export') + args = parser.parse_args() + + mapping_path = SCRIPT_PATH.parent / 'config' / 'mapping.toml' + + updateMapping(args, mapping_path) + +if __name__ == '__main__': + main()