mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GT-3376: Headless now properly honors -processor flag, even if the
specified processor is not a valid opinion.
This commit is contained in:
parent
3ce8d3fa39
commit
a46e788706
6 changed files with 167 additions and 287 deletions
|
@ -205,60 +205,17 @@ public final class AutoImporter {
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap =
|
Map<Loader, Collection<LoadSpec>> loadMap =
|
||||||
LoaderService.getSupportedLoadSpecs(provider, loaderFilter);
|
LoaderService.getSupportedLoadSpecs(provider, loaderFilter);
|
||||||
|
|
||||||
List<LoadSpec> allLoadSpecs = new ArrayList<>();
|
LoadSpec loadSpec = loadSpecChooser.choose(loadMap);
|
||||||
for (Collection<LoadSpec> loadSpecs : loadMap.values()) {
|
if (loadSpec != null) {
|
||||||
allLoadSpecs.addAll(loadSpecs);
|
return loadSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "count" up our preferred (we really only care about 0, 1, and >1)
|
|
||||||
int preferredCount = 0;
|
|
||||||
LoadSpec preferred = null;
|
|
||||||
for (LoadSpec op : allLoadSpecs) {
|
|
||||||
if (op.isPreferred()) {
|
|
||||||
if (preferred == null) {
|
|
||||||
preferred = op;
|
|
||||||
preferredCount = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
preferredCount = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we had just one load spec, we forcefully consider it preferred
|
|
||||||
if (allLoadSpecs.size() == 1) {
|
|
||||||
preferredCount = 1;
|
|
||||||
preferred = allLoadSpecs.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not just one preferred loadSpec? ask loadSpec chooser
|
|
||||||
LoadSpec loadSpec;
|
|
||||||
if (loadSpecChooser.usePreferred() && preferredCount == 1) {
|
|
||||||
loadSpec = preferred;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
loadSpec = loadSpecChooser.choose(allLoadSpecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadSpec chooser tell us it can't pick one? can't import
|
|
||||||
if (loadSpec == null) {
|
|
||||||
File f = provider.getFile();
|
File f = provider.getFile();
|
||||||
String name = f != null ? f.getAbsolutePath() : provider.getName();
|
String name = f != null ? f.getAbsolutePath() : provider.getName();
|
||||||
Msg.info(AutoImporter.class, "No load spec found for import file: " + name);
|
Msg.info(AutoImporter.class, "No load spec found for import file: " + name);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allLoadSpecs.size() > 1) {
|
|
||||||
for (LoadSpec unusedLoadSpec : allLoadSpecs) {
|
|
||||||
if (unusedLoadSpec.getLoader().getTier() != LoaderTier.UNTARGETED_LOADER &&
|
|
||||||
!unusedLoadSpec.equals(loadSpec)) {
|
|
||||||
Msg.trace(AutoImporter.class, "discarding load spec " + unusedLoadSpec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Program> getPrograms(List<DomainObject> domainObjects) {
|
private static List<Program> getPrograms(List<DomainObject> domainObjects) {
|
||||||
List<Program> programs = new ArrayList<Program>();
|
List<Program> programs = new ArrayList<Program>();
|
||||||
for (DomainObject domainObject : domainObjects) {
|
for (DomainObject domainObject : domainObjects) {
|
||||||
|
@ -269,84 +226,4 @@ public final class AutoImporter {
|
||||||
|
|
||||||
return programs;
|
return programs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean importAddToProgram(File file, Program program, MessageLog messageLog,
|
|
||||||
TaskMonitor monitor, Predicate<Loader> loaderFilter, LoadSpecChooser loadSpecChooser,
|
|
||||||
OptionChooser optionChooser) throws IOException, CancelledException {
|
|
||||||
if (file == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadSpec loadSpec = null;
|
|
||||||
try (RandomAccessByteProvider provider = new RandomAccessByteProvider(file)) {
|
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap =
|
|
||||||
LoaderService.getSupportedLoadSpecs(provider, loaderFilter);
|
|
||||||
|
|
||||||
List<LoadSpec> allLoadSpecs = new ArrayList<>();
|
|
||||||
for (Collection<LoadSpec> loadSpecs : loadMap.values()) {
|
|
||||||
allLoadSpecs.addAll(loadSpecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// "count" up our preferred (we really only care about 0, 1, and >1)
|
|
||||||
int preferredCount = 0;
|
|
||||||
LoadSpec preferred = null;
|
|
||||||
for (LoadSpec op : allLoadSpecs) {
|
|
||||||
if (op.isPreferred()) {
|
|
||||||
if (preferred == null) {
|
|
||||||
preferred = op;
|
|
||||||
preferredCount = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
preferredCount = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we had just one load spec, we forcefully consider it preferred
|
|
||||||
if (allLoadSpecs.size() == 1) {
|
|
||||||
preferredCount = 1;
|
|
||||||
preferred = allLoadSpecs.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not just one preferred loadSpec? ask loadSpec chooser
|
|
||||||
if (loadSpecChooser.usePreferred() && preferredCount == 1) {
|
|
||||||
loadSpec = preferred;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
loadSpec = loadSpecChooser.choose(allLoadSpecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadSpec chooser tell us it can't pick one? can't import
|
|
||||||
if (loadSpec == null) {
|
|
||||||
File f = provider.getFile();
|
|
||||||
String name = f != null ? f.getAbsolutePath() : provider.getName();
|
|
||||||
Msg.info(AutoImporter.class, "No load spec found for import file: " + name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageCompilerSpecPair programPair = new LanguageCompilerSpecPair(
|
|
||||||
program.getLanguageID(), program.getCompilerSpec().getCompilerSpecID());
|
|
||||||
// loadSpec doesn't match current program
|
|
||||||
if (!loadSpec.getLanguageCompilerSpec().equals(programPair)) {
|
|
||||||
Msg.info(AutoImporter.class,
|
|
||||||
"Import file load spec does not match add-to program: " +
|
|
||||||
file.getAbsolutePath());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Option> options = null;
|
|
||||||
try (RandomAccessByteProvider provider = new RandomAccessByteProvider(file)) {
|
|
||||||
List<Option> optionChoices =
|
|
||||||
loadSpec.getLoader().getDefaultOptions(provider, loadSpec, program, true);
|
|
||||||
options = optionChooser.choose(optionChoices,
|
|
||||||
DefaultLanguageService.getLanguageService().getLanguage(
|
|
||||||
loadSpec.getLanguageCompilerSpec().languageID).getAddressFactory());
|
|
||||||
}
|
|
||||||
|
|
||||||
try (RandomAccessByteProvider provider = new RandomAccessByteProvider(file)) {
|
|
||||||
return loadSpec.getLoader().loadInto(provider, loadSpec, options, messageLog, program,
|
|
||||||
monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,64 +15,75 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.importer;
|
package ghidra.app.util.importer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import ghidra.app.util.opinion.LoadSpec;
|
import ghidra.app.util.opinion.*;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
import util.CollectionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on a provided {@link Language} and
|
||||||
|
* {@link CompilerSpec}.
|
||||||
|
*/
|
||||||
public class LcsHintLoadSpecChooser implements LoadSpecChooser {
|
public class LcsHintLoadSpecChooser implements LoadSpecChooser {
|
||||||
private final LanguageID languageID;
|
private final LanguageID languageID;
|
||||||
private final CompilerSpecID compilerSpecID;
|
private final CompilerSpecID compilerSpecID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link LcsHintLoadSpecChooser}.
|
||||||
|
* <p>
|
||||||
|
* NOTE: It is assumed that the given {@link Language} is valid and it supports the given
|
||||||
|
* {@link CompilerSpec}.
|
||||||
|
*
|
||||||
|
* @param language The {@link Language} to use (should not be null)
|
||||||
|
* @param compilerSpec The {@link CompilerSpec} to use (should not be null)
|
||||||
|
*/
|
||||||
public LcsHintLoadSpecChooser(Language language, CompilerSpec compilerSpec) {
|
public LcsHintLoadSpecChooser(Language language, CompilerSpec compilerSpec) {
|
||||||
this.languageID = language.getLanguageID();
|
this.languageID = language.getLanguageID();
|
||||||
this.compilerSpecID = compilerSpec == null ? null : compilerSpec.getCompilerSpecID();
|
this.compilerSpecID = compilerSpec.getCompilerSpecID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoadSpec choose(List<LoadSpec> loadSpecs) {
|
public LoadSpec choose(Map<Loader, Collection<LoadSpec>> loadMap) {
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
if (loadSpec == null) {
|
// We need to reduce the set of matching loaders down to one. The only requirement is that
|
||||||
Msg.warn(this, "found null load spec whilst trying to choose");
|
// if we do reduce, make sure we don't reduce it to the BinaryLoader.
|
||||||
|
Loader loader;
|
||||||
|
if (loadMap.size() > 1) {
|
||||||
|
loader = loadMap.keySet()
|
||||||
|
.stream()
|
||||||
|
.filter(e -> e.getTier() != LoaderTier.UNTARGETED_LOADER)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
else if (loadSpec.isPreferred()) {
|
else if (loadMap.size() == 1) {
|
||||||
LanguageCompilerSpecPair lcsPair = loadSpec.getLanguageCompilerSpec();
|
loader = loadMap.keySet().iterator().next();
|
||||||
if (lcsPair == null) {
|
|
||||||
Msg.warn(this, "load spec " + loadSpec +
|
|
||||||
" proffered null LCS pair whilst trying to choose");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (lcsPair.languageID.equals(languageID) &&
|
|
||||||
(compilerSpecID == null || lcsPair.compilerSpecID.equals(compilerSpecID))) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
if (loadSpec == null) {
|
|
||||||
Msg.warn(this, "found null load spec whilst trying to choose");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LanguageCompilerSpecPair lcsPair = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsPair == null) {
|
|
||||||
Msg.warn(this, "load spec " + loadSpec +
|
|
||||||
" proffered null LCS pair whilst trying to choose");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (lcsPair.languageID.equals(languageID) &&
|
|
||||||
(compilerSpecID == null || lcsPair.compilerSpecID.equals(compilerSpecID))) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Try to use a known LoadSpec that matches the desired language/compiler spec
|
||||||
public boolean usePreferred() {
|
Collection<LoadSpec> loadSpecs = loadMap.get(loader);
|
||||||
return false;
|
for (LoadSpec loadSpec : loadSpecs) {
|
||||||
|
LanguageCompilerSpecPair lcsPair = loadSpec.getLanguageCompilerSpec();
|
||||||
|
if (lcsPair.languageID.equals(languageID) &&
|
||||||
|
(compilerSpecID == null || lcsPair.compilerSpecID.equals(compilerSpecID))) {
|
||||||
|
return loadSpec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The desired language/compiler spec is not a defined LoadSpec, so we'll create a custom
|
||||||
|
// one. This could result in crazy results/analysis, but the point of this chooser is to do
|
||||||
|
// what we are told.
|
||||||
|
LoadSpec anyLoadSpec = CollectionUtils.any(loadSpecs);
|
||||||
|
LanguageCompilerSpecPair customLcsPair =
|
||||||
|
new LanguageCompilerSpecPair(languageID, compilerSpecID);
|
||||||
|
LoadSpec customLoadSpec =
|
||||||
|
new LoadSpec(loader, anyLoadSpec.getDesiredImageBase(), customLcsPair, false);
|
||||||
|
Msg.warn(this, "Using unknown opinion: " + loader.getName() + ", " + customLcsPair);
|
||||||
|
return customLoadSpec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,33 +15,37 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.importer;
|
package ghidra.app.util.importer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import ghidra.app.util.opinion.LoadSpec;
|
import ghidra.app.util.opinion.LoadSpec;
|
||||||
import ghidra.util.Msg;
|
import ghidra.app.util.opinion.Loader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on some criteria
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface LoadSpecChooser {
|
public interface LoadSpecChooser {
|
||||||
public static final LoadSpecChooser CHOOSE_THE_FIRST_PREFERRED = new LoadSpecChooser() {
|
|
||||||
@Override
|
|
||||||
public LoadSpec choose(List<LoadSpec> loadSpecs) {
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
if (loadSpec == null) {
|
|
||||||
Msg.warn(this, "found null load spec whilst trying to choose");
|
|
||||||
}
|
|
||||||
else if (loadSpec.isPreferred()) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean usePreferred() {
|
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on some criteria
|
||||||
return true;
|
*
|
||||||
}
|
* @param loadMap A {@link Map} of {@link Loader}s to their respective {@link LoadSpec}s
|
||||||
|
* @return The chosen {@link LoadSpec}
|
||||||
|
*/
|
||||||
|
public LoadSpec choose(Map<Loader, Collection<LoadSpec>> loadMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses the first "preferred" {@link LoadSpec}
|
||||||
|
*
|
||||||
|
* @see LoadSpec#isPreferred()
|
||||||
|
*/
|
||||||
|
public static final LoadSpecChooser CHOOSE_THE_FIRST_PREFERRED = loadMap -> {
|
||||||
|
return loadMap.values()
|
||||||
|
.stream()
|
||||||
|
.flatMap(e -> e.stream())
|
||||||
|
.filter(e -> e != null && e.isPreferred())
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
public LoadSpec choose(List<LoadSpec> loadSpecs);
|
|
||||||
|
|
||||||
public boolean usePreferred();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.app.util.bin.*;
|
import ghidra.app.util.bin.*;
|
||||||
|
@ -35,12 +36,13 @@ import ghidra.util.InvalidNameException;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.CancelOnlyWrappingTaskMonitor;
|
import ghidra.util.task.CancelOnlyWrappingTaskMonitor;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
import util.CollectionUtils;
|
||||||
|
|
||||||
public class ImportMSLibs extends GhidraScript {
|
public class ImportMSLibs extends GhidraScript {
|
||||||
final static Predicate<Loader> LOADER_FILTER = new SingleLoaderFilter(MSCoffLoader.class);
|
final static Predicate<Loader> LOADER_FILTER = new SingleLoaderFilter(MSCoffLoader.class);
|
||||||
final static LoadSpecChooser LOADSPEC_CHOOSER = new LoadSpecChooser() {
|
final static LoadSpecChooser LOADSPEC_CHOOSER = loadMap -> {
|
||||||
@Override
|
Stream<LoadSpec> loadSpecStream = loadMap.values().stream().flatMap(e -> e.stream());
|
||||||
public LoadSpec choose(List<LoadSpec> loadSpecs) {
|
Iterable<LoadSpec> loadSpecs = CollectionUtils.asIterable(loadSpecStream.iterator());
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
for (LoadSpec loadSpec : loadSpecs) {
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
||||||
|
@ -71,12 +73,6 @@ public class ImportMSLibs extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usePreferred() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -54,6 +54,7 @@ import java.io.IOException;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
|
@ -73,13 +74,14 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.InvalidNameException;
|
import ghidra.util.InvalidNameException;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
import util.CollectionUtils;
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
|
|
||||||
public class MSLibBatchImportWorker extends GhidraScript {
|
public class MSLibBatchImportWorker extends GhidraScript {
|
||||||
final static Predicate<Loader> LOADER_FILTER = new SingleLoaderFilter(MSCoffLoader.class);
|
final static Predicate<Loader> LOADER_FILTER = new SingleLoaderFilter(MSCoffLoader.class);
|
||||||
final static LoadSpecChooser LOADSPEC_CHOOSER = new LoadSpecChooser() {
|
final static LoadSpecChooser LOADSPEC_CHOOSER = loadMap -> {
|
||||||
@Override
|
Stream<LoadSpec> loadSpecStream = loadMap.values().stream().flatMap(e -> e.stream());
|
||||||
public LoadSpec choose(List<LoadSpec> loadSpecs) {
|
Iterable<LoadSpec> loadSpecs = CollectionUtils.asIterable(loadSpecStream.iterator());
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
for (LoadSpec loadSpec : loadSpecs) {
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
||||||
|
@ -105,12 +107,6 @@ public class MSLibBatchImportWorker extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usePreferred() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static String getProcessId(String fallback) {
|
private static String getProcessId(String fallback) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import generic.stl.Pair;
|
import generic.stl.Pair;
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
@ -33,12 +34,13 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.InvalidNameException;
|
import ghidra.util.InvalidNameException;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
import util.CollectionUtils;
|
||||||
|
|
||||||
public class RecursiveRecursiveMSLibImport extends GhidraScript {
|
public class RecursiveRecursiveMSLibImport extends GhidraScript {
|
||||||
final static Predicate<Loader> LOADER_FILTER = new SingleLoaderFilter(MSCoffLoader.class);
|
final static Predicate<Loader> LOADER_FILTER = new SingleLoaderFilter(MSCoffLoader.class);
|
||||||
final static LoadSpecChooser LOADSPEC_CHOOSER = new LoadSpecChooser() {
|
final static LoadSpecChooser LOADSPEC_CHOOSER = loadMap -> {
|
||||||
@Override
|
Stream<LoadSpec> loadSpecStream = loadMap.values().stream().flatMap(e -> e.stream());
|
||||||
public LoadSpec choose(List<LoadSpec> loadSpecs) {
|
Iterable<LoadSpec> loadSpecs = CollectionUtils.asIterable(loadSpecStream.iterator());
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
for (LoadSpec loadSpec : loadSpecs) {
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
||||||
|
@ -64,12 +66,6 @@ public class RecursiveRecursiveMSLibImport extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usePreferred() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue