mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 20:33:11 +08:00
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.
This commit is contained in:
+14
-10
@@ -472,17 +472,21 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-10
@@ -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) {
|
||||
|
||||
+6
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user