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
This commit is contained in:
d-millar 2024-01-05 18:55:22 -05:00
parent df05b6b8fe
commit af73f267d0
10 changed files with 244 additions and 252 deletions

View file

@ -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<String, Object> result, Program program,
AddressSet set) throws AddressOverflowException {
if (set == null) {
set = new AddressSet();
}
List<Location> locations = (List<Location>) 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<ReportingDescriptor> view = new ArrayList<>(taxonomy.getTaxa());
return view.get(taxa.getIndex().intValue());
}
public static ToolComponent getTaxonomy(ReportingDescriptorReference taxa, Set<ToolComponent> taxonomies) {
public static ToolComponent getTaxonomy(ReportingDescriptorReference taxa,
Set<ToolComponent> taxonomies) {
Object idx = taxa.getToolComponent().getIndex();
if (idx == null) {
List<ToolComponent> 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())) {