mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Merge remote-tracking branch
'origin/GP-6073-dragonmacher-fid-plugin-delayed-loading-12.0' into Ghidra_12.0 (Closes #8593)
This commit is contained in:
@@ -114,19 +114,25 @@ public class FidAnalyzer extends AbstractAnalyzer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getDefaultEnablement(Program program) {
|
public boolean getDefaultEnablement(Program program) {
|
||||||
return service.canProcess(program.getLanguage());
|
// Loading Fid db files can be slow. For now, signal that we can analyze and check later.
|
||||||
|
return true;
|
||||||
|
//return service.canProcess(program.getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAnalyze(Program program) {
|
public boolean canAnalyze(Program program) {
|
||||||
return service.canProcess(program.getLanguage());
|
// Loading Fid db files can be slow. For now, signal that we can analyze and check later.
|
||||||
|
return true;
|
||||||
|
//return service.canProcess(program.getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
|
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
|
|
||||||
if (!service.canProcess(program.getLanguage())) {
|
if (!service.canProcess(program.getLanguage())) {
|
||||||
Msg.warn(this, "No FID Libraries apply for language " + program.getLanguageID());
|
// This can now happen, since we no longer check in canAnalyze()
|
||||||
|
Msg.debug(this, "No FID Libraries apply for language " + program.getLanguageID());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,18 @@ import generic.util.Path;
|
|||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
import ghidra.program.model.lang.Language;
|
import ghidra.program.model.lang.Language;
|
||||||
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.VersionException;
|
import ghidra.util.exception.VersionException;
|
||||||
|
import ghidra.util.task.TaskLauncher;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the set of FidFiles for the application. This uses the singleton pattern and
|
* Manages the set of FidFiles for the application. This uses the singleton pattern and
|
||||||
* all users of Fid databases must use this to get open Fid databases. This ensures that
|
* all users of Fid databases must use this to get open Fid databases. This ensures that
|
||||||
* there is only one updateable Fid database open for any given FidFile.
|
* there is only one updatable Fid database open for any given FidFile.
|
||||||
*/
|
*/
|
||||||
public class FidFileManager {
|
public class FidFileManager {
|
||||||
|
|
||||||
@@ -48,7 +52,7 @@ public class FidFileManager {
|
|||||||
private WeakSet<ChangeListener> listeners;
|
private WeakSet<ChangeListener> listeners;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the singleton instance of the FidFileManager.
|
* {@return the singleton instance of the FidFileManager.}
|
||||||
*/
|
*/
|
||||||
public static FidFileManager getInstance() {
|
public static FidFileManager getInstance() {
|
||||||
if (THE_FID_FILE_MANAGER == null) {
|
if (THE_FID_FILE_MANAGER == null) {
|
||||||
@@ -59,14 +63,23 @@ public class FidFileManager {
|
|||||||
|
|
||||||
private FidFileManager() {
|
private FidFileManager() {
|
||||||
listeners = WeakDataStructureFactory.createCopyOnWriteWeakSet();
|
listeners = WeakDataStructureFactory.createCopyOnWriteWeakSet();
|
||||||
// findDeliveredFidFiles(); - too slow
|
|
||||||
// restoreFromPreferences();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<FidFile> loadFidFiles() {
|
private Set<FidFile> loadFidFiles() {
|
||||||
if (fidFiles == null) {
|
if (fidFiles == null) {
|
||||||
findDeliveredFidFiles();
|
|
||||||
restoreFromPreferences();
|
TaskLauncher.launchModal("Loading Fid Files", monitor -> {
|
||||||
|
|
||||||
|
fidFiles = new CopyOnWriteArraySet<>();
|
||||||
|
try {
|
||||||
|
findDeliveredFidFiles(monitor);
|
||||||
|
restoreFromPreferences(monitor);
|
||||||
|
}
|
||||||
|
catch (CancelledException ce) {
|
||||||
|
Msg.showWarn(this, null, "Fid Loading Cancelled", "User cancelled Fid Db " +
|
||||||
|
"loading. To load all Fid Db files, the tool must be restarted.");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return fidFiles;
|
return fidFiles;
|
||||||
@@ -74,7 +87,7 @@ public class FidFileManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add user FidDb file
|
* Add user FidDb file
|
||||||
* @param file
|
* @param file the file
|
||||||
* @return FidFile or null if invalid
|
* @return FidFile or null if invalid
|
||||||
*/
|
*/
|
||||||
public FidFile addUserFidFile(File file) {
|
public FidFile addUserFidFile(File file) {
|
||||||
@@ -105,7 +118,7 @@ public class FidFileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all the FidFiles know to the application.
|
* {@return a list of all the FidFiles know to the application.}
|
||||||
*/
|
*/
|
||||||
public List<FidFile> getFidFiles() {
|
public List<FidFile> getFidFiles() {
|
||||||
loadFidFiles();
|
loadFidFiles();
|
||||||
@@ -114,13 +127,30 @@ public class FidFileManager {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasFidFiles() {
|
/**
|
||||||
loadFidFiles();
|
* Triggers a load of the Fid db files, if not already loaded.
|
||||||
return !fidFiles.isEmpty();
|
*/
|
||||||
|
public void load() {
|
||||||
|
if (fidFiles == null) {
|
||||||
|
loadFidFiles();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return true if Fid db files have been loaded and files have been found.}
|
||||||
|
*/
|
||||||
|
public boolean hasFidFiles() {
|
||||||
|
return fidFiles != null && !fidFiles.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return true if Fid db files have been loaded and user Fid files have been found.}
|
||||||
|
*/
|
||||||
public boolean hasUserFidFiles() {
|
public boolean hasUserFidFiles() {
|
||||||
loadFidFiles();
|
if (fidFiles == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (FidFile fidFile : fidFiles) {
|
for (FidFile fidFile : fidFiles) {
|
||||||
if (!fidFile.isInstalled()) {
|
if (!fidFile.isInstalled()) {
|
||||||
return true;
|
return true;
|
||||||
@@ -130,8 +160,15 @@ public class FidFileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all the user added (non installation) Fid files. This will
|
* {@return true if the Fid db files have been loaded.}
|
||||||
* be files containing packed databases.
|
*/
|
||||||
|
public boolean hasLoadedFidFiles() {
|
||||||
|
return fidFiles != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return a list of all the user added (non installation) Fid files. This will
|
||||||
|
* be files containing packed databases.}
|
||||||
*/
|
*/
|
||||||
public List<FidFile> getUserAddedFiles() {
|
public List<FidFile> getUserAddedFiles() {
|
||||||
loadFidFiles();
|
loadFidFiles();
|
||||||
@@ -251,17 +288,20 @@ public class FidFileManager {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restoreFromPreferences() {
|
private void restoreFromPreferences(TaskMonitor monitor) throws CancelledException {
|
||||||
Set<File> userAddedFiles = getFilesFromPreference(USER_ADDED_FILES);
|
Set<File> userAddedFiles = getFilesFromPreference(USER_ADDED_FILES);
|
||||||
addUserFidFiles(userAddedFiles);
|
monitor.initialize(userAddedFiles.size(), "Adding user Fid files...");
|
||||||
|
doAddUserFidFiles(userAddedFiles, monitor);
|
||||||
|
|
||||||
Set<File> excludedFiles = getFilesFromPreference(INACTIVE_FID_FILES);
|
Set<File> excludedFiles = getFilesFromPreference(INACTIVE_FID_FILES);
|
||||||
excludeFidFiles(excludedFiles);
|
monitor.initialize(excludedFiles.size(), "Removing inactive user Fid files...");
|
||||||
|
doExcludeFidFiles(excludedFiles, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addUserFidFiles(Set<File> userAddedFiles) {
|
private void doAddUserFidFiles(Set<File> userAddedFiles, TaskMonitor monitor)
|
||||||
loadFidFiles();
|
throws CancelledException {
|
||||||
for (File file : userAddedFiles) {
|
for (File file : userAddedFiles) {
|
||||||
|
monitor.increment();
|
||||||
FidFile fidFile = new FidFile(this, file, false);
|
FidFile fidFile = new FidFile(this, file, false);
|
||||||
if (fidFile.isValidFile()) {
|
if (fidFile.isValidFile()) {
|
||||||
fidFiles.add(fidFile);
|
fidFiles.add(fidFile);
|
||||||
@@ -269,9 +309,10 @@ public class FidFileManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void excludeFidFiles(Set<File> excludedFiles) {
|
private void doExcludeFidFiles(Set<File> excludedFiles, TaskMonitor monitor)
|
||||||
loadFidFiles();
|
throws CancelledException {
|
||||||
for (FidFile fidFile : fidFiles) {
|
for (FidFile fidFile : fidFiles) {
|
||||||
|
monitor.increment();
|
||||||
if (excludedFiles.contains(fidFile.getFile())) {
|
if (excludedFiles.contains(fidFile.getFile())) {
|
||||||
fidFile.setActive(false);
|
fidFile.setActive(false);
|
||||||
}
|
}
|
||||||
@@ -296,11 +337,14 @@ public class FidFileManager {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findDeliveredFidFiles() {
|
private void findDeliveredFidFiles(TaskMonitor monitor) throws CancelledException {
|
||||||
fidFiles = new CopyOnWriteArraySet<>();
|
|
||||||
List<ResourceFile> foundFiles =
|
List<ResourceFile> foundFiles =
|
||||||
Application.findFilesByExtensionInApplication(FidFile.FID_RAW_DATABASE_FILE_EXTENSION);
|
Application.findFilesByExtensionInApplication(FidFile.FID_RAW_DATABASE_FILE_EXTENSION);
|
||||||
|
|
||||||
|
monitor.initialize(foundFiles.size(), "Processing included Fid files...");
|
||||||
for (ResourceFile resourceFile : foundFiles) {
|
for (ResourceFile resourceFile : foundFiles) {
|
||||||
|
monitor.increment();
|
||||||
File file = resourceFile.getFile(true);
|
File file = resourceFile.getFile(true);
|
||||||
FidFile fidFile = new FidFile(this, file, true);
|
FidFile fidFile = new FidFile(this, file, true);
|
||||||
if (fidFile.isValidFile()) {
|
if (fidFile.isValidFile()) {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
*/
|
*/
|
||||||
private void createStandardActions() {
|
private void createStandardActions() {
|
||||||
new ActionBuilder("Choose Active FidDbs", getName())
|
new ActionBuilder("Choose Active FidDbs", getName())
|
||||||
.enabledWhen(ac -> fidFileManager.hasFidFiles())
|
.enabledWhen(ac -> enabledForAnyFidFiles())
|
||||||
.onAction(ac -> chooseActiveFidDbs())
|
.onAction(ac -> chooseActiveFidDbs())
|
||||||
.menuPath(ToolConstants.MENU_TOOLS, FUNCTION_ID_NAME, "Choose active FidDbs...")
|
.menuPath(ToolConstants.MENU_TOOLS, FUNCTION_ID_NAME, "Choose active FidDbs...")
|
||||||
.menuGroup(MENU_GROUP_1, "1")
|
.menuGroup(MENU_GROUP_1, "1")
|
||||||
@@ -121,7 +121,7 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
.buildAndInstall(tool);
|
.buildAndInstall(tool);
|
||||||
|
|
||||||
new ActionBuilder("Detach attached FidDb", getName())
|
new ActionBuilder("Detach attached FidDb", getName())
|
||||||
.enabledWhen(ac -> fidFileManager.hasUserFidFiles())
|
.enabledWhen(ac -> enabledForUserFidFiles())
|
||||||
.onAction(ac -> removeFidFile())
|
.onAction(ac -> removeFidFile())
|
||||||
.menuPath(ToolConstants.MENU_TOOLS, FUNCTION_ID_NAME, "Detach attached FidDb...")
|
.menuPath(ToolConstants.MENU_TOOLS, FUNCTION_ID_NAME, "Detach attached FidDb...")
|
||||||
.menuGroup(MENU_GROUP_1, "4")
|
.menuGroup(MENU_GROUP_1, "4")
|
||||||
@@ -130,8 +130,9 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
.buildAndInstall(tool);
|
.buildAndInstall(tool);
|
||||||
|
|
||||||
new ActionBuilder("Populate FidDb from programs", getName())
|
new ActionBuilder("Populate FidDb from programs", getName())
|
||||||
.enabledWhen(ac -> fidFileManager.hasUserFidFiles())
|
.enabledWhen(ac -> enabledForUserFidFiles())
|
||||||
.onAction(ac -> {
|
.onAction(ac -> {
|
||||||
|
fidFileManager.load();
|
||||||
PopulateFidDialog populateFidDialog = new PopulateFidDialog(tool, service);
|
PopulateFidDialog populateFidDialog = new PopulateFidDialog(tool, service);
|
||||||
tool.showDialog(populateFidDialog);
|
tool.showDialog(populateFidDialog);
|
||||||
})
|
})
|
||||||
@@ -143,11 +144,30 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
.buildAndInstall(tool);
|
.buildAndInstall(tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean enabledForAnyFidFiles() {
|
||||||
|
if (!fidFileManager.hasLoadedFidFiles()) {
|
||||||
|
// We haven't loaded Fid files yet. Since we don't know if we can enable, return true
|
||||||
|
// so users can at least try to perform the action.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return fidFileManager.hasFidFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean enabledForUserFidFiles() {
|
||||||
|
if (!fidFileManager.hasLoadedFidFiles()) {
|
||||||
|
// We haven't loaded Fid files yet. Since we don't know if we can enable, return true
|
||||||
|
// so users can at least try to perform the action.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return fidFileManager.hasUserFidFiles();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to select which known FID databases are currently active
|
* Method to select which known FID databases are currently active
|
||||||
* during search.
|
* during search.
|
||||||
*/
|
*/
|
||||||
private synchronized void chooseActiveFidDbs() {
|
private synchronized void chooseActiveFidDbs() {
|
||||||
|
fidFileManager.load();
|
||||||
ActiveFidConfigureDialog dialog =
|
ActiveFidConfigureDialog dialog =
|
||||||
new ActiveFidConfigureDialog(fidFileManager.getFidFiles());
|
new ActiveFidConfigureDialog(fidFileManager.getFidFiles());
|
||||||
tool.showDialog(dialog);
|
tool.showDialog(dialog);
|
||||||
@@ -159,6 +179,7 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
* extension (.fidb). If they don't, we will add it for them.
|
* extension (.fidb). If they don't, we will add it for them.
|
||||||
*/
|
*/
|
||||||
private void createFidDb() {
|
private void createFidDb() {
|
||||||
|
fidFileManager.load();
|
||||||
File dbFile = askFile("Create new FidDb file", "Create");
|
File dbFile = askFile("Create new FidDb file", "Create");
|
||||||
if (dbFile == null) {
|
if (dbFile == null) {
|
||||||
return;
|
return;
|
||||||
@@ -186,6 +207,7 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
* Method to attach an already-created (but heretofore unknown) database.
|
* Method to attach an already-created (but heretofore unknown) database.
|
||||||
*/
|
*/
|
||||||
private void attachFidDb() {
|
private void attachFidDb() {
|
||||||
|
fidFileManager.load();
|
||||||
File dbFile = askFile("Attach existing FidDb file", "Attach");
|
File dbFile = askFile("Attach existing FidDb file", "Attach");
|
||||||
if (dbFile != null) {
|
if (dbFile != null) {
|
||||||
fidFileManager.addUserFidFile(dbFile);
|
fidFileManager.addUserFidFile(dbFile);
|
||||||
@@ -196,6 +218,8 @@ public class FidPlugin extends ProgramPlugin implements ChangeListener {
|
|||||||
* Method to "forget" about (close and stop trying to re-open next session) a FID database.
|
* Method to "forget" about (close and stop trying to re-open next session) a FID database.
|
||||||
*/
|
*/
|
||||||
private void removeFidFile() {
|
private void removeFidFile() {
|
||||||
|
fidFileManager.load();
|
||||||
|
|
||||||
FidFile fidFile = askChoice("Choose FidDb to detach", "Please choose the FidDb to detach",
|
FidFile fidFile = askChoice("Choose FidDb to detach", "Please choose the FidDb to detach",
|
||||||
fidFileManager.getUserAddedFiles(), null);
|
fidFileManager.getUserAddedFiles(), null);
|
||||||
if (fidFile != null) {
|
if (fidFile != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user