mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 18:38:11 +08:00
GP-5343: Importer filesystem mirroring
This commit is contained in:
@@ -21,7 +21,6 @@ import java.util.*;
|
||||
import org.jdom.*;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
|
||||
import ghidra.app.util.Option;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
@@ -37,7 +36,6 @@ import ghidra.file.formats.android.xml.AndroidXmlFileSystem;
|
||||
import ghidra.file.formats.zip.ZipFileSystem;
|
||||
import ghidra.formats.gfilesystem.FileSystemService;
|
||||
import ghidra.formats.gfilesystem.GFile;
|
||||
import ghidra.framework.model.Project;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -64,15 +62,15 @@ public class ApkLoader extends DexLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Loaded<Program>> loadProgram(ByteProvider provider, String programName,
|
||||
Project project, String programFolderPath, LoadSpec loadSpec, List<Option> options,
|
||||
MessageLog log, Object consumer, TaskMonitor monitor)
|
||||
protected List<Loaded<Program>> loadProgram(ImporterSettings settings)
|
||||
throws IOException, LoadException, CancelledException {
|
||||
|
||||
MessageLog log = settings.log();
|
||||
TaskMonitor monitor = settings.monitor();
|
||||
boolean success = false;
|
||||
List<Loaded<Program>> allLoadedPrograms = new ArrayList<>();
|
||||
int dexIndex = 1;//DEX file numbering starts at 1
|
||||
try (ZipFileSystem zipFS = openAPK(provider, monitor)) {
|
||||
try (ZipFileSystem zipFS = openAPK(settings.provider(), monitor)) {
|
||||
while (!monitor.isCancelled()) {
|
||||
GFile classesDexFile =
|
||||
zipFS.lookup("/" + "classes" + (dexIndex == 1 ? "" : dexIndex) + ".dex");
|
||||
@@ -81,16 +79,17 @@ public class ApkLoader extends DexLoader {
|
||||
break;
|
||||
}
|
||||
|
||||
monitor.setMessage(
|
||||
"Loading " + classesDexFile.getName() + " from " + programName + "...");
|
||||
monitor.setMessage("Loading " + classesDexFile.getName() + " from " +
|
||||
settings.importName() + "...");
|
||||
|
||||
try (ByteProvider dexProvider =
|
||||
zipFS.getByteProvider(classesDexFile, monitor)) {
|
||||
// defer to the super class (DexLoader) to actually load the DEX file
|
||||
List<Loaded<Program>> loadedPrograms =
|
||||
super.loadProgram(dexProvider, classesDexFile.getName(), project,
|
||||
joinPaths(programFolderPath, programName), loadSpec, options, log,
|
||||
consumer, monitor);
|
||||
ImporterSettings newSettings = new ImporterSettings(dexProvider,
|
||||
classesDexFile.getName(), settings.project(), settings.projectRootPath(),
|
||||
settings.mirrorFsLayout(), settings.loadSpec(), settings.options(),
|
||||
settings.consumer(), settings.log(), settings.monitor());
|
||||
List<Loaded<Program>> loadedPrograms = super.loadProgram(newSettings);
|
||||
|
||||
allLoadedPrograms.addAll(loadedPrograms);
|
||||
}
|
||||
|
||||
@@ -72,21 +72,21 @@ public class DexLoader extends AbstractProgramWrapperLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
Program program, TaskMonitor monitor, MessageLog log) throws IOException {
|
||||
|
||||
public void load(Program program, ImporterSettings settings) throws IOException {
|
||||
MessageLog log = settings.log();
|
||||
TaskMonitor monitor = settings.monitor();
|
||||
monitor.setMessage(getMonitorMessagePrimary());
|
||||
try {
|
||||
Address start = program.getAddressFactory().getDefaultAddressSpace().getAddress(0x0);
|
||||
long length = provider.length();
|
||||
long length = settings.provider().length();
|
||||
|
||||
try (InputStream inputStream = provider.getInputStream(0)) {
|
||||
try (InputStream inputStream = settings.provider().getInputStream(0)) {
|
||||
program.getMemory()
|
||||
.createInitializedBlock(getMemoryBlockName(), start, inputStream, length,
|
||||
monitor, false);
|
||||
}
|
||||
|
||||
BinaryReader reader = new BinaryReader(provider, true);
|
||||
BinaryReader reader = new BinaryReader(settings.provider(), true);
|
||||
DexHeader header = DexHeaderFactory.getDexHeader(reader);
|
||||
|
||||
monitor.setMessage(getMonitorMessageSecondary());
|
||||
@@ -244,7 +244,7 @@ public class DexLoader extends AbstractProgramWrapperLoader {
|
||||
|
||||
@Override
|
||||
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
|
||||
DomainObject domainObject, boolean loadIntoProgram) {
|
||||
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
+19
-21
@@ -26,7 +26,6 @@ import ghidra.file.formats.ios.dyldcache.DyldCacheExtractor;
|
||||
import ghidra.file.formats.ios.dyldcache.DyldCacheFileSystem;
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.model.Project;
|
||||
import ghidra.program.database.mem.FileBytes;
|
||||
import ghidra.program.model.listing.Group;
|
||||
import ghidra.program.model.listing.Program;
|
||||
@@ -77,14 +76,14 @@ public class DyldCacheExtractLoader extends MachoLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
Program program, TaskMonitor monitor, MessageLog log) throws IOException {
|
||||
public void load(Program program, ImporterSettings settings) throws IOException {
|
||||
|
||||
try {
|
||||
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);
|
||||
MachoExtractProgramBuilder.buildProgram(program, provider, fileBytes, false, log,
|
||||
monitor);
|
||||
addOptionalComponents(program, options, log, monitor);
|
||||
FileBytes fileBytes =
|
||||
MemoryBlockUtils.createFileBytes(program, settings.provider(), settings.monitor());
|
||||
MachoExtractProgramBuilder.buildProgram(program, settings.provider(), fileBytes, false,
|
||||
settings.log(), settings.monitor());
|
||||
addOptionalComponents(program, settings.options(), settings.log(), settings.monitor());
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
return;
|
||||
@@ -98,20 +97,20 @@ public class DyldCacheExtractLoader extends MachoLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadProgramInto(ByteProvider provider, LoadSpec loadSpec,
|
||||
List<Option> options, MessageLog log, Program program, TaskMonitor monitor)
|
||||
protected void loadProgramInto(Program program, ImporterSettings settings)
|
||||
throws IOException, LoadException, CancelledException {
|
||||
FSRL fsrl = provider.getFSRL();
|
||||
FSRL fsrl = settings.provider().getFSRL();
|
||||
Group[] children = program.getListing().getDefaultRootModule().getChildren();
|
||||
if (Arrays.stream(children).anyMatch(e -> e.getName().contains(fsrl.getPath()))) {
|
||||
log.appendMsg("%s has already been added".formatted(fsrl.getPath()));
|
||||
settings.log().appendMsg("%s has already been added".formatted(fsrl.getPath()));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);
|
||||
MachoExtractProgramBuilder.buildProgram(program, provider, fileBytes, true, log,
|
||||
monitor);
|
||||
addOptionalComponents(program, options, log, monitor);
|
||||
FileBytes fileBytes =
|
||||
MemoryBlockUtils.createFileBytes(program, settings.provider(), settings.monitor());
|
||||
MachoExtractProgramBuilder.buildProgram(program, settings.provider(), fileBytes, true,
|
||||
settings.log(), settings.monitor());
|
||||
addOptionalComponents(program, settings.options(), settings.log(), settings.monitor());
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
return;
|
||||
@@ -141,7 +140,7 @@ public class DyldCacheExtractLoader extends MachoLoader {
|
||||
|
||||
@Override
|
||||
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
|
||||
DomainObject domainObject, boolean loadIntoProgram) {
|
||||
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
|
||||
List<Option> list = new ArrayList<>();
|
||||
list.add(new Option(LIBOBJC_OPTION_NAME, !loadIntoProgram && LIBOBJC_OPTION_DEFAULT,
|
||||
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-libobjc"));
|
||||
@@ -185,19 +184,18 @@ public class DyldCacheExtractLoader extends MachoLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isLoadLibraries(List<Option> options) {
|
||||
protected boolean isLoadLibraries(ImporterSettings settings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||
protected boolean shouldSearchAllPaths(Program program, ImporterSettings settings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms, Project project,
|
||||
LoadSpec loadSpec, List<Option> options, MessageLog messageLog, TaskMonitor monitor)
|
||||
throws CancelledException, IOException {
|
||||
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms,
|
||||
ImporterSettings settings) throws CancelledException, IOException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
+17
-21
@@ -21,16 +21,13 @@ import java.util.*;
|
||||
import ghidra.app.util.MemoryBlockUtils;
|
||||
import ghidra.app.util.Option;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.file.formats.ios.fileset.MachoFileSetExtractor;
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.model.Project;
|
||||
import ghidra.program.database.mem.FileBytes;
|
||||
import ghidra.program.model.listing.Group;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* A {@link Loader} for Mach-O file set entries extracted by Ghidra from a Mach-O file set
|
||||
@@ -52,13 +49,13 @@ public class MachoFileSetExtractLoader extends MachoLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
Program program, TaskMonitor monitor, MessageLog log) throws IOException {
|
||||
public void load(Program program, ImporterSettings settings) throws IOException {
|
||||
|
||||
try {
|
||||
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);
|
||||
MachoExtractProgramBuilder.buildProgram(program, provider, fileBytes, false, log,
|
||||
monitor);
|
||||
FileBytes fileBytes =
|
||||
MemoryBlockUtils.createFileBytes(program, settings.provider(), settings.monitor());
|
||||
MachoExtractProgramBuilder.buildProgram(program, settings.provider(), fileBytes, false,
|
||||
settings.log(), settings.monitor());
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
return;
|
||||
@@ -72,19 +69,19 @@ public class MachoFileSetExtractLoader extends MachoLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadProgramInto(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
MessageLog log, Program program, TaskMonitor monitor)
|
||||
protected void loadProgramInto(Program program, ImporterSettings settings)
|
||||
throws IOException, LoadException, CancelledException {
|
||||
FSRL fsrl = provider.getFSRL();
|
||||
FSRL fsrl = settings.provider().getFSRL();
|
||||
Group[] children = program.getListing().getDefaultRootModule().getChildren();
|
||||
if (Arrays.stream(children).anyMatch(e -> e.getName().contains(fsrl.getPath()))) {
|
||||
log.appendMsg("%s has already been added".formatted(fsrl.getPath()));
|
||||
settings.log().appendMsg("%s has already been added".formatted(fsrl.getPath()));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);
|
||||
MachoExtractProgramBuilder.buildProgram(program, provider, fileBytes, true, log,
|
||||
monitor);
|
||||
FileBytes fileBytes =
|
||||
MemoryBlockUtils.createFileBytes(program, settings.provider(), settings.monitor());
|
||||
MachoExtractProgramBuilder.buildProgram(program, settings.provider(), fileBytes, true,
|
||||
settings.log(), settings.monitor());
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
return;
|
||||
@@ -114,24 +111,23 @@ public class MachoFileSetExtractLoader extends MachoLoader {
|
||||
|
||||
@Override
|
||||
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
|
||||
DomainObject domainObject, boolean loadIntoProgram) {
|
||||
DomainObject domainObject, boolean loadIntoProgram, boolean mirrorFsLayout) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isLoadLibraries(List<Option> options) {
|
||||
protected boolean isLoadLibraries(ImporterSettings settings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||
protected boolean shouldSearchAllPaths(Program program, ImporterSettings settings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms, Project project,
|
||||
LoadSpec loadSpec, List<Option> options, MessageLog messageLog, TaskMonitor monitor)
|
||||
throws CancelledException, IOException {
|
||||
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms,
|
||||
ImporterSettings settings) throws CancelledException, IOException {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
+7
-8
@@ -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.
|
||||
@@ -106,12 +106,11 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("hiding")
|
||||
protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
Program program, TaskMonitor monitor, MessageLog log)
|
||||
protected void load(Program program, ImporterSettings settings)
|
||||
throws CancelledException, IOException {
|
||||
this.log = log;
|
||||
parseDumpFile(provider, program, options, loadSpec, monitor);
|
||||
this.log = settings.log();
|
||||
parseDumpFile(settings.provider(), program, settings.options(), settings.loadSpec(),
|
||||
settings.monitor());
|
||||
}
|
||||
|
||||
private void parseDumpFile(ByteProvider provider, Program program, List<Option> options,
|
||||
@@ -300,7 +299,7 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
|
||||
|
||||
@Override
|
||||
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
|
||||
DomainObject domainObject, boolean isLoadIntoProgram) {
|
||||
DomainObject domainObject, boolean isLoadIntoProgram, boolean mirrorFsLayout) {
|
||||
List<Option> options = new ArrayList<>();
|
||||
try {
|
||||
int size = loadSpec.getLanguageCompilerSpec().getLanguage().getDefaultSpace().getSize();
|
||||
|
||||
+9
-1
@@ -22,6 +22,7 @@ import ghidra.app.util.*;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.*;
|
||||
import ghidra.app.util.opinion.Loader.ImporterSettings;
|
||||
import ghidra.file.formats.dump.DumpFile;
|
||||
import ghidra.file.formats.dump.DumpFileReader;
|
||||
import ghidra.framework.store.LockException;
|
||||
@@ -79,6 +80,7 @@ public class Apport extends DumpFile {
|
||||
private void createBlocksFromElf(LoadSpec loadSpec, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
|
||||
Object consumer = new Object();
|
||||
try (
|
||||
DecodedProvider provider =
|
||||
new DecodedProvider(this, reader.getByteProvider(), monitor)) {
|
||||
@@ -86,7 +88,13 @@ public class Apport extends DumpFile {
|
||||
Option base = new Option(ElfLoaderOptionsFactory.IMAGE_BASE_OPTION_NAME,
|
||||
Long.toHexString(header.getMemoryInfo(0).getBaseAddress()));
|
||||
options.add(base);
|
||||
elfLoader.load(provider, loadSpec, options, program, monitor, log);
|
||||
program.addConsumer(consumer);
|
||||
ImporterSettings settings = new ImporterSettings(provider, program.getName(), null,
|
||||
null, false, loadSpec, options, consumer, log, monitor);
|
||||
elfLoader.load(program, settings);
|
||||
}
|
||||
finally {
|
||||
program.release(consumer);
|
||||
}
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
|
||||
+6
-1
@@ -62,12 +62,17 @@ public class DumpPeShim extends PeLoader {
|
||||
return;
|
||||
}
|
||||
program.setEffectiveImageBase(minAddress);
|
||||
Object consumer = new Object();
|
||||
try {
|
||||
load(provider, loadSpec, options, program, monitor, log);
|
||||
program.addConsumer(consumer);
|
||||
ImporterSettings settings = new ImporterSettings(provider, program.getName(), null,
|
||||
null, false, loadSpec, options, consumer, log, monitor);
|
||||
load(program, settings);
|
||||
monitor.checkCancelled();
|
||||
}
|
||||
finally {
|
||||
program.setEffectiveImageBase(null);
|
||||
program.release(consumer);
|
||||
}
|
||||
|
||||
shiftModule();
|
||||
|
||||
Reference in New Issue
Block a user