From af73f267d09b51fc6476e2fa3199f1ecb829dca2 Mon Sep 17 00:00:00 2001 From: d-millar <33498836+d-millar@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:55:22 -0500 Subject: [PATCH] GP-4097: last change GP-4097: last change GP-4097: per review comments GP-4079: once more w/overlays GP-4097: working again, post-review GP-4097: broken for the moment GP-4097: post-review changes GP-4097: added processor-defined label options GP-4097: consolidated addressSpace handling w/ fixes non-RAM --- .../Sarif/src/main/java/sarif/DEVNOTES.txt | 7 +- .../src/main/java/sarif/SarifController.java | 33 +--- .../main/java/sarif/SarifProgramOptions.java | 39 +++++ .../Sarif/src/main/java/sarif/SarifUtils.java | 161 ++++++++++++++++-- .../main/java/sarif/export/SarifObject.java | 46 +---- .../java/sarif/export/mm/ExtMemoryMap.java | 10 -- .../java/sarif/export/symbols/ExtSymbol.java | 2 + .../sarif/managers/MemoryMapSarifMgr.java | 87 ++++------ .../main/java/sarif/managers/SarifMgr.java | 107 +----------- .../sarif/managers/SymbolTableSarifMgr.java | 4 + 10 files changed, 244 insertions(+), 252 deletions(-) diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/DEVNOTES.txt b/Ghidra/Features/Sarif/src/main/java/sarif/DEVNOTES.txt index 24af15197d..2dd0243f7e 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/DEVNOTES.txt +++ b/Ghidra/Features/Sarif/src/main/java/sarif/DEVNOTES.txt @@ -3,11 +3,14 @@ Random notes: 1. Symbols require a pre- and post-function pass, pre- to guarantee the correct naming of globals including functions and libraries and post- to guarantee namespaces have already been created for locals + +2. Overlay spaces are currently flagged using artifactLocation::uri on Location; address spaces with different names + are flagged in "fullyQualifiedName". + +3: "Location is used to convey addresses; "location" is used generally for non-address information, e.g. file::offset. Code differences from export/re-import: 1. There may be missing parameter datatypes for parameters in a FunctionDefinition used inside a structure or union. 2. Datatypes like "RTTIBaseDescriptor *32 _((image-base-relative)) *32 _((image-base-relative))" are not handled correctly. - -3. Modified/multiple ProgramTrees will not be imported correctly. Appears to be no way to fix this with the current API. \ No newline at end of file diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java b/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java index b5b260c2af..2976dd4ac4 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java @@ -24,7 +24,6 @@ import java.util.Map; import java.util.Set; import com.contrastsecurity.sarif.Location; -import com.contrastsecurity.sarif.LogicalLocation; import com.contrastsecurity.sarif.Result; import com.contrastsecurity.sarif.SarifSchema210; @@ -35,7 +34,6 @@ import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; import ghidra.program.model.listing.BookmarkManager; import ghidra.program.model.listing.CodeUnit; -import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Program; import ghidra.service.graph.AttributedGraph; import ghidra.service.graph.EmptyGraphType; @@ -200,13 +198,6 @@ public class SarifController implements ObjectSelectedListener logicalLocations = loc.getLogicalLocations(); - for (LogicalLocation logLoc : logicalLocations) { - switch (logLoc.getKind()) { - case "function": - String fname = logLoc.getName(); - for (Function func : getProgram().getFunctionManager().getFunctions(true)) { - if (fname.equals(func.getName())) { - return func.getEntryPoint(); - } - } - break; - default: - Msg.error(this, "Unknown logical location to handle: " + logLoc.toString()); - } - } - } - return null; + public Address locationToAddress(Location location) { + return SarifUtils.locationToAddress(location, program); } @SuppressWarnings("unchecked") diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/SarifProgramOptions.java b/Ghidra/Features/Sarif/src/main/java/sarif/SarifProgramOptions.java index d0d4274a9e..a90621d71f 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/SarifProgramOptions.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/SarifProgramOptions.java @@ -20,6 +20,7 @@ import java.util.List; import ghidra.app.util.Option; import ghidra.app.util.OptionException; +import ghidra.app.util.opinion.AbstractProgramLoader; /** * A class to hold SARIF options. @@ -94,6 +95,8 @@ public class SarifProgramOptions { private boolean relocationTable = true; private boolean entryPoints = true; private boolean externalLibraries = true; + private boolean applyProcDefinedLabels = false; + private boolean anchorProcDefinedLabels = true; /** * Returns an array of importer options representing @@ -146,6 +149,8 @@ public class SarifProgramOptions { optionList.add(new Option("Relocation Table", Boolean.valueOf(isRelocationTable()))); optionList.add(new Option("Entry Points", Boolean.valueOf(isEntryPoints()))); optionList.add(new Option("External Libraries", Boolean.valueOf(isExternalLibraries()))); + optionList.add(new Option(AbstractProgramLoader.APPLY_LABELS_OPTION_NAME, Boolean.valueOf(applyProcDefinedLabels()))); + optionList.add(new Option(AbstractProgramLoader.ANCHOR_LABELS_OPTION_NAME, Boolean.valueOf(anchorProcDefinedLabels()))); return optionList; } @@ -234,6 +239,12 @@ public class SarifProgramOptions { else if (optName.equals("External Libraries")) { setExternalLibraries(val); } + else if (optName.equals("Apply Processor Defined Labels")) { + setExternalLibraries(val); + } + else if (optName.equals("Anchor Processor Defined Labels")) { + setExternalLibraries(val); + } else { throw new OptionException("Unknown option: " + optName); } @@ -604,6 +615,34 @@ public class SarifProgramOptions { overwriteSymbolConflicts = b; } + /** + * @return true if the processor-defined labels should be applied + */ + public boolean applyProcDefinedLabels() { + return applyProcDefinedLabels; + } + + /** + * @param b true if the processor-defined labels should be applied + */ + public void setApplyProcDefinedLabels(boolean b) { + applyProcDefinedLabels = b; + } + + /** + * @param b trueif the processor-defined labels should be anchored + */ + public void setAnchorProcDefinedLabels(boolean b) { + anchorProcDefinedLabels = b; + } + + /** + * @return true true if the processor-defined labels should be anchored + */ + public boolean anchorProcDefinedLabels() { + return anchorProcDefinedLabels; + } + public void setAddToProgram(boolean addToProgram) { this.addToProgram = addToProgram; } diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java b/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java index bf71814d19..0d298747ca 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java @@ -16,21 +16,152 @@ package sarif; import java.io.ByteArrayInputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; import org.bouncycastle.util.encoders.Base64; -import com.contrastsecurity.sarif.Artifact; -import com.contrastsecurity.sarif.ArtifactContent; -import com.contrastsecurity.sarif.ReportingDescriptor; -import com.contrastsecurity.sarif.ReportingDescriptorReference; -import com.contrastsecurity.sarif.Run; -import com.contrastsecurity.sarif.ToolComponent; +import com.contrastsecurity.sarif.*; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import ghidra.framework.store.LockException; +import ghidra.program.model.address.*; +import ghidra.program.model.address.Address; +import ghidra.program.model.listing.Program; +import ghidra.util.InvalidNameException; +import ghidra.util.exception.DuplicateNameException; public class SarifUtils { - + + // NB: We're abusing "fullyQualifiedName" and "artifactLocation/uri" here. + // For our purposes: + // fullyQualifiedName <= addressSpace name for overlays or non-TYPE_RAM + // addresses + // artifactLocation/uri <= the overlayED space name (typically OTHER) + + public static JsonArray setLocations(Address min, Address max) { + AddressSet set = new AddressSet(min, max); + return setLocations(set); + } + + public static JsonArray setLocations(AddressSetView set) { + JsonArray locations = new JsonArray(); + AddressRangeIterator addressRanges = set.getAddressRanges(); + while (addressRanges.hasNext()) { + JsonObject element = new JsonObject(); + locations.add(element); + AddressRange next = addressRanges.next(); + JsonObject ploc = new JsonObject(); + element.add("physicalLocation", ploc); + JsonObject address = new JsonObject(); + ploc.add("address", address); + address.addProperty("absoluteAddress", next.getMinAddress().getOffset()); + address.addProperty("length", next.getLength()); + Address minAddress = next.getMinAddress(); + AddressSpace addressSpace = minAddress.getAddressSpace(); + if (!addressSpace.showSpaceName()) { + continue; + } + + // type != TYPE_RAM || isOverlaySpace() + address.addProperty("fullyQualifiedName", addressSpace.getName()); + if (!(addressSpace instanceof OverlayAddressSpace ospace)) { + continue; + } + + JsonObject artifact = new JsonObject(); + ploc.add("artifactLocation", artifact); + String name = ospace.getOverlayedSpace().getName(); + artifact.addProperty("uri", name); + } + return locations; + } + + @SuppressWarnings("unchecked") + public static AddressSet getLocations(Map result, Program program, + AddressSet set) throws AddressOverflowException { + if (set == null) { + set = new AddressSet(); + } + List locations = (List) result.get("Locations"); + if (locations == null) { + return set; + } + for (Location location : locations) { + AddressRange range = locationToRange(location, program); + if (range != null) { + set.add(range); + } + } + return set; + } + + public static AddressRange locationToRange(Location location, Program program) + throws AddressOverflowException { + PhysicalLocation physicalLocation = location.getPhysicalLocation(); + long len = physicalLocation.getAddress().getLength(); + Address addr = locationToAddress(location, program); + return addr == null ? null : new AddressRangeImpl(addr, len); + } + + public static Address locationToAddress(Location location, Program program) { + if (location.getPhysicalLocation() != null) { + AddressFactory af = program.getAddressFactory(); + AddressSpace base = af.getDefaultAddressSpace(); + + PhysicalLocation physicalLocation = location.getPhysicalLocation(); + Long addr = physicalLocation.getAddress().getAbsoluteAddress(); + String fqn = physicalLocation.getAddress().getFullyQualifiedName(); + if (fqn == null) { + return longToAddress(base, addr); + } + if (fqn.equals("NO ADDRESS")) { + return null; + } + + ArtifactLocation artifact = physicalLocation.getArtifactLocation(); + if (artifact == null) { // Not an overlay + AddressSpace space = getAddressSpace(program, fqn, base); + return longToAddress(space, addr); + } + + // Overlay + String uri = artifact.getUri(); + base = program.getAddressFactory().getAddressSpace(uri); + if (base == null) { + try { + base = program.createOverlaySpace(fqn, base); + } + catch (IllegalStateException | DuplicateNameException | InvalidNameException + | LockException e) { + throw new RuntimeException("Attempt to create " + fqn + " failed!"); + } + } + AddressSpace space = getAddressSpace(program, fqn, base); + return longToAddress(space, addr); + } + return null; + } + + private static AddressSpace getAddressSpace(Program program, String fqn, AddressSpace base) { + AddressSpace space = program.getAddressFactory().getAddressSpace(fqn); + if (space != null) { + return space; + } + try { + space = program.createOverlaySpace(fqn, base); + } + catch (IllegalStateException | DuplicateNameException | InvalidNameException + | LockException e) { + throw new RuntimeException("Attempt to create " + fqn + " failed!"); + } + return space; + } + + public static Address longToAddress(AddressSpace space, Long addr) { + return space.getAddressInThisSpaceOnly(addr); + } + public static ByteArrayInputStream getArtifactContent(Artifact artifact) { ArtifactContent content = artifact.getContents(); String b64 = content.getBinary(); @@ -38,17 +169,19 @@ public class SarifUtils { return new ByteArrayInputStream(decoded); } - public static ReportingDescriptor getTaxaValue(ReportingDescriptorReference taxa, ToolComponent taxonomy) { + public static ReportingDescriptor getTaxaValue(ReportingDescriptorReference taxa, + ToolComponent taxonomy) { List view = new ArrayList<>(taxonomy.getTaxa()); return view.get(taxa.getIndex().intValue()); } - public static ToolComponent getTaxonomy(ReportingDescriptorReference taxa, Set taxonomies) { + public static ToolComponent getTaxonomy(ReportingDescriptorReference taxa, + Set taxonomies) { Object idx = taxa.getToolComponent().getIndex(); if (idx == null) { List view = new ArrayList<>(taxonomies); - idx= taxa.getIndex(); - return view.get(idx instanceof Long ? ((Long)idx).intValue() : (Integer) idx); + idx = taxa.getIndex(); + return view.get(idx instanceof Long ? ((Long) idx).intValue() : (Integer) idx); } for (ToolComponent taxonomy : taxonomies) { if (taxonomy.getName().equals(taxa.getToolComponent().getName())) { diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java b/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java index 808f5bb57a..5c947e97f2 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java @@ -20,11 +20,9 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressRange; -import ghidra.program.model.address.AddressRangeIterator; import ghidra.program.model.address.AddressSetView; -import ghidra.program.model.address.AddressSpace; import ghidra.program.model.data.ISF.IsfObject; +import sarif.SarifUtils; public class SarifObject implements IsfObject { @@ -71,23 +69,8 @@ public class SarifObject implements IsfObject { protected void writeLocations(Address min, Address max) { if (SARIF) { - locations = new JsonArray(); - JsonObject element = new JsonObject(); - locations.add(element); - JsonObject ploc = new JsonObject(); - element.add("physicalLocation", ploc); - JsonObject address = new JsonObject(); - ploc.add("address", address); - address.addProperty("absoluteAddress", min.getOffset()); - address.addProperty("length", max.subtract(min) + 1); - Address minAddress = min; - if (minAddress.getAddressSpace().getType() != AddressSpace.TYPE_RAM) { - JsonObject artifact = new JsonObject(); - ploc.add("artifactLocation", artifact); - artifact.addProperty("uri", minAddress.toString()); - } - } - else { + locations = SarifUtils.setLocations(min, max); + } else { element.addProperty("startAddress", min.toString(true)); element.addProperty("stopAddress", max.toString(true)); } @@ -95,27 +78,8 @@ public class SarifObject implements IsfObject { protected void writeLocations(AddressSetView set) { if (SARIF) { - locations = new JsonArray(); - AddressRangeIterator addressRanges = set.getAddressRanges(); - while (addressRanges.hasNext()) { - JsonObject element = new JsonObject(); - locations.add(element); - AddressRange next = addressRanges.next(); - JsonObject ploc = new JsonObject(); - element.add("physicalLocation", ploc); - JsonObject address = new JsonObject(); - ploc.add("address", address); - address.addProperty("absoluteAddress", next.getMinAddress().getOffset()); - address.addProperty("length", next.getLength()); - Address minAddress = next.getMinAddress(); - if (minAddress.getAddressSpace().getType() != AddressSpace.TYPE_RAM) { - JsonObject artifact = new JsonObject(); - ploc.add("artifactLocation", artifact); - artifact.addProperty("uri", minAddress.toString()); - } - } - } - else { + locations = SarifUtils.setLocations(set); + } else { element.addProperty("startAddress", set.getMinAddress().toString(true)); element.addProperty("stopAddress", set.getMaxAddress().toString(true)); } diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/export/mm/ExtMemoryMap.java b/Ghidra/Features/Sarif/src/main/java/sarif/export/mm/ExtMemoryMap.java index ee05bbfd5e..0abb9dcc4a 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/export/mm/ExtMemoryMap.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/export/mm/ExtMemoryMap.java @@ -18,8 +18,6 @@ package sarif.export.mm; import java.io.IOException; import ghidra.program.model.address.AddressRange; -import ghidra.program.model.address.AddressSpace; -import ghidra.program.model.address.OverlayAddressSpace; import ghidra.program.model.data.ISF.IsfObject; import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.mem.MemoryBlockSourceInfo; @@ -30,8 +28,6 @@ public class ExtMemoryMap implements IsfObject { String name; String kind; - String overlaySpace; - String overlayedSpace; String comment; boolean isVolatile; String type; @@ -52,12 +48,6 @@ public class ExtMemoryMap implements IsfObject { name = block.getName(); kind = permissions; - AddressSpace space = range.getAddressSpace(); - if (space instanceof OverlayAddressSpace) { - OverlayAddressSpace oSpace = (OverlayAddressSpace) space; - overlaySpace = oSpace.getName(); - overlayedSpace = oSpace.getOverlayedSpace().getName(); - } if (block.getComment() != null) { comment = block.getComment(); } diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/export/symbols/ExtSymbol.java b/Ghidra/Features/Sarif/src/main/java/sarif/export/symbols/ExtSymbol.java index 2ba4590908..1bad5a7183 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/export/symbols/ExtSymbol.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/export/symbols/ExtSymbol.java @@ -33,6 +33,7 @@ public class ExtSymbol implements IsfObject { String type; String sourceType; boolean primary; + boolean pinned; public ExtSymbol(Symbol symbol) { name = symbol.getName(); @@ -40,6 +41,7 @@ public class ExtSymbol implements IsfObject { kind = checkGlobal(symbol) ? "global" : "local"; sourceType = symbol.getSource().toString(); primary = symbol.isPrimary(); + pinned = symbol.isPinned(); if (symbol instanceof ClassSymbol) { type = "class"; } else if (symbol instanceof LibrarySymbol) { diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/managers/MemoryMapSarifMgr.java b/Ghidra/Features/Sarif/src/main/java/sarif/managers/MemoryMapSarifMgr.java index 1bb529a561..075cd963bc 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/managers/MemoryMapSarifMgr.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/managers/MemoryMapSarifMgr.java @@ -30,7 +30,6 @@ import com.google.gson.JsonArray; import generic.stl.Pair; import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.importer.MessageLog; -import ghidra.framework.store.LockException; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressFactory; import ghidra.program.model.address.AddressOverflowException; @@ -39,17 +38,14 @@ import ghidra.program.model.address.AddressRangeImpl; import ghidra.program.model.address.AddressRangeIterator; import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSetView; -import ghidra.program.model.address.AddressSpace; -import ghidra.program.model.address.OverlayAddressSpace; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryBlock; -import ghidra.util.InvalidNameException; import ghidra.util.exception.CancelledException; -import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskLauncher; import ghidra.util.task.TaskMonitor; import sarif.SarifProgramOptions; +import sarif.SarifUtils; import sarif.export.SarifWriterTask; import sarif.export.mm.SarifMemoryMapWriter; @@ -87,9 +83,13 @@ public class MemoryMapSarifMgr extends SarifMgr { Program program, TaskMonitor monitor) throws FileNotFoundException, AddressOverflowException { String name = (String) result.get("name"); - AddressSet set = getLocations(result, null); - Address addr = set.getMinAddress(); - int length = (int) set.getMaxAddress().subtract(addr) + 1; + AddressSet set = SarifUtils.getLocations(result, program, null); + Address blockAddress = set.getMinAddress(); + if (set.getNumAddressRanges() != 1) { + throw new RuntimeException( + "Unexpected number of ranges for block @ " + blockAddress + ": " + set.getNumAddressRanges()); + } + int length = (int) set.getMaxAddress().subtract(blockAddress) + 1; String permissions = (String) result.get("kind"); if (permissions == null) { @@ -103,37 +103,23 @@ public class MemoryMapSarifMgr extends SarifMgr { String comment = (String) result.get("comment"); String type = (String) result.get("type"); - String loc = (String) result.get("location"); - String overlayName = (String) result.get("overlaySpace"); - - Address blockAddress = addr; - if (overlayName != null) { - AddressSpace addressSpace = program.getAddressFactory().getAddressSpace(overlayName); - if (addressSpace == null) { - try { - addressSpace = program.createOverlaySpace(overlayName, addr.getAddressSpace()); - } catch (IllegalStateException | DuplicateNameException | InvalidNameException | LockException e) { - throw new RuntimeException("Attempt to create " + overlayName + " failed!"); - } - } else if (!addressSpace.isOverlaySpace()) { - throw new RuntimeException(overlayName + " is not a valid overlay space!"); - } - blockAddress = ((OverlayAddressSpace) addressSpace).getAddressInThisSpaceOnly(addr.getOffset()); - } + String loc = (String) result.get("location"); // location == position of the bytes w/i file (file::pos) + // TODO: Explore the possibility of using FileBytes in the future? try { - byte[] bytes = new byte[length]; - Arrays.fill(bytes, (byte) 0xff); MemoryBlock block = null; - if (type.equals("DEFAULT") && (loc != null)) { - Address startAddr = addr; - String[] split = loc.split(":"); - String fileName = split[0]; - int fileOffset = Integer.parseInt(split[1]); - setData(bytes, (int) startAddr.subtract(addr), directory, fileName, fileOffset, length, log); - - block = MemoryBlockUtils.createInitializedBlock(program, false, name, blockAddress, - new ByteArrayInputStream(bytes), bytes.length, comment, null, r, w, x, log, monitor); + if (type.equals("DEFAULT")) { + if (loc == null) { + block = MemoryBlockUtils.createUninitializedBlock(program, false, name, blockAddress, length, + comment, null, r, w, x, log); + } else { + String[] split = loc.split(":"); + String fileName = split[0]; + int fileOffset = Integer.parseInt(split[1]); + byte[] bytes = setData(directory, fileName, fileOffset, length, log); + block = MemoryBlockUtils.createInitializedBlock(program, false, name, blockAddress, + new ByteArrayInputStream(bytes), bytes.length, comment, null, r, w, x, log, monitor); + } } else if (type.equals("BIT_MAPPED")) { Address sourceAddr = factory.getAddress(loc); block = MemoryBlockUtils.createBitMappedBlock(program, name, blockAddress, sourceAddr, length, comment, @@ -143,8 +129,7 @@ public class MemoryMapSarifMgr extends SarifMgr { block = MemoryBlockUtils.createByteMappedBlock(program, name, blockAddress, sourceAddr, length, comment, comment, r, w, x, false, log); } else { - block = MemoryBlockUtils.createUninitializedBlock(program, false, name, blockAddress, length, comment, - null, r, w, x, log); + throw new RuntimeException("Unexpected type value - " + type); } if (block != null) { block.setVolatile(isVolatile); @@ -156,11 +141,12 @@ public class MemoryMapSarifMgr extends SarifMgr { } } - private void setData(byte[] bytes, int offset, String directory, String fileName, int fileOffset, int length, + private byte[] setData(String directory, String fileName, int fileOffset, int length, MessageLog log) throws IOException { + byte[] bytes = new byte[length]; + Arrays.fill(bytes, (byte) 0xff); File f = new File(directory, fileName); - RandomAccessFile binfile = new RandomAccessFile(f, "r"); - try { + try (RandomAccessFile binfile = new RandomAccessFile(f, "r")) { int pos = 0; while (pos < length) { int readLen = (512 * 1024); @@ -168,16 +154,16 @@ public class MemoryMapSarifMgr extends SarifMgr { readLen = length - pos; } binfile.seek(fileOffset + pos); - readLen = binfile.read(bytes, offset + pos, readLen); + readLen = binfile.read(bytes, pos, readLen); if (readLen <= 0) { break; } pos += readLen; } } catch (IndexOutOfBoundsException e) { - log.appendMsg("Invalid bin file offset " + offset + " with length " + length); + log.appendMsg("Read exceeded array length " + length); } - binfile.close(); + return bytes; } ///////////////////////////// @@ -188,8 +174,6 @@ public class MemoryMapSarifMgr extends SarifMgr { throws IOException, CancelledException { monitor.setMessage("Writing MEMORY MAP ..."); - bf = isWriteContents ? new MemoryMapBytesFile(program, filePath) : null; - List> request = new ArrayList<>(); AddressRangeIterator iter = addrs.getAddressRanges(); while (iter.hasNext()) { @@ -203,10 +187,13 @@ public class MemoryMapSarifMgr extends SarifMgr { } } - writeAsSARIF(request, bf, isWriteContents, results); - - if (isWriteContents) { - bf.close(); + try { + bf = isWriteContents ? new MemoryMapBytesFile(program, filePath) : null; + writeAsSARIF(request, bf, isWriteContents, results); + } finally { + if (isWriteContents) { + bf.close(); + } } } diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/managers/SarifMgr.java b/Ghidra/Features/Sarif/src/main/java/sarif/managers/SarifMgr.java index 6b39fb332e..c5caeaf80c 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/managers/SarifMgr.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/managers/SarifMgr.java @@ -22,24 +22,13 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.contrastsecurity.sarif.ArtifactLocation; -import com.contrastsecurity.sarif.Location; -import com.contrastsecurity.sarif.PhysicalLocation; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - import ghidra.app.util.NamespaceUtils; import ghidra.app.util.importer.MessageLog; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressFactory; import ghidra.program.model.address.AddressFormatException; import ghidra.program.model.address.AddressOverflowException; -import ghidra.program.model.address.AddressRange; -import ghidra.program.model.address.AddressRangeImpl; -import ghidra.program.model.address.AddressRangeIterator; import ghidra.program.model.address.AddressSet; -import ghidra.program.model.address.AddressSetView; -import ghidra.program.model.address.AddressSpace; import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Listing; import ghidra.program.model.listing.Program; @@ -52,6 +41,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.InvalidInputException; import ghidra.util.task.TaskMonitor; import sarif.SarifProgramOptions; +import sarif.SarifUtils; public abstract class SarifMgr { @@ -89,89 +79,8 @@ public abstract class SarifMgr { columnKeys.put("typeLocation", true); } - protected void writeLocation(JsonObject result, Address start, Address end) { - JsonArray locs = new JsonArray(); - result.add("locations", locs); - JsonObject element = new JsonObject(); - locs.add(element); - JsonObject ploc = new JsonObject(); - element.add("physicalLocation", ploc); - JsonObject address = new JsonObject(); - ploc.add("address", address); - address.addProperty("absoluteAddress", start.getOffset()); - if (end != null) { - address.addProperty("length", end.subtract(start) + 1); - if (!start.getAddressSpace().equals(program.getAddressFactory().getDefaultAddressSpace())) { - JsonObject artifact = new JsonObject(); - ploc.add("artifactLocation", artifact); - artifact.addProperty("uri", start.toString()); - } - } - } - - protected void writeLocations(JsonObject result, AddressSetView set) { - JsonArray locs = new JsonArray(); - result.add("locations", locs); - AddressRangeIterator addressRanges = set.getAddressRanges(); - while (addressRanges.hasNext()) { - JsonObject element = new JsonObject(); - locs.add(element); - AddressRange next = addressRanges.next(); - JsonObject ploc = new JsonObject(); - element.add("physicalLocation", ploc); - JsonObject address = new JsonObject(); - ploc.add("address", address); - address.addProperty("absoluteAddress", next.getMinAddress().getOffset()); - address.addProperty("length", next.getLength()); - Address minAddress = next.getMinAddress(); - if (!minAddress.getAddressSpace().equals(program.getAddressFactory().getDefaultAddressSpace())) { - JsonObject artifact = new JsonObject(); - ploc.add("artifactLocation", artifact); - artifact.addProperty("uri", minAddress.toString()); - } - } - } - - @SuppressWarnings("unchecked") protected AddressSet getLocations(Map result, AddressSet set) throws AddressOverflowException { - if (set == null) { - set = new AddressSet(); - } - AddressFactory af = program.getAddressFactory(); - AddressSpace space = af.getDefaultAddressSpace(); - String namespace = (String) result.get("location"); - if (namespace != null) { - boolean isExternal = namespace.contains(""); - if (isExternal) { - space = af.getAddressSpace("EXTERNAL"); - } - } - String ospace = (String) result.get("overlayedSpace"); - if (ospace != null) { - space = af.getAddressSpace(ospace); - } - List locations = (List) result.get("Locations"); - if (locations == null) { - return set; - } - for (Location location : locations) { - PhysicalLocation physicalLocation = location.getPhysicalLocation(); - Object addr = physicalLocation.getAddress().getAbsoluteAddress(); - Address address = longToAddress(space, addr); - long len = (long) physicalLocation.getAddress().getLength(); - ArtifactLocation artifact = physicalLocation.getArtifactLocation(); - if (artifact != null) { - String uri = artifact.getUri(); - if (uri != null) { - Address test = program.getAddressFactory().getAddress(uri); - if (test != null) { - address = test; - } - } - } - set.add(new AddressRangeImpl(address, len)); - } - return set; + return SarifUtils.getLocations(result, program, set); } protected Address getLocation(Map result) throws AddressOverflowException { @@ -259,10 +168,7 @@ public abstract class SarifMgr { } Address addr = factory.getAddress(addrString); if (addr == null) { - int index = addrString.indexOf("::"); - if (index > 0) { - addr = factory.getAddress(addrString.substring(index + 2)); - } + throw new RuntimeException("Error converting "+addrString+" to address"); } return addr; } @@ -313,11 +219,4 @@ public abstract class SarifMgr { return unescapedStr; } - public Address longToAddress(AddressSpace space, Object addr) { - if (addr instanceof Long) { - return space.getAddress((Long) addr); - } - return space.getAddress((Integer) addr); - } - } diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/managers/SymbolTableSarifMgr.java b/Ghidra/Features/Sarif/src/main/java/sarif/managers/SymbolTableSarifMgr.java index 025e1fc9b9..1f8ab5c685 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/managers/SymbolTableSarifMgr.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/managers/SymbolTableSarifMgr.java @@ -80,6 +80,7 @@ public class SymbolTableSarifMgr extends SarifMgr { String type = (String) result.get("type"); boolean isPrimary = (boolean) result.get("primary"); + boolean isPinned = (boolean) result.get("pinned"); String sourceTypeString = (String) result.get("sourceType"); SourceType sourceType = getSourceType(sourceTypeString); @@ -134,6 +135,9 @@ public class SymbolTableSarifMgr extends SarifMgr { if (s != null && isPrimary && overwritePrimary) { s.setPrimary(); } + if (isPinned) { + s.setPinned(true); + } } } catch (Exception e) { log.appendException(e);