GP-1983 refactor setting of program properties when imported

This commit is contained in:
dev747368 2022-04-29 20:48:57 +00:00
parent ccbf264116
commit 27db91b7a0
5 changed files with 52 additions and 64 deletions

View File

@ -15,11 +15,12 @@
*/
package ghidra.app.util.opinion;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.io.InputStream;
import ghidra.app.plugin.processors.generic.MemoryBlockDefinition;
import ghidra.app.util.Option;
import ghidra.app.util.OptionUtils;
@ -29,6 +30,7 @@ import ghidra.formats.gfilesystem.FSRL;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.LockException;
import ghidra.plugin.importer.ProgramMappingService;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.*;
@ -284,14 +286,7 @@ public abstract class AbstractProgramLoader implements Loader {
prog.setEventsEnabled(false);
int id = prog.startTransaction("Set program properties");
try {
prog.setExecutablePath(provider.getAbsolutePath());
if (executableFormatName != null) {
prog.setExecutableFormat(executableFormatName);
}
String md5 = computeBinaryMD5(provider);
prog.setExecutableMD5(md5);
String sha256 = computeBinarySHA256(provider);
prog.setExecutableSHA256(sha256);
setProgramProperties(prog, provider, executableFormatName);
if (shouldSetImageBase(prog, imageBase)) {
try {
@ -311,6 +306,37 @@ public abstract class AbstractProgramLoader implements Loader {
return prog;
}
/**
* Sets a program's Executable Path, Executable Format, MD5, SHA256, and FSRL properties.
* <p>
*
* @param prog {@link Program} (with active transaction)
* @param provider {@link ByteProvider} that the program was created from
* @param executableFormatName executable format string
* @throws IOException if error reading from ByteProvider
*/
public static void setProgramProperties(Program prog, ByteProvider provider,
String executableFormatName) throws IOException {
prog.setExecutablePath(provider.getAbsolutePath());
if (executableFormatName != null) {
prog.setExecutableFormat(executableFormatName);
}
FSRL fsrl = provider.getFSRL();
String md5 = (fsrl != null && fsrl.getMD5() != null)
? fsrl.getMD5()
: computeBinaryMD5(provider);
if (fsrl != null) {
if (fsrl.getMD5() == null) {
fsrl = fsrl.withMD5(md5);
}
prog.getOptions(Program.PROGRAM_INFO)
.setString(ProgramMappingService.PROGRAM_SOURCE_FSRL, fsrl.toString());
}
prog.setExecutableMD5(md5);
String sha256 = computeBinarySHA256(provider);
prog.setExecutableSHA256(sha256);
}
private String getProgramNameFromSourceData(ByteProvider provider, String domainFileName) {
FSRL fsrl = provider.getFSRL();
if (fsrl != null) {
@ -529,13 +555,13 @@ public abstract class AbstractProgramLoader implements Loader {
}
}
private String computeBinaryMD5(ByteProvider provider) throws IOException {
private static String computeBinaryMD5(ByteProvider provider) throws IOException {
try (InputStream in = provider.getInputStream(0)) {
return MD5Utilities.getMD5Hash(in);
}
}
private String computeBinarySHA256(ByteProvider provider) throws IOException {
private static String computeBinarySHA256(ByteProvider provider) throws IOException {
try (InputStream in = provider.getInputStream(0)) {
return HashUtilities.getHash(HashUtilities.SHA256_ALGORITHM, in);
}

View File

@ -34,7 +34,6 @@ import ghidra.formats.gfilesystem.*;
import ghidra.framework.main.AppInfo;
import ghidra.framework.main.FrontEndTool;
import ghidra.framework.model.*;
import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool;
import ghidra.plugins.importer.batch.BatchImportDialog;
import ghidra.program.model.lang.LanguageCompilerSpecPair;
@ -86,41 +85,6 @@ public class ImporterUtilities {
return CollectionUtils.asList(pairs);
}
/**
* Ensure that a {@link Program}'s metadata includes its import origin.
*
* @param program imported {@link Program} to modify
* @param fsrl {@link FSRL} of the import source.
* @param monitor {@link TaskMonitor} to use when accessing filesystem stuff.
* @throws CancelledException if user cancels
* @throws IOException if IO error
*/
public static void setProgramProperties(Program program, FSRL fsrl, TaskMonitor monitor)
throws CancelledException, IOException {
Objects.requireNonNull(monitor);
int id = program.startTransaction("setImportProperties");
try {
fsrl = fsService.getFullyQualifiedFSRL(fsrl, monitor);
Options propertyList = program.getOptions(Program.PROGRAM_INFO);
if (!propertyList.contains(ProgramMappingService.PROGRAM_SOURCE_FSRL)) {
propertyList.setString(ProgramMappingService.PROGRAM_SOURCE_FSRL, fsrl.toString());
}
String md5 = program.getExecutableMD5();
if ((md5 == null || md5.isEmpty()) && fsrl.getMD5() != null) {
program.setExecutableMD5(fsrl.getMD5());
}
}
finally {
program.endTransaction(id, true);
}
if (program.canSave()) {
program.save("Added import properties", monitor);
}
}
/**
* Displays the appropriate import dialog for the specified {@link FSRL file}.
* <p>
@ -431,13 +395,12 @@ public class ImporterUtilities {
if (importedObject instanceof Program) {
Program program = (Program) importedObject;
setProgramProperties(program, fsrl, monitor);
ProgramMappingService.createAssociation(fsrl, program);
if (programManager != null) {
int openState =
firstProgram ? ProgramManager.OPEN_CURRENT : ProgramManager.OPEN_VISIBLE;
int openState = firstProgram
? ProgramManager.OPEN_CURRENT
: ProgramManager.OPEN_VISIBLE;
programManager.openProgram(program, openState);
}
importedFilesSet.add(program.getDomainFile());

View File

@ -15,16 +15,16 @@
*/
package ghidra.plugins.fsbrowser.tasks;
import java.io.IOException;
import java.util.List;
import java.io.IOException;
import ghidra.app.services.ProgramManager;
import ghidra.formats.gfilesystem.*;
import ghidra.framework.main.AppInfo;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.model.ProjectDataUtils;
import ghidra.framework.plugintool.Plugin;
import ghidra.plugin.importer.ImporterUtilities;
import ghidra.plugin.importer.ProgramMappingService;
import ghidra.program.model.lang.LanguageService;
import ghidra.program.model.listing.Program;
@ -141,7 +141,6 @@ public class GFileSystemLoadKernelTask extends Task {
String fileName = ProjectDataUtils.getUniqueName(folder, program.getName());
GhidraProgramUtilities.setAnalyzedFlag(program, true);
ImporterUtilities.setProgramProperties(program, file.getFSRL(), monitor);
folder.createFile(fileName, program, monitor);

View File

@ -15,9 +15,10 @@
*/
package ghidra.plugins.importer.tasks;
import java.io.IOException;
import java.util.List;
import java.io.IOException;
import org.apache.commons.io.FilenameUtils;
import generic.stl.Pair;
@ -29,7 +30,6 @@ import ghidra.app.util.opinion.LoadSpec;
import ghidra.formats.gfilesystem.*;
import ghidra.framework.model.*;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.plugin.importer.ImporterUtilities;
import ghidra.plugin.importer.ProgramMappingService;
import ghidra.plugins.importer.batch.*;
import ghidra.plugins.importer.batch.BatchGroup.BatchLoadConfig;
@ -199,9 +199,7 @@ public class ImportBatchTask extends Task {
}
/*
* sets the imported program's source properties, creates fsrl associations,
* updates task statistics, opens the imported program (if allowed), and
* calls the ImportManagerServiceListener callback.
* creates fsrl associations, updates task statistics, opens the imported program (if allowed)
*/
private void processImportResults(List<DomainObject> importedObjects, BatchLoadConfig appInfo,
TaskMonitor monitor) throws CancelledException, IOException {
@ -209,7 +207,6 @@ public class ImportBatchTask extends Task {
for (DomainObject obj : importedObjects) {
if (obj instanceof Program) {
Program program = (Program) obj;
ImporterUtilities.setProgramProperties(program, appInfo.getFSRL(), monitor);
if (programManager != null && totalObjsImported < MAX_PROGRAMS_TO_OPEN) {
programManager.openProgram(program,

View File

@ -15,9 +15,10 @@
*/
package ghidra.file.formats.ios.prelink;
import java.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import org.apache.commons.collections4.BidiMap;
import org.jdom.JDOMException;
@ -194,8 +195,10 @@ public class PrelinkFileSystem extends GFileSystemBase implements GFileSystemPro
new ByteProviderWrapper(provider, offset, provider.length() - offset);
MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes, new MessageLog(),
monitor);
program.setExecutableFormat(MachoLoader.MACH_O_NAME);
program.setExecutablePath(file.getPath());
AbstractProgramLoader.setProgramProperties(program, providerWrapper,
MachoLoader.MACH_O_NAME);
program.setExecutablePath(file.getPath()); // override the value set by AbstractProgramLoader.setProgramProperties
if (file.equals(systemKextFile)) {
processSystemKext(languageService, program, monitor);