From 561748578926fbde8a2b575796ea5f31a9025a27 Mon Sep 17 00:00:00 2001 From: ghizard <50744617+ghizard@users.noreply.github.com> Date: Mon, 10 Nov 2025 07:34:49 -0500 Subject: [PATCH 1/4] GP-6100 - PDB - fixed NPE due to function null container class --- .../app/util/pdb/pdbapplicator/DefaultPdbApplicator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DefaultPdbApplicator.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DefaultPdbApplicator.java index aea2f96589..da68dd9188 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DefaultPdbApplicator.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DefaultPdbApplicator.java @@ -2228,6 +2228,9 @@ public class DefaultPdbApplicator implements PdbApplicator { //============================================================================================== void predefineClass(SymbolPath classPath) { + if (classPath == null) { + return; + } isClassByNamespace.put(classPath, true); for (SymbolPath path = classPath.getParent(); path != null; path = path.getParent()) { if (!isClassByNamespace.containsKey(path)) { From 09353f5f6f3adc7cb98bd263d5b88699cacdd46c Mon Sep 17 00:00:00 2001 From: dev747368 <48332326+dev747368@users.noreply.github.com> Date: Thu, 13 Nov 2025 18:52:35 +0000 Subject: [PATCH 2/4] GP-6106 fix go apisnapshot version fallback Wasn't trying to use previous patch-ver snapshot info. --- .../core/analysis/GolangSymbolAnalyzer.java | 2 + .../bin/format/golang/rtti/GoApiSnapshot.java | 60 ++++++++++++------- .../bin/format/golang/rtti/GoRttiMapper.java | 8 +-- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java index 2ccf428c5c..3197942c15 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java @@ -130,6 +130,8 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { return false; } + Msg.info(this, "Go version %s".formatted(goBinary.getGoVer())); + goTypes = goBinary.getGoTypes(); markupSession = goBinary.createMarkupSession(monitor); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoApiSnapshot.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoApiSnapshot.java index b976d069f7..62f6c97f57 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoApiSnapshot.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoApiSnapshot.java @@ -31,6 +31,7 @@ import ghidra.app.util.bin.format.golang.GoVer; import ghidra.formats.gfilesystem.FSRL; import ghidra.formats.gfilesystem.FileSystemService; import ghidra.framework.Application; +import ghidra.util.Msg; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -124,30 +125,44 @@ public class GoApiSnapshot { return null; } - ByteProvider bp = null; - if (goVer.getPatch() == 0) { - // doesn't need diffpatching - bp = fsService.getByteProvider(fsService.getLocalFSRL(jsonFile), false, monitor); + File patchDiffFile = getPatchVerDiffFile(goVer); + if (patchDiffFile == null) { + return fsService.getByteProvider(fsService.getLocalFSRL(jsonFile), false, monitor); + } + + FSRL fsrl = fsService.getFullyQualifiedFSRL(fsService.getLocalFSRL(jsonFile), monitor); + ByteProvider bp = fsService.getDerivedByteProviderPush(fsrl, null, + "go%s.json".formatted(goVer), -1, os -> { + JsonPatch jsonPatch = JsonPatch.read(patchDiffFile); + JsonPatchApplier jpa = new JsonPatchApplier(jsonFile); + monitor.initialize(jsonPatch.getSectionCount(), + "Patching Go API snapshot %s -> %s".formatted(baseVer, goVer)); + jpa.apply(jsonPatch, monitor); + OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8); + new Gson().toJson(jpa.getJson(), osw); + osw.flush(); // don't close outputstream, handled by caller + }, monitor); + return bp; + } + + static File getPatchVerDiffFile(GoVer goVer) { + // returns the closest patch file that is present, or null if patch-ver-num is already 0 + // or no patch diff files are found for the specified major.minor version. + GoVer patchVer = goVer; + File patchDiffFile = null; + while (patchVer.getPatch() > 0 && + (patchDiffFile = getApiSnapshotFile(patchVer, "patchverdiffs/", ".diff")) == null) { + patchVer = patchVer.prevPatch(); + } + + if (patchVer.getPatch() != goVer.getPatch()) { + Msg.warn(GoApiSnapshot.class, + "Falling back from %s to %s for Go API snapshot".formatted(goVer, patchVer)); } else { - File patchDiffFile = getApiSnapshotFile(goVer, "patchverdiffs/", ".diff"); - if (patchDiffFile != null) { - FSRL fsrl = - fsService.getFullyQualifiedFSRL(fsService.getLocalFSRL(jsonFile), monitor); - bp = fsService.getDerivedByteProviderPush(fsrl, null, - "go%s.json".formatted(goVer), -1, os -> { - JsonPatch jsonPatch = JsonPatch.read(patchDiffFile); - JsonPatchApplier jpa = new JsonPatchApplier(jsonFile); - monitor.initialize(jsonPatch.getSectionCount(), - "Patching Go API snapshot %s -> %s".formatted(baseVer, goVer)); - jpa.apply(jsonPatch, monitor); - OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8); - new Gson().toJson(jpa.getJson(), osw); - osw.flush(); // don't close outputstream, handled by caller - }, monitor); - } + Msg.info(GoApiSnapshot.class, "Using Go API snapshot for %s".formatted(goVer)); } - return bp; + return patchDiffFile; } static File getApiSnapshotFile(GoVer goVer, String subdir, String suffix) { @@ -189,7 +204,7 @@ public class GoApiSnapshot { */ private static GoApiSnapshot read(InputStream is, List archNames, GoVer ver) throws IOException { - Gson gson = new GsonBuilder() + Gson gson = new GsonBuilder() // register postfix handler .registerTypeAdapter(GoTypeDef.class, new GoTypeDefDeserializer()) .registerTypeAdapterFactory(new GsonPostFixupAdapter()) .create(); @@ -418,6 +433,7 @@ public class GoApiSnapshot { TypeParams = List.of(); } } + @Override public String toString() { return "GoFuncTypeDef [Params=" + Params + ", Results=" + Results + ", TypeParams=" + diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java index a274200b78..97b1c3a873 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java @@ -155,7 +155,7 @@ public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContex * @return new {@link GoRttiMapper}, or null if basic Go information is not found in the * binary * @throws BootstrapInfoException if it is a Go binary and has an unsupported or - * unparseable version number or if there was a missing Go bootstrap .gdt file + * unparseable version number or if Go bootstrap info was missing * @throws IOException if there was an error in the Ghidra Go RTTI reading logic */ public static GoRttiMapper getGoBinary(Program program, TaskMonitor monitor) @@ -326,9 +326,9 @@ public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContex * @param goVer version of Go * @param apiSnapshot json func signatures and data types * @throws IOException if error linking a structure mapped structure to its matching - * ghidra structure, which is a programming error or a corrupted bootstrap gdt - * @throws BootstrapInfoException if there is no matching bootstrap gdt for this specific - * type of Go binary + * ghidra structure, which is a programming error or invalid bootstrap info + * @throws BootstrapInfoException if there is no bootstrap info for this specific + * type and version of Go binary */ public GoRttiMapper(Program program, GoBuildInfo buildInfo, int ptrSize, GoVer goVer, GoApiSnapshot apiSnapshot) throws IOException, BootstrapInfoException { From 64671247210906fa2a0afe52ae64c3c396b9f7f8 Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Mon, 17 Nov 2025 05:32:40 -0500 Subject: [PATCH 3/4] GP-0: Fixing javadoc --- .../ghidra/app/util/bin/format/som/SomDynamicLoaderHeader.java | 2 +- .../java/ghidra/app/util/bin/format/som/SomExportEntryExt.java | 2 +- .../Generic/src/main/java/ghidra/net/ApplicationKeyStore.java | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomDynamicLoaderHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomDynamicLoaderHeader.java index cac53a08b7..65d596a58d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomDynamicLoaderHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomDynamicLoaderHeader.java @@ -452,7 +452,7 @@ public class SomDynamicLoaderHeader implements StructConverter { } /** - * {@return the {@link List} of {@link SomExportEntryExt export entry extensions} + * {@return the {@link List} of {@link SomExportEntryExt export entry extensions}} */ public List getExportExtensions() { return exportExtensions; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomExportEntryExt.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomExportEntryExt.java index 75baef79fe..fc2626879d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomExportEntryExt.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/som/SomExportEntryExt.java @@ -53,7 +53,7 @@ public class SomExportEntryExt implements StructConverter { } /** - * {@return the size of the export symbol and is only valid for exports of type {@code ST_DATA} + * {@return the size of the export symbol and is only valid for exports of type {@code ST_DATA}} */ public int getSize() { return size; diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationKeyStore.java b/Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationKeyStore.java index d9985d392d..36373183be 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationKeyStore.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationKeyStore.java @@ -95,7 +95,6 @@ public class ApplicationKeyStore { /** * Attempt to load a client/server keystore in a PKCS12 form (*.p12, *.pks, *.pfx) or * Java JKS (*.jks) form. - * @param path keystore file path * @param pwd keystore password * @return keystore instance * @throws IOException From 66f8ed38e16b1343b6621dc0c548937ab00ec484 Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Mon, 17 Nov 2025 05:34:16 -0500 Subject: [PATCH 4/4] GP-0: Upping gradle wrapper version to 9.2.0 --- .../Common/support/gradle/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/RuntimeScripts/Common/support/gradle/gradle-wrapper.properties b/Ghidra/RuntimeScripts/Common/support/gradle/gradle-wrapper.properties index 2e1113280e..bad7c2462f 100644 --- a/Ghidra/RuntimeScripts/Common/support/gradle/gradle-wrapper.properties +++ b/Ghidra/RuntimeScripts/Common/support/gradle/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME