mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GT-3376: Design improvements
This commit is contained in:
parent
a46e788706
commit
73b018fd84
13 changed files with 149 additions and 170 deletions
|
@ -17,7 +17,8 @@ package ghidra.app.util.importer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import generic.stl.Pair;
|
import generic.stl.Pair;
|
||||||
|
@ -202,8 +203,7 @@ public final class AutoImporter {
|
||||||
|
|
||||||
private static LoadSpec getLoadSpec(Predicate<Loader> loaderFilter,
|
private static LoadSpec getLoadSpec(Predicate<Loader> loaderFilter,
|
||||||
LoadSpecChooser loadSpecChooser, ByteProvider provider) {
|
LoadSpecChooser loadSpecChooser, ByteProvider provider) {
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap =
|
LoadMap loadMap = LoaderService.getSupportedLoadSpecs(provider, loaderFilter);
|
||||||
LoaderService.getSupportedLoadSpecs(provider, loaderFilter);
|
|
||||||
|
|
||||||
LoadSpec loadSpec = loadSpecChooser.choose(loadMap);
|
LoadSpec loadSpec = loadSpecChooser.choose(loadMap);
|
||||||
if (loadSpec != null) {
|
if (loadSpec != null) {
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.util.importer;
|
||||||
|
|
||||||
|
import ghidra.app.util.opinion.*;
|
||||||
|
import ghidra.program.model.lang.CompilerSpec;
|
||||||
|
import ghidra.program.model.lang.CompilerSpecID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on a provided {@link CompilerSpec}.
|
||||||
|
*/
|
||||||
|
public class CsHintLoadSpecChooser implements LoadSpecChooser {
|
||||||
|
private final CompilerSpecID compilerSpecID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link CsHintLoadSpecChooser}
|
||||||
|
*
|
||||||
|
* @param compilerSpecID The {@link CompilerSpecID} to use (should not be null)
|
||||||
|
*/
|
||||||
|
public CsHintLoadSpecChooser(CompilerSpecID compilerSpecID) {
|
||||||
|
this.compilerSpecID = compilerSpecID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link CsHintLoadSpecChooser}
|
||||||
|
*
|
||||||
|
* @param compilerSpecID The {@link CompilerSpecID} to use (should not be null)
|
||||||
|
*/
|
||||||
|
public CsHintLoadSpecChooser(String compilerSpecID) {
|
||||||
|
this(new CompilerSpecID(compilerSpecID));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoadSpec choose(LoadMap loadMap) {
|
||||||
|
|
||||||
|
return loadMap.values()
|
||||||
|
.stream()
|
||||||
|
.flatMap(loadSpec -> loadSpec.stream())
|
||||||
|
.filter(loadSpec -> loadSpec.getLanguageCompilerSpec().compilerSpecID
|
||||||
|
.equals(compilerSpecID))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,6 @@
|
||||||
package ghidra.app.util.importer;
|
package ghidra.app.util.importer;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ghidra.app.util.opinion.*;
|
import ghidra.app.util.opinion.*;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
|
@ -46,22 +45,11 @@ public class LcsHintLoadSpecChooser implements LoadSpecChooser {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoadSpec choose(Map<Loader, Collection<LoadSpec>> loadMap) {
|
public LoadSpec choose(LoadMap loadMap) {
|
||||||
|
|
||||||
// We need to reduce the set of matching loaders down to one. The only requirement is that
|
// Use the highest priority loader (it will be the first one)
|
||||||
// if we do reduce, make sure we don't reduce it to the BinaryLoader.
|
Loader loader = loadMap.keySet().stream().findFirst().orElse(null);
|
||||||
Loader loader;
|
if (loader == null) {
|
||||||
if (loadMap.size() > 1) {
|
|
||||||
loader = loadMap.keySet()
|
|
||||||
.stream()
|
|
||||||
.filter(e -> e.getTier() != LoaderTier.UNTARGETED_LOADER)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
else if (loadMap.size() == 1) {
|
|
||||||
loader = loadMap.keySet().iterator().next();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.importer;
|
package ghidra.app.util.importer;
|
||||||
|
|
||||||
import java.util.Collection;
|
import ghidra.app.util.opinion.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ghidra.app.util.opinion.LoadSpec;
|
|
||||||
import ghidra.app.util.opinion.Loader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on some criteria
|
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on some criteria
|
||||||
|
@ -30,10 +26,10 @@ public interface LoadSpecChooser {
|
||||||
/**
|
/**
|
||||||
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on some criteria
|
* Chooses a {@link LoadSpec} for a {@link Loader} to use based on some criteria
|
||||||
*
|
*
|
||||||
* @param loadMap A {@link Map} of {@link Loader}s to their respective {@link LoadSpec}s
|
* @param loadMap A {@link LoadMap}
|
||||||
* @return The chosen {@link LoadSpec}
|
* @return The chosen {@link LoadSpec}, or null if one could not be found
|
||||||
*/
|
*/
|
||||||
public LoadSpec choose(Map<Loader, Collection<LoadSpec>> loadMap);
|
public LoadSpec choose(LoadMap loadMap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chooses the first "preferred" {@link LoadSpec}
|
* Chooses the first "preferred" {@link LoadSpec}
|
||||||
|
@ -43,8 +39,8 @@ public interface LoadSpecChooser {
|
||||||
public static final LoadSpecChooser CHOOSE_THE_FIRST_PREFERRED = loadMap -> {
|
public static final LoadSpecChooser CHOOSE_THE_FIRST_PREFERRED = loadMap -> {
|
||||||
return loadMap.values()
|
return loadMap.values()
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(e -> e.stream())
|
.flatMap(loadSpecs -> loadSpecs.stream())
|
||||||
.filter(e -> e != null && e.isPreferred())
|
.filter(loadSpec -> loadSpec != null && loadSpec.isPreferred())
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.util.opinion;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Map} of {@link Loader}s to their respective {@link LoadSpec}s.
|
||||||
|
* <p>
|
||||||
|
* The {@link Loader} keys are sorted according to their {@link Loader#compareTo(Loader) natural
|
||||||
|
* ordering}.
|
||||||
|
*/
|
||||||
|
public class LoadMap extends TreeMap<Loader, Collection<LoadSpec>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new, empty {@link LoadMap}
|
||||||
|
*/
|
||||||
|
public LoadMap() {
|
||||||
|
super((loader1, loader2) -> loader1.compareTo(loader2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (Loader loader : keySet()) {
|
||||||
|
Collection<LoadSpec> loadSpecs = get(loader);
|
||||||
|
sb.append(loader.getName() + " - " + loadSpecs.size() + " load specs\n");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,13 +36,11 @@ public class LoaderService {
|
||||||
*
|
*
|
||||||
* @param provider The {@link ByteProvider} to load.
|
* @param provider The {@link ByteProvider} to load.
|
||||||
* @param loaderFilter A {@link Predicate} that will filter out undesired {@link Loader}s.
|
* @param loaderFilter A {@link Predicate} that will filter out undesired {@link Loader}s.
|
||||||
* @return A {@link Map} of {@link Loader}s to their respective {@link LoadSpec}s. It is safe
|
* @return All supported {@link LoadSpec}s in the form of a {@link LoadMap}.
|
||||||
* to assume that every {@link Loader} in the {@link Map} will have at least one
|
|
||||||
* {@link LoadSpec}.
|
|
||||||
*/
|
*/
|
||||||
public static Map<Loader, Collection<LoadSpec>> getSupportedLoadSpecs(ByteProvider provider,
|
public static LoadMap getSupportedLoadSpecs(ByteProvider provider,
|
||||||
Predicate<Loader> loaderFilter) {
|
Predicate<Loader> loaderFilter) {
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap = new LinkedHashMap<>(); // maintain loader order
|
LoadMap loadMap = new LoadMap();
|
||||||
for (Loader loader : getAllLoaders()) {
|
for (Loader loader : getAllLoaders()) {
|
||||||
if (loaderFilter.test(loader)) {
|
if (loaderFilter.test(loader)) {
|
||||||
try {
|
try {
|
||||||
|
@ -67,27 +65,25 @@ public class LoaderService {
|
||||||
* Gets all supported {@link LoadSpec}s for loading the given {@link ByteProvider}.
|
* Gets all supported {@link LoadSpec}s for loading the given {@link ByteProvider}.
|
||||||
*
|
*
|
||||||
* @param provider The {@link ByteProvider} to load.
|
* @param provider The {@link ByteProvider} to load.
|
||||||
* @return A {@link Map} of {@link Loader}s to their respective {@link LoadSpec}s. It is safe
|
* @return All supported {@link LoadSpec}s in the form of a {@link LoadMap}.
|
||||||
* to assume that every {@link Loader} in the {@link Map} will have at least one
|
|
||||||
* {@link LoadSpec}.
|
|
||||||
*/
|
*/
|
||||||
public static Map<Loader, Collection<LoadSpec>> getAllSupportedLoadSpecs(
|
public static LoadMap getAllSupportedLoadSpecs(ByteProvider provider) {
|
||||||
ByteProvider provider) {
|
|
||||||
return getSupportedLoadSpecs(provider, ACCEPT_ALL);
|
return getSupportedLoadSpecs(provider, ACCEPT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all known {@link Loader}s' names.
|
* Gets all known {@link Loader}s' names.
|
||||||
*
|
*
|
||||||
* @return All known {@link Loader}s' names.
|
* @return All known {@link Loader}s' names. The {@link Loader} names are sorted
|
||||||
|
* according to their corresponding {@link Loader}s {@link Loader#compareTo(Loader) natural
|
||||||
|
* ordering}.
|
||||||
*/
|
*/
|
||||||
public static Collection<String> getAllLoaderNames() {
|
public static Collection<String> getAllLoaderNames() {
|
||||||
//@formatter:off
|
|
||||||
return getAllLoaders()
|
return getAllLoaders()
|
||||||
.stream()
|
.stream()
|
||||||
|
.sorted()
|
||||||
.map(loader -> loader.getName())
|
.map(loader -> loader.getName())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,20 +95,19 @@ public class LoaderService {
|
||||||
* name.
|
* name.
|
||||||
*/
|
*/
|
||||||
public static Class<? extends Loader> getLoaderClassByName(String name) {
|
public static Class<? extends Loader> getLoaderClassByName(String name) {
|
||||||
//@formatter:off
|
|
||||||
return getAllLoaders()
|
return getAllLoaders()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(loader -> loader.getClass().getSimpleName().equals(name))
|
.filter(loader -> loader.getClass().getSimpleName().equals(name))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(loader -> loader.getClass())
|
.map(loader -> loader.getClass())
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
//@formatter:on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an instance of every known {@link Loader}.
|
* Gets an instance of every known {@link Loader}.
|
||||||
*
|
*
|
||||||
* @return An instance of every known {@link Loader}.
|
* @return An instance of every known {@link Loader}. The {@link Loader} instances are sorted
|
||||||
|
* according to their {@link Loader#compareTo(Loader) natural ordering}.
|
||||||
*/
|
*/
|
||||||
private synchronized static Collection<Loader> getAllLoaders() {
|
private synchronized static Collection<Loader> getAllLoaders() {
|
||||||
List<Loader> loaders = new ArrayList<>(ClassSearcher.getInstances(Loader.class));
|
List<Loader> loaders = new ArrayList<>(ClassSearcher.getInstances(Loader.class));
|
||||||
|
|
|
@ -15,12 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.plugin.importer;
|
package ghidra.plugin.importer;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.Option;
|
import ghidra.app.util.Option;
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.opinion.LoadSpec;
|
import ghidra.app.util.opinion.*;
|
||||||
import ghidra.app.util.opinion.Loader;
|
|
||||||
import ghidra.formats.gfilesystem.FSRL;
|
import ghidra.formats.gfilesystem.FSRL;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.model.DomainFolder;
|
import ghidra.framework.model.DomainFolder;
|
||||||
|
@ -47,9 +46,8 @@ public class AddToProgramDialog extends ImporterDialog {
|
||||||
* @param byteProvider the ByteProvider from which the bytes from the source can be read.
|
* @param byteProvider the ByteProvider from which the bytes from the source can be read.
|
||||||
* @param addToProgram the program to which the newly imported data will be added
|
* @param addToProgram the program to which the newly imported data will be added
|
||||||
*/
|
*/
|
||||||
protected AddToProgramDialog(PluginTool tool, FSRL fsrl,
|
protected AddToProgramDialog(PluginTool tool, FSRL fsrl, LoadMap loadMap,
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap, ByteProvider byteProvider,
|
ByteProvider byteProvider, Program addToProgram) {
|
||||||
Program addToProgram) {
|
|
||||||
super("Add To Program: " + fsrl.getPath(), tool, loadMap, byteProvider, null);
|
super("Add To Program: " + fsrl.getPath(), tool, loadMap, byteProvider, null);
|
||||||
this.addToProgram = addToProgram;
|
this.addToProgram = addToProgram;
|
||||||
folderNameTextField.setText(getFolderName(addToProgram));
|
folderNameTextField.setText(getFolderName(addToProgram));
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class ImporterDialog extends DialogComponentProvider {
|
||||||
private ProgramManager programManager;
|
private ProgramManager programManager;
|
||||||
protected FSRL fsrl;
|
protected FSRL fsrl;
|
||||||
protected List<Option> options;
|
protected List<Option> options;
|
||||||
private Map<Loader, Collection<LoadSpec>> loadMap;
|
private LoadMap loadMap;
|
||||||
protected LanguageCompilerSpecPair selectedLanguage;
|
protected LanguageCompilerSpecPair selectedLanguage;
|
||||||
private DomainFolder destinationFolder;
|
private DomainFolder destinationFolder;
|
||||||
private boolean languageNeeded;
|
private boolean languageNeeded;
|
||||||
|
@ -96,17 +96,15 @@ public class ImporterDialog extends DialogComponentProvider {
|
||||||
* option which requires the DomainFolder to already exist). The two destination paths work together
|
* option which requires the DomainFolder to already exist). The two destination paths work together
|
||||||
* to specify the final Ghidra project folder where the imported binary is placed.
|
* to specify the final Ghidra project folder where the imported binary is placed.
|
||||||
*/
|
*/
|
||||||
public ImporterDialog(PluginTool tool, ProgramManager programManager,
|
public ImporterDialog(PluginTool tool, ProgramManager programManager, LoadMap loadMap,
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap, ByteProvider byteProvider,
|
ByteProvider byteProvider, String suggestedDestinationPath) {
|
||||||
String suggestedDestinationPath) {
|
|
||||||
this("Import " + byteProvider.getFSRL().getPath(), tool, loadMap, byteProvider,
|
this("Import " + byteProvider.getFSRL().getPath(), tool, loadMap, byteProvider,
|
||||||
suggestedDestinationPath);
|
suggestedDestinationPath);
|
||||||
this.programManager = programManager;
|
this.programManager = programManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ImporterDialog(String title, PluginTool tool,
|
protected ImporterDialog(String title, PluginTool tool, LoadMap loadMap,
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap, ByteProvider byteProvider,
|
ByteProvider byteProvider, String suggestedDestinationPath) {
|
||||||
String suggestedDestinationPath) {
|
|
||||||
super(title);
|
super(title);
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
this.programManager = tool.getService(ProgramManager.class);
|
this.programManager = tool.getService(ProgramManager.class);
|
||||||
|
|
|
@ -271,8 +271,8 @@ public class ImporterUtilities {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap = LoaderService.getSupportedLoadSpecs(
|
LoadMap loadMap = LoaderService.getSupportedLoadSpecs(provider,
|
||||||
provider, loader -> loader.supportsLoadIntoProgram());
|
loader -> loader.supportsLoadIntoProgram());
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(() -> {
|
SystemUtilities.runSwingLater(() -> {
|
||||||
AddToProgramDialog dialog =
|
AddToProgramDialog dialog =
|
||||||
|
@ -309,8 +309,7 @@ public class ImporterUtilities {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ByteProvider provider = FileSystemService.getInstance().getByteProvider(fsrl, monitor);
|
ByteProvider provider = FileSystemService.getInstance().getByteProvider(fsrl, monitor);
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap =
|
LoadMap loadMap = LoaderService.getAllSupportedLoadSpecs(provider);
|
||||||
LoaderService.getAllSupportedLoadSpecs(provider);
|
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(() -> {
|
SystemUtilities.runSwingLater(() -> {
|
||||||
ImporterDialog importerDialog =
|
ImporterDialog importerDialog =
|
||||||
|
|
|
@ -357,8 +357,7 @@ public class BatchInfo {
|
||||||
|
|
||||||
try (ByteProvider provider =
|
try (ByteProvider provider =
|
||||||
FileSystemService.getInstance().getByteProvider(fsrl, monitor)) {
|
FileSystemService.getInstance().getByteProvider(fsrl, monitor)) {
|
||||||
Map<Loader, Collection<LoadSpec>> loadMap =
|
LoadMap loadMap = pollLoadersForLoadSpecs(provider, fsrl, monitor);
|
||||||
pollLoadersForLoadSpecs(provider, fsrl, monitor);
|
|
||||||
for (Loader loader : loadMap.keySet()) {
|
for (Loader loader : loadMap.keySet()) {
|
||||||
Collection<LoadSpec> loadSpecs = loadMap.get(loader);
|
Collection<LoadSpec> loadSpecs = loadMap.get(loader);
|
||||||
BatchSegregatingCriteria bsc =
|
BatchSegregatingCriteria bsc =
|
||||||
|
@ -380,8 +379,7 @@ public class BatchInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Loader, Collection<LoadSpec>> pollLoadersForLoadSpecs(ByteProvider provider,
|
private LoadMap pollLoadersForLoadSpecs(ByteProvider provider, FSRL fsrl, TaskMonitor monitor) {
|
||||||
FSRL fsrl, TaskMonitor monitor) {
|
|
||||||
monitor.setMessage(fsrl.getName());
|
monitor.setMessage(fsrl.getName());
|
||||||
return LoaderService.getSupportedLoadSpecs(provider,
|
return LoaderService.getSupportedLoadSpecs(provider,
|
||||||
loader -> !(loader instanceof BinaryLoader));
|
loader -> !(loader instanceof BinaryLoader));
|
||||||
|
|
|
@ -19,7 +19,6 @@ 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.*;
|
||||||
|
@ -27,53 +26,20 @@ import ghidra.app.util.bin.format.coff.*;
|
||||||
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
|
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
|
||||||
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
|
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
|
||||||
import ghidra.app.util.importer.*;
|
import ghidra.app.util.importer.*;
|
||||||
import ghidra.app.util.opinion.*;
|
import ghidra.app.util.opinion.Loader;
|
||||||
|
import ghidra.app.util.opinion.MSCoffLoader;
|
||||||
import ghidra.framework.model.DomainFolder;
|
import ghidra.framework.model.DomainFolder;
|
||||||
import ghidra.framework.store.local.LocalFileSystem;
|
import ghidra.framework.store.local.LocalFileSystem;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.LanguageDescription;
|
||||||
import ghidra.program.model.listing.Program;
|
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.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 = loadMap -> {
|
final static LoadSpecChooser LOADSPEC_CHOOSER = new CsHintLoadSpecChooser("windows");
|
||||||
Stream<LoadSpec> loadSpecStream = loadMap.values().stream().flatMap(e -> e.stream());
|
|
||||||
Iterable<LoadSpec> loadSpecs = CollectionUtils.asIterable(loadSpecStream.iterator());
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// XXX short circuit; for now only process valid windows opinions, which means x86
|
|
||||||
if (Math.min(1, 2) == 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
try {
|
|
||||||
if (lcsp.getLanguageDescription().getProcessor() == Processor.toProcessor(
|
|
||||||
"ARM") && lcsp.getLanguageDescription().getEndian() == Endian.LITTLE &&
|
|
||||||
lcsp.getLanguageDescription().getVariant().contains("v7")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (LanguageNotFoundException e) {
|
|
||||||
// ignore...not sure why this happened
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("gcc")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws Exception {
|
protected void run() throws Exception {
|
||||||
|
|
|
@ -54,7 +54,6 @@ 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;
|
||||||
|
|
||||||
|
@ -65,49 +64,20 @@ import ghidra.app.util.bin.format.coff.*;
|
||||||
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
|
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
|
||||||
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
|
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
|
||||||
import ghidra.app.util.importer.*;
|
import ghidra.app.util.importer.*;
|
||||||
import ghidra.app.util.opinion.*;
|
import ghidra.app.util.opinion.Loader;
|
||||||
|
import ghidra.app.util.opinion.MSCoffLoader;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.model.DomainFolder;
|
import ghidra.framework.model.DomainFolder;
|
||||||
import ghidra.framework.store.local.LocalFileSystem;
|
import ghidra.framework.store.local.LocalFileSystem;
|
||||||
import ghidra.program.model.lang.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
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 = loadMap -> {
|
final static LoadSpecChooser LOADSPEC_CHOOSER = new CsHintLoadSpecChooser("windows");
|
||||||
Stream<LoadSpec> loadSpecStream = loadMap.values().stream().flatMap(e -> e.stream());
|
|
||||||
Iterable<LoadSpec> loadSpecs = CollectionUtils.asIterable(loadSpecStream.iterator());
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
try {
|
|
||||||
if (lcsp.getLanguageDescription().getEndian() == Endian.LITTLE &&
|
|
||||||
lcsp.getLanguageDescription().getVariant().contains("v7")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (LanguageNotFoundException e) {
|
|
||||||
// ignore...not sure why this happened
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("gcc")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
private static String getProcessId(String fallback) {
|
private static String getProcessId(String fallback) {
|
||||||
// something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
|
// something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
|
||||||
|
|
|
@ -17,7 +17,6 @@ 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;
|
||||||
|
@ -26,47 +25,18 @@ import ghidra.app.util.bin.format.coff.*;
|
||||||
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
|
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
|
||||||
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
|
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
|
||||||
import ghidra.app.util.importer.*;
|
import ghidra.app.util.importer.*;
|
||||||
import ghidra.app.util.opinion.*;
|
import ghidra.app.util.opinion.Loader;
|
||||||
|
import ghidra.app.util.opinion.MSCoffLoader;
|
||||||
import ghidra.framework.model.DomainFolder;
|
import ghidra.framework.model.DomainFolder;
|
||||||
import ghidra.framework.store.local.LocalFileSystem;
|
import ghidra.framework.store.local.LocalFileSystem;
|
||||||
import ghidra.program.model.lang.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
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 = loadMap -> {
|
final static LoadSpecChooser LOADSPEC_CHOOSER = new CsHintLoadSpecChooser("windows");
|
||||||
Stream<LoadSpec> loadSpecStream = loadMap.values().stream().flatMap(e -> e.stream());
|
|
||||||
Iterable<LoadSpec> loadSpecs = CollectionUtils.asIterable(loadSpecStream.iterator());
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("windows")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
try {
|
|
||||||
if (lcsp.getLanguageDescription().getEndian() == Endian.LITTLE &&
|
|
||||||
lcsp.getLanguageDescription().getVariant().contains("v7")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (LanguageNotFoundException e) {
|
|
||||||
// ignore...not sure why this happened
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LoadSpec loadSpec : loadSpecs) {
|
|
||||||
LanguageCompilerSpecPair lcsp = loadSpec.getLanguageCompilerSpec();
|
|
||||||
if (lcsp.compilerSpecID.getIdAsString().equals("gcc")) {
|
|
||||||
return loadSpec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws Exception {
|
protected void run() throws Exception {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue