From 3422409568e2715e81a624a1f35dcef037b0e973 Mon Sep 17 00:00:00 2001 From: Ivan Mladenov Date: Fri, 30 May 2025 13:02:43 -0400 Subject: [PATCH 1/2] Fixed magic bytes to resolve Golang (v1.20+) functions. --- .../java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java index 20103fa8b5..e8cdfb66e5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java @@ -47,6 +47,7 @@ public class GoPcHeader { public static final int GO_1_2_MAGIC = 0xfffffffb; public static final int GO_1_16_MAGIC = 0xfffffffa; public static final int GO_1_18_MAGIC = 0xfffffff0; + public static final int GO_1_20_MAGIC = 0xfffffff1; /** * Returns the {@link Address} (if present) of the go pclntab section or symbol. @@ -314,6 +315,7 @@ public class GoPcHeader { case GO_1_2_MAGIC -> new GoVer(1, 2, 0); case GO_1_16_MAGIC -> new GoVer(1, 16, 0); case GO_1_18_MAGIC -> new GoVer(1, 18, 0); + case GO_1_20_MAGIC -> new GoVer(1, 20, 0); default -> GoVer.INVALID; }; From 4521861b182c89987f1c286b508190d82c2c4fb2 Mon Sep 17 00:00:00 2001 From: dev747368 <48332326+dev747368@users.noreply.github.com> Date: Fri, 30 May 2025 22:01:57 +0000 Subject: [PATCH 2/2] GP-5728 improve go pcheader and moduledata searching These code paths are mainly hit with stripped PE binaries, and together with the missing 1.20+ pcheader magic value would cause failure to find the firstmoduledata struct, which is the root of everything. --- .../bin/format/golang/rtti/GoModuledata.java | 24 ++++++++++------- .../bin/format/golang/rtti/GoPcHeader.java | 26 ++++++++++++------- .../bin/format/golang/rtti/GoRttiMapper.java | 6 +++++ 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoModuledata.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoModuledata.java index afa45271f7..03e970061a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoModuledata.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoModuledata.java @@ -472,17 +472,21 @@ public class GoModuledata implements StructureMarkup { int ptrSize = context.getPtrSize(); byte[] searchBytes = new byte[ptrSize]; context.getDataConverter().putValue(pcHeaderAddress.getOffset(), ptrSize, searchBytes, 0); - Address moduleAddr = memory.findBytes(range.getMinAddress(), range.getMaxAddress(), - searchBytes, null, true, monitor); - if (moduleAddr == null) { - return null; + + Address moduleAddr; + while ((moduleAddr = memory.findBytes(range.getMinAddress(), range.getMaxAddress(), + searchBytes, null, true, monitor)) != null) { + + GoModuledata moduleData = context.readStructure(GoModuledata.class, moduleAddr); + + // Verify that we read a good GoModuledata struct by comparing some of its values to + // the pclntab structure. + if (moduleData.matchesPcHeader(pcHeader)) { + return moduleData; + } + range = new AddressRangeImpl(moduleAddr.next(), range.getMaxAddress()); } - - GoModuledata moduleData = context.readStructure(GoModuledata.class, moduleAddr); - - // Verify that we read a good GoModuledata struct by comparing some of its values to - // the pclntab structure. - return moduleData.matchesPcHeader(pcHeader) ? moduleData : null; + return null; } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java index e8cdfb66e5..9d3fb072e7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcHeader.java @@ -20,8 +20,7 @@ import java.io.IOException; import ghidra.app.util.bin.*; import ghidra.app.util.bin.format.golang.GoVer; import ghidra.app.util.bin.format.golang.structmapping.*; -import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressRange; +import ghidra.program.model.address.*; import ghidra.program.model.data.*; import ghidra.program.model.lang.Endian; import ghidra.program.model.listing.Program; @@ -113,15 +112,18 @@ public class GoPcHeader { (byte) 0xff // ptrSize }; Memory memory = programContext.getProgram().getMemory(); - Address pcHeaderAddr = memory.findBytes(range.getMinAddress(), range.getMaxAddress(), - searchBytes, searchMask, true, monitor); - if (pcHeaderAddr == null) { - return null; - } - try (MemoryByteProvider bp = - new MemoryByteProvider(memory, pcHeaderAddr, range.getMaxAddress())) { - return isPcHeader(bp) ? pcHeaderAddr : null; + Address pcHeaderAddr; + while ((pcHeaderAddr = memory.findBytes(range.getMinAddress(), range.getMaxAddress(), + searchBytes, searchMask, true, monitor)) != null) { + try (MemoryByteProvider bp = + new MemoryByteProvider(memory, pcHeaderAddr, range.getMaxAddress())) { + if (isPcHeader(bp)) { + return pcHeaderAddr; + } + } + range = new AddressRangeImpl(pcHeaderAddr.next(), range.getMaxAddress()); } + return null; } /** @@ -287,6 +289,10 @@ public class GoPcHeader { return ptrSize; } + public int getMagic() { + return magic; + } + //-------------------------------------------------------------------------------------------- record GoVerEndian(GoVer goVer, Endian endian) { GoVerEndian(GoVer goVer, boolean isLittleEndian) { 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 d65999d9fb..48797d7de9 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 @@ -507,6 +507,12 @@ public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContex throw new IOException( "Mismatched ptrSize: %d vs %d".formatted(pcHeader.getPtrSize(), ptrSize)); } + if (pcHeader.getGoVersion().isInvalid()) { + // we can get here if the firstmoduledata was located via symbolname instead of + // relying on bootstraping via the pcheader + Msg.warn(this, + "Unknown golang pcheader magic value: 0x%x".formatted(pcHeader.getMagic())); + } } addModule(firstModule); }