mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-07-30 07:18:37 -09:00
Merge remote-tracking branch
'origin/GP-5128_ryanmkurtz_extensions--SQUASHED' (Closes #7128)
This commit is contained in:
@@ -827,6 +827,11 @@ public class CoffLoader extends AbstractLibrarySupportLoader {
|
||||
return COFF_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("o", "obj");
|
||||
}
|
||||
|
||||
class CoffPair {
|
||||
public long offset;
|
||||
public long size;
|
||||
|
||||
@@ -51,6 +51,11 @@ public class ComLoader extends AbstractLibrarySupportLoader {
|
||||
return COM_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("com");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFallback() {
|
||||
return true;
|
||||
|
||||
@@ -193,6 +193,11 @@ public class ElfLoader extends AbstractLibrarySupportLoader {
|
||||
return ELF_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("so", "o");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to detect a more specific compiler from the ELF
|
||||
*
|
||||
|
||||
@@ -289,4 +289,9 @@ public class IntelHexLoader extends AbstractProgramLoader {
|
||||
public String getName() {
|
||||
return INTEL_HEX_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("hex");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,6 +297,13 @@ public interface Loader extends ExtensionPoint, Comparable<Loader> {
|
||||
return COMMAND_LINE_ARG_PREFIX + arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@link Collection} of file extensions associated with this {@link Loader}}
|
||||
*/
|
||||
public default Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public default int compareTo(Loader o) {
|
||||
int compareTiers = getTier().compareTo(o.getTier());
|
||||
|
||||
@@ -168,7 +168,7 @@ public class LoaderService {
|
||||
* @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() {
|
||||
public synchronized static Collection<Loader> getAllLoaders() {
|
||||
List<Loader> loaders = new ArrayList<>(ClassSearcher.getInstances(Loader.class));
|
||||
Collections.sort(loaders);
|
||||
return loaders;
|
||||
|
||||
@@ -178,6 +178,11 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||
return MACH_O_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("dylib");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValidSearchPath(FSRL fsrl, ImporterSettings settings)
|
||||
throws CancelledException {
|
||||
|
||||
@@ -829,4 +829,9 @@ public class NeLoader extends AbstractOrdinalSupportLoader {
|
||||
return NE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("exe", "dll");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -480,4 +480,9 @@ public class Omf51Loader extends AbstractProgramWrapperLoader {
|
||||
public String getName() {
|
||||
return OMF51_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("obj");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,11 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
||||
return OMF_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("obj");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(Program program, ImporterSettings settings)
|
||||
throws IOException, CancelledException {
|
||||
|
||||
@@ -870,6 +870,11 @@ public class PeLoader extends AbstractPeDebugLoader {
|
||||
return PE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("exe", "dll", "sys");
|
||||
}
|
||||
|
||||
public static class CompilerOpinion {
|
||||
static final char[] errString_borland =
|
||||
"This program must be run under Win32\r\n$".toCharArray();
|
||||
|
||||
@@ -79,6 +79,13 @@ public interface GFileSystem extends Closeable, Iterable<GFile>, ExtensionPoint
|
||||
return FSUtilities.getFilesystemDescriptionFromClass(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a {@link Collection} of file extensions associated with this {@link GFileSystem}}
|
||||
*/
|
||||
public default Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* File system's FSRL
|
||||
*
|
||||
|
||||
@@ -45,6 +45,11 @@ public @interface FileSystemInfo {
|
||||
*/
|
||||
String description() default "";
|
||||
|
||||
/**
|
||||
* {@return an array of file extensions associated with this filesystem}
|
||||
*/
|
||||
public String[] extensions() default {};
|
||||
|
||||
/**
|
||||
* The {@link GFileSystemFactory} class that will be responsible for probing and
|
||||
* creating instances of this filesystem.
|
||||
|
||||
@@ -17,6 +17,7 @@ package ghidra.formats.gfilesystem.factory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
@@ -116,6 +117,18 @@ public class FileSystemFactoryMgr {
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a map of associated file system extensions keyed by file system description}
|
||||
*/
|
||||
public Map<String, String[]> getFilesystemExtensionsByDescription() {
|
||||
return sortedFactories
|
||||
.stream()
|
||||
.collect(
|
||||
Collectors.toMap(FileSystemInfoRec::getDescription,
|
||||
FileSystemInfoRec::getExtensions));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file system type of the specified {@link GFileSystem} class.
|
||||
*
|
||||
|
||||
@@ -36,6 +36,7 @@ public class FileSystemInfoRec {
|
||||
private final int priority;
|
||||
private final Class<? extends GFileSystem> fsClass;
|
||||
private final GFileSystemFactory<?> factory;
|
||||
private final String[] extensions;
|
||||
|
||||
/**
|
||||
* A static {@link Comparator} that will order {@link FileSystemInfoRec} by their
|
||||
@@ -54,6 +55,7 @@ public class FileSystemInfoRec {
|
||||
* @return new {@link FileSystemInfoRec}, or null if the class doesn't have
|
||||
* valid file system meta data.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static FileSystemInfoRec fromClass(Class<? extends GFileSystem> fsClazz) {
|
||||
FileSystemInfo fsi = fsClazz.getAnnotation(FileSystemInfo.class);
|
||||
if (fsi == null) {
|
||||
@@ -81,24 +83,26 @@ public class FileSystemInfoRec {
|
||||
|
||||
// Hack to allow GFileSystemBaseFactory to know which fsclass is using it
|
||||
// so instances can be created by the single GFileSystemBaseFactory impl.
|
||||
if (factory instanceof GFileSystemBaseFactory) {
|
||||
((GFileSystemBaseFactory) factory).setFileSystemClass(
|
||||
(Class<? extends GFileSystemBase>) fsClazz);
|
||||
if (factory instanceof GFileSystemBaseFactory base) {
|
||||
base.setFileSystemClass((Class<? extends GFileSystemBase>) fsClazz);
|
||||
}
|
||||
|
||||
FileSystemInfoRec fsir =
|
||||
new FileSystemInfoRec(fsType, fsi.description(), fsi.priority(), fsClazz, factory);
|
||||
new FileSystemInfoRec(fsType, fsi.description(), fsi.priority(), fsClazz, factory,
|
||||
fsi.extensions());
|
||||
|
||||
return fsir;
|
||||
}
|
||||
|
||||
private FileSystemInfoRec(String type, String description, int priority,
|
||||
Class<? extends GFileSystem> fsClass, GFileSystemFactory<?> factory) {
|
||||
Class<? extends GFileSystem> fsClass, GFileSystemFactory<?> factory,
|
||||
String[] extensions) {
|
||||
this.type = type;
|
||||
this.description = description;
|
||||
this.priority = priority;
|
||||
this.fsClass = fsClass;
|
||||
this.factory = factory;
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,4 +152,11 @@ public class FileSystemInfoRec {
|
||||
public GFileSystemFactory<?> getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the associated file extensions for this filesystem}
|
||||
*/
|
||||
public String[] getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,8 +465,8 @@ public class ImporterPlugin extends Plugin
|
||||
private void initializeChooser(String title, String buttonText, boolean multiSelect) {
|
||||
if (chooser == null) {
|
||||
chooser = new GhidraFileChooser(tool.getActiveWindow());
|
||||
chooser.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
|
||||
chooser.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
|
||||
ImporterUtilities.addLoadableFileFilters(chooser);
|
||||
ImporterUtilities.addFileSystemFileFilters(chooser);
|
||||
chooser.setSelectedFileFilter(GhidraFileFilter.ALL);
|
||||
}
|
||||
chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import ghidra.app.events.ProgramAddedToPluginEvent;
|
||||
import ghidra.app.plugin.core.help.AboutDomainObjectUtils;
|
||||
import ghidra.app.services.FileSystemBrowserService;
|
||||
@@ -31,6 +32,7 @@ import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.*;
|
||||
import ghidra.app.util.opinion.Loader.ImporterSettings;
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.formats.gfilesystem.factory.FileSystemFactoryMgr;
|
||||
import ghidra.framework.main.AppInfo;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import ghidra.framework.model.*;
|
||||
@@ -46,7 +48,6 @@ import ghidra.util.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.CryptoException;
|
||||
import ghidra.util.filechooser.ExtensionFileFilter;
|
||||
import ghidra.util.filechooser.GhidraFileFilter;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import util.CollectionUtils;
|
||||
@@ -60,20 +61,44 @@ import util.CollectionUtils;
|
||||
public class ImporterUtilities {
|
||||
|
||||
/**
|
||||
* File extension filter for well known 'loadable' files for GhidraFileChoosers.
|
||||
* Adds file filters for associated {@link Loader} file extensions to the given
|
||||
* {@link GhidraFileChooser}
|
||||
*
|
||||
* @param chooser The {@link GhidraFileChooser} to add extension file filters to
|
||||
*/
|
||||
public static final GhidraFileFilter LOADABLE_FILES_FILTER = ExtensionFileFilter.forExtensions(
|
||||
"Loadable files", "exe", "dll", "obj", "drv", "bin", "hex", "o", "a", "so", "class", "lib",
|
||||
"dylib");
|
||||
public static void addLoadableFileFilters(GhidraFileChooser chooser) {
|
||||
Set<String> all = new HashSet<>();
|
||||
for (Loader loader : LoaderService.getAllLoaders()) {
|
||||
Collection<String> exts = loader.getAssociatedFileExtensions();
|
||||
if (!exts.isEmpty()) {
|
||||
chooser.addFileFilter(new ExtensionFileFilter(exts, loader.getName()));
|
||||
all.addAll(exts);
|
||||
}
|
||||
}
|
||||
if (!all.isEmpty()) {
|
||||
chooser.addFileFilter(new ExtensionFileFilter(all, "Loadable files"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* File extension filter for well known 'container' files for GhidraFileChoosers.
|
||||
* Adds file filters for associated {@link GFileSystem} file extensions to the given
|
||||
* {@link GhidraFileChooser}
|
||||
*
|
||||
* @param chooser The {@link GhidraFileChooser} to add extension file filters to
|
||||
*/
|
||||
public static final GhidraFileFilter CONTAINER_FILES_FILTER =
|
||||
ExtensionFileFilter.forExtensions("Container files", "zip", "tar", "tgz", "jar", "gz",
|
||||
"ipsw", "img3", "dmg", "apk", "cpio", "rpm", "lib");
|
||||
|
||||
private static final FileSystemService fsService = FileSystemService.getInstance();
|
||||
public static void addFileSystemFileFilters(GhidraFileChooser chooser) {
|
||||
Set<String> all = new HashSet<>();
|
||||
FileSystemFactoryMgr mgr = FileSystemFactoryMgr.getInstance();
|
||||
mgr.getFilesystemExtensionsByDescription().forEach((description, exts) -> {
|
||||
if (exts.length > 0) {
|
||||
chooser.addFileFilter(new ExtensionFileFilter(exts, description));
|
||||
Collections.addAll(all, exts);
|
||||
}
|
||||
});
|
||||
if (!all.isEmpty()) {
|
||||
chooser.addFileFilter(new ExtensionFileFilter(all, "Container files"));
|
||||
}
|
||||
}
|
||||
|
||||
static List<LanguageCompilerSpecPair> getPairs(Collection<LoadSpec> loadSpecs) {
|
||||
Set<LanguageCompilerSpecPair> pairs = new HashSet<>();
|
||||
@@ -133,6 +158,8 @@ public class ImporterUtilities {
|
||||
|
||||
Objects.requireNonNull(monitor);
|
||||
|
||||
FileSystemService fsService = FileSystemService.getInstance();
|
||||
|
||||
try (RefdFile referencedFile = fsService.getRefdFile(fsrl, monitor)) {
|
||||
if (!ensureFileImportable(referencedFile, monitor)) {
|
||||
return;
|
||||
@@ -222,6 +249,7 @@ public class ImporterUtilities {
|
||||
}
|
||||
|
||||
try {
|
||||
FileSystemService fsService = FileSystemService.getInstance();
|
||||
ByteProvider provider = fsService.getByteProvider(fsrl, false, monitor);
|
||||
if (provider.length() == 0) {
|
||||
Msg.showWarn(null, null, "Error opening " + fsrl.getName(),
|
||||
@@ -319,6 +347,7 @@ public class ImporterUtilities {
|
||||
TaskMonitor monitor) {
|
||||
|
||||
try {
|
||||
FileSystemService fsService = FileSystemService.getInstance();
|
||||
ByteProvider provider = fsService.getByteProvider(fsrl, true, monitor);
|
||||
LoaderMap loaderMap = LoaderService.getAllSupportedLoadSpecs(provider, monitor);
|
||||
|
||||
@@ -421,6 +450,8 @@ public class ImporterUtilities {
|
||||
|
||||
Objects.requireNonNull(monitor);
|
||||
|
||||
FileSystemService fsService = FileSystemService.getInstance();
|
||||
|
||||
try (ByteProvider bp = fsService.getByteProvider(fsrl, false, monitor)) {
|
||||
MessageLog messageLog = new MessageLog();
|
||||
|
||||
@@ -511,6 +542,7 @@ public class ImporterUtilities {
|
||||
|
||||
Objects.requireNonNull(monitor);
|
||||
|
||||
FileSystemService fsService = FileSystemService.getInstance();
|
||||
MessageLog messageLog = new MessageLog();
|
||||
Object consumer = new Object();
|
||||
program.addConsumer(consumer);
|
||||
|
||||
@@ -203,8 +203,8 @@ public class FileSystemBrowserPlugin extends Plugin
|
||||
private void openChooser(String title, String buttonText, boolean multiSelect) {
|
||||
if (chooserOpen == null) {
|
||||
chooserOpen = new GhidraFileChooser(tool.getActiveWindow());
|
||||
chooserOpen.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
|
||||
chooserOpen.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
|
||||
ImporterUtilities.addLoadableFileFilters(chooserOpen);
|
||||
ImporterUtilities.addFileSystemFileFilters(chooserOpen);
|
||||
chooserOpen.setSelectedFileFilter(GhidraFileFilter.ALL);
|
||||
}
|
||||
chooserOpen.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
|
||||
|
||||
@@ -464,8 +464,8 @@ public class BatchImportDialog extends DialogComponentProvider {
|
||||
chooser.setTitle("Choose File to Batch Import");
|
||||
chooser.setApproveButtonText("Select files");
|
||||
chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
|
||||
chooser.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
|
||||
chooser.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
|
||||
ImporterUtilities.addLoadableFileFilters(chooser);
|
||||
ImporterUtilities.addFileSystemFileFilters(chooser);
|
||||
chooser.setSelectedFileFilter(GhidraFileFilter.ALL);
|
||||
|
||||
chooser.setLastDirectoryPreference(LAST_IMPORT_DIR);
|
||||
|
||||
@@ -133,6 +133,11 @@ public class DyldCacheExtractLoader extends MachoLoader {
|
||||
return DYLD_CACHE_EXTRACT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTierPriority() {
|
||||
return 49; // Higher priority than MachoLoader
|
||||
|
||||
@@ -104,6 +104,11 @@ public class MachoFileSetExtractLoader extends MachoLoader {
|
||||
return MACHO_FILESET_EXTRACT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTierPriority() {
|
||||
return 49; // Higher priority than MachoLoader
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -33,7 +33,12 @@ import ghidra.util.task.TaskMonitor;
|
||||
* APK is really just a ZIP file.
|
||||
*
|
||||
*/
|
||||
@FileSystemInfo(type = "apk", description = "Android APK", factory = GFileSystemBaseFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "apk",
|
||||
description = "Android APK",
|
||||
factory = GFileSystemBaseFactory.class,
|
||||
extensions = { "apk" }
|
||||
)
|
||||
public class ApkFileSystem extends GFileSystemBase {
|
||||
|
||||
public ApkFileSystem(String fileSystemName, ByteProvider provider) {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -30,7 +30,12 @@ import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@FileSystemInfo(type = "coff", description = "COFF Archive", factory = CoffArchiveFileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "coff",
|
||||
description = "COFF Archive",
|
||||
factory = CoffArchiveFileSystemFactory.class,
|
||||
extensions = { "a" }
|
||||
)
|
||||
public class CoffArchiveFileSystem extends AbstractFileSystem<CoffArchiveMemberHeader> {
|
||||
|
||||
private ByteProvider provider;
|
||||
|
||||
@@ -32,7 +32,12 @@ import ghidra.formats.gfilesystem.fileinfo.FileType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@FileSystemInfo(type = "cpio", description = "CPIO", factory = CpioFileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "cpio",
|
||||
description = "CPIO",
|
||||
factory = CpioFileSystemFactory.class,
|
||||
extensions = { "cpio" }
|
||||
)
|
||||
public class CpioFileSystem extends AbstractFileSystem<CpioArchiveEntry> {
|
||||
private static final int MAX_SANE_SYMLINK = 64 * 1024;
|
||||
|
||||
|
||||
@@ -28,7 +28,13 @@ import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||
* If the filename can be recovered from the embedded metadata, it will be used as the
|
||||
* name of the singleton file, otherwise the name "gzip_decompressed" will be used.
|
||||
*/
|
||||
@FileSystemInfo(type = "gzip", description = "GZIP", priority = FileSystemInfo.PRIORITY_LOW, factory = GZipFileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "gzip",
|
||||
description = "GZIP",
|
||||
priority = FileSystemInfo.PRIORITY_LOW,
|
||||
factory = GZipFileSystemFactory.class,
|
||||
extensions = { "gz" }
|
||||
)
|
||||
public class GZipFileSystem extends AbstractSinglePayloadFileSystem {
|
||||
|
||||
public GZipFileSystem(FSRLRoot fsFSRL, ByteProvider payloadProvider, String payloadFilename,
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -44,7 +44,12 @@ import ghidra.util.task.*;
|
||||
* DMG server process seems to leak memory. Currently it is killed every N commands and
|
||||
* restarted.
|
||||
*/
|
||||
@FileSystemInfo(type = "dmg", description = "iOS Disk Image (DMG)", factory = DmgClientFileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "dmg",
|
||||
description = "iOS Disk Image (DMG)",
|
||||
factory = DmgClientFileSystemFactory.class,
|
||||
extensions = { "dmg" }
|
||||
)
|
||||
public class DmgClientFileSystem extends AbstractFileSystem<Object> {
|
||||
|
||||
private File decryptedDmgFile;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -28,8 +28,12 @@ import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.CryptoException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@FileSystemInfo(type = "img3", description = "iOS " +
|
||||
Img3Constants.IMG3_SIGNATURE, factory = Img3FileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "img3",
|
||||
description = "iOS " + Img3Constants.IMG3_SIGNATURE,
|
||||
factory = Img3FileSystemFactory.class,
|
||||
extensions = { "img3" }
|
||||
)
|
||||
public class Img3FileSystem extends AbstractFileSystem<DataTag> {
|
||||
|
||||
private ByteProvider provider;
|
||||
|
||||
@@ -34,7 +34,12 @@ import ghidra.util.task.TaskMonitor;
|
||||
* <p>
|
||||
* This implementation is currently unused (isValid always returns false).
|
||||
*/
|
||||
@FileSystemInfo(type = "ipsw", description = "iOS Firmware (IPSW)", factory = GFileSystemBaseFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "ipsw",
|
||||
description = "iOS Firmware (IPSW)",
|
||||
factory = GFileSystemBaseFactory.class,
|
||||
extensions = { "ipsw" }
|
||||
)
|
||||
public class IpswFileSystem extends GFileSystemBase {
|
||||
|
||||
public IpswFileSystem(String fileSystemName, ByteProvider provider) {
|
||||
|
||||
@@ -46,7 +46,12 @@ import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
|
||||
* WARNING: care is taken to synchronize access to the underlying sevenzip library methods as
|
||||
* some race conditions have been encountered that cause the entire jdk to core dump.
|
||||
*/
|
||||
@FileSystemInfo(type = "7zip", description = "7Zip", factory = SevenZipFileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "7zip",
|
||||
description = "7Zip",
|
||||
factory = SevenZipFileSystemFactory.class,
|
||||
extensions = { "7z", "rpm" }
|
||||
)
|
||||
public class SevenZipFileSystem extends AbstractFileSystem<ISimpleInArchiveItem> {
|
||||
private Map<Integer, String> passwords = new HashMap<>();
|
||||
|
||||
@@ -203,7 +208,7 @@ public class SevenZipFileSystem extends AbstractFileSystem<ISimpleInArchiveItem>
|
||||
// that file will not be readable unless a password is found for it (see
|
||||
// getPasswordForFile()).
|
||||
|
||||
try (CryptoSession cryptoSession = fsService.newCryptoSession()) {
|
||||
try (CryptoSession _ = fsService.newCryptoSession()) {
|
||||
List<ISimpleInArchiveItem> encryptedItems = getEncryptedItemsWithoutPasswords();
|
||||
ISimpleInArchiveItem encryptedItem = null;
|
||||
while ((encryptedItem = getFirstItemWithoutPassword(encryptedItems)) != null &&
|
||||
|
||||
@@ -36,7 +36,13 @@ import ghidra.util.task.TaskMonitor;
|
||||
* The factory supports detecting both compressed (gz) and uncompressed tar files,
|
||||
* and keys both on the tar filename extension as well as the data in the file.
|
||||
*/
|
||||
@FileSystemInfo(type = "tar", description = "TAR", priority = FileSystemInfo.PRIORITY_HIGH, factory = TarFileSystemFactory.class)
|
||||
@FileSystemInfo(
|
||||
type = "tar",
|
||||
description = "TAR",
|
||||
priority = FileSystemInfo.PRIORITY_HIGH,
|
||||
factory = TarFileSystemFactory.class,
|
||||
extensions = { "tar", "tgz" }
|
||||
)
|
||||
public class TarFileSystem extends AbstractFileSystem<TarMetadata> {
|
||||
|
||||
private ByteProvider provider;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -25,7 +25,13 @@ import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
* <p>
|
||||
* 7Zip's features are superior to the native java zip handling (ie. passwords)
|
||||
*/
|
||||
@FileSystemInfo(type = "zip", description = "ZIP", factory = ZipFileSystemFactory.class, priority = FileSystemInfo.PRIORITY_HIGH)
|
||||
@FileSystemInfo(
|
||||
type = "zip",
|
||||
description = "ZIP",
|
||||
factory = ZipFileSystemFactory.class,
|
||||
priority = FileSystemInfo.PRIORITY_HIGH,
|
||||
extensions = { "zip", "jar" }
|
||||
)
|
||||
public class ZipFileSystem extends SevenZipFileSystem {
|
||||
|
||||
public ZipFileSystem(FSRLRoot fsrl, FileSystemService fsService) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import ghidra.util.Msg;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
@@ -56,6 +57,7 @@ public class ExtensionFileFilter implements GhidraFileFilter {
|
||||
|
||||
/**
|
||||
* Creates a file filter that accepts the given file type.
|
||||
* <p>
|
||||
* Example: new ExtensionFileFilter("jpg", "JPEG Images");
|
||||
*
|
||||
* @param extension file extension to match, without leading dot
|
||||
@@ -67,16 +69,38 @@ public class ExtensionFileFilter implements GhidraFileFilter {
|
||||
|
||||
/**
|
||||
* Creates a file filter from the given string array and description.
|
||||
* <p>
|
||||
* Example: new ExtensionFileFilter(String {"gif", "jpg"}, "Gif and JPG Images");
|
||||
*
|
||||
* @param filters array of file name extensions, each without a leading dot
|
||||
* @param description descriptive string of the filter
|
||||
*/
|
||||
public ExtensionFileFilter(String[] filters, String description) {
|
||||
this.extensions = Arrays.asList(filters)
|
||||
.stream()
|
||||
.map(ExtensionFileFilter::clean)
|
||||
.collect(Collectors.toList());
|
||||
this(Arrays.stream(filters), description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file filter from the given string {@link Collection} and description.
|
||||
* <p>
|
||||
* Example: new ExtensionFileFilter(List.of("gif", "jpg"), "Gif and JPG Images");
|
||||
*
|
||||
* @param filters array of file name extensions, each without a leading dot
|
||||
* @param description descriptive string of the filter
|
||||
*/
|
||||
public ExtensionFileFilter(Collection<String> filters, String description) {
|
||||
this(filters.stream(), description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file filter from the given string {@link Stream} and description.
|
||||
* <p>
|
||||
* Example: new ExtensionFileFilter(Stream.of("gif", "jpg"), "Gif and JPG Images");
|
||||
*
|
||||
* @param filters {@link List} of file name extensions, each without a leading dot
|
||||
* @param description descriptive string of the filter
|
||||
*/
|
||||
private ExtensionFileFilter(Stream<String> filters, String description) {
|
||||
this.extensions = filters.map(ExtensionFileFilter::clean).collect(Collectors.toList());
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,11 @@ public class JavaLoader extends AbstractProgramWrapperLoader {
|
||||
return JAVA_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAssociatedFileExtensions() {
|
||||
return List.of("class");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Program program, ImporterSettings settings) throws IOException {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user