From 53b0e82417a08c4be91bba71958d06b6b16f03d8 Mon Sep 17 00:00:00 2001 From: KeybadeBlox Date: Wed, 11 Feb 2026 20:23:26 -0500 Subject: [PATCH] Include headless demangling in delink.sh This means we get delinked objects with proper mangled names matching our recompiled files. --- ghidra/delink.sh | 3 +++ ghidra/ghidra_scripts/MSVC7Mangle.java | 33 ++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ghidra/delink.sh b/ghidra/delink.sh index 2df52e2..9b14b9b 100755 --- a/ghidra/delink.sh +++ b/ghidra/delink.sh @@ -65,8 +65,11 @@ delink() { export MSYS_NO_PATHCONV=1 "$1/support/analyzeHeadless$suffix" "$2" "$3"\ + -readOnly\ -process default.xbe\ -noanalysis\ + -scriptPath ghidra_scripts\ + -preScript MSVC7Mangle.java $4\ -postScript DelinkProgram.java\ /exporter 'COFF relocatable object'\ $(printf "/include-range %s " $4)\ diff --git a/ghidra/ghidra_scripts/MSVC7Mangle.java b/ghidra/ghidra_scripts/MSVC7Mangle.java index df39ac0..84d197c 100644 --- a/ghidra/ghidra_scripts/MSVC7Mangle.java +++ b/ghidra/ghidra_scripts/MSVC7Mangle.java @@ -7,17 +7,20 @@ // permissive form (public, non-const, etc.). // // Special symbol names like "operator new" or "scalar deleting destructor" -// are given unique mangling. To properly demangle these, name them as they +// are given unique mangling. To properly mangle these, name them as they // appear in objdiff, replacing spaces with underscores, e.g. "operator_new" // and "`scalar_deleting_destructor'" (notice the ` and '). // +// This script can be called in headless mode with the address ranges to mangle +// as arguments, e.g. 0x1234-0x5678. Any symbols referenced by functions being +// mangled will also be mangled in this mode (so that the references are +// correct if the mangling is done in preparation for exporting functions). +// // @category Symbol import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; -import ghidra.program.model.listing.Data; -import ghidra.program.model.listing.Function; -import ghidra.program.model.listing.FunctionSignature; +import ghidra.program.model.address.AddressSet; import ghidra.program.model.data.Array; import ghidra.program.model.data.BooleanDataType; import ghidra.program.model.data.CharDataType; @@ -47,6 +50,9 @@ import ghidra.program.model.data.UnsignedLongLongDataType; import ghidra.program.model.data.UnsignedShortDataType; import ghidra.program.model.data.VoidDataType; import ghidra.program.model.data.WideCharDataType; +import ghidra.program.model.listing.Data; +import ghidra.program.model.listing.Function; +import ghidra.program.model.listing.FunctionSignature; import ghidra.program.model.symbol.Namespace; import ghidra.program.model.symbol.Reference; import ghidra.program.model.symbol.SourceType; @@ -66,6 +72,22 @@ import java.util.zip.CRC32; public class MSVC7Mangle extends GhidraScript{ @Override public void run() throws Exception { + // Get selected ranges from arguments if invoked headless + if (isRunningHeadless()) { + final String[] args = getScriptArgs(); + final AddressSet addr = new AddressSet(); + + for (int i = 0; i < args.length; i++) { + final String[] range = args[i].split("-"); + addr.add( + currentAddress.getAddress(range[0]), + currentAddress.getAddress(range[1]) + ); + } + + setCurrentSelection(addr); + } + final SymbolIterator iter = currentProgram.getSymbolTable() .getPrimarySymbolIterator(currentSelection, true); @@ -87,6 +109,9 @@ public class MSVC7Mangle extends GhidraScript{ s.setName(mangled, SourceType.USER_DEFINED); makeGlobal(s); } + + // TODO: in headless mode, also mangle everything + // referenced by functions } }