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; package ghidra.app.util.opinion;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.io.IOException;
import java.io.InputStream;
import ghidra.app.plugin.processors.generic.MemoryBlockDefinition; import ghidra.app.plugin.processors.generic.MemoryBlockDefinition;
import ghidra.app.util.Option; import ghidra.app.util.Option;
import ghidra.app.util.OptionUtils; import ghidra.app.util.OptionUtils;
@ -29,6 +30,7 @@ import ghidra.formats.gfilesystem.FSRL;
import ghidra.framework.model.DomainFolder; import ghidra.framework.model.DomainFolder;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.store.LockException; import ghidra.framework.store.LockException;
import ghidra.plugin.importer.ProgramMappingService;
import ghidra.program.database.ProgramDB; import ghidra.program.database.ProgramDB;
import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
@ -284,14 +286,7 @@ public abstract class AbstractProgramLoader implements Loader {
prog.setEventsEnabled(false); prog.setEventsEnabled(false);
int id = prog.startTransaction("Set program properties"); int id = prog.startTransaction("Set program properties");
try { try {
prog.setExecutablePath(provider.getAbsolutePath()); setProgramProperties(prog, provider, executableFormatName);
if (executableFormatName != null) {
prog.setExecutableFormat(executableFormatName);
}
String md5 = computeBinaryMD5(provider);
prog.setExecutableMD5(md5);
String sha256 = computeBinarySHA256(provider);
prog.setExecutableSHA256(sha256);
if (shouldSetImageBase(prog, imageBase)) { if (shouldSetImageBase(prog, imageBase)) {
try { try {
@ -311,6 +306,37 @@ public abstract class AbstractProgramLoader implements Loader {
return prog; 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) { private String getProgramNameFromSourceData(ByteProvider provider, String domainFileName) {
FSRL fsrl = provider.getFSRL(); FSRL fsrl = provider.getFSRL();
if (fsrl != null) { 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)) { try (InputStream in = provider.getInputStream(0)) {
return MD5Utilities.getMD5Hash(in); 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)) { try (InputStream in = provider.getInputStream(0)) {
return HashUtilities.getHash(HashUtilities.SHA256_ALGORITHM, in); 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.AppInfo;
import ghidra.framework.main.FrontEndTool; import ghidra.framework.main.FrontEndTool;
import ghidra.framework.model.*; import ghidra.framework.model.*;
import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.plugins.importer.batch.BatchImportDialog; import ghidra.plugins.importer.batch.BatchImportDialog;
import ghidra.program.model.lang.LanguageCompilerSpecPair; import ghidra.program.model.lang.LanguageCompilerSpecPair;
@ -86,41 +85,6 @@ public class ImporterUtilities {
return CollectionUtils.asList(pairs); 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}. * Displays the appropriate import dialog for the specified {@link FSRL file}.
* <p> * <p>
@ -431,13 +395,12 @@ public class ImporterUtilities {
if (importedObject instanceof Program) { if (importedObject instanceof Program) {
Program program = (Program) importedObject; Program program = (Program) importedObject;
setProgramProperties(program, fsrl, monitor);
ProgramMappingService.createAssociation(fsrl, program); ProgramMappingService.createAssociation(fsrl, program);
if (programManager != null) { if (programManager != null) {
int openState = int openState = firstProgram
firstProgram ? ProgramManager.OPEN_CURRENT : ProgramManager.OPEN_VISIBLE; ? ProgramManager.OPEN_CURRENT
: ProgramManager.OPEN_VISIBLE;
programManager.openProgram(program, openState); programManager.openProgram(program, openState);
} }
importedFilesSet.add(program.getDomainFile()); importedFilesSet.add(program.getDomainFile());

View File

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

View File

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

View File

@ -15,9 +15,10 @@
*/ */
package ghidra.file.formats.ios.prelink; package ghidra.file.formats.ios.prelink;
import java.util.*;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.*;
import org.apache.commons.collections4.BidiMap; import org.apache.commons.collections4.BidiMap;
import org.jdom.JDOMException; import org.jdom.JDOMException;
@ -194,8 +195,10 @@ public class PrelinkFileSystem extends GFileSystemBase implements GFileSystemPro
new ByteProviderWrapper(provider, offset, provider.length() - offset); new ByteProviderWrapper(provider, offset, provider.length() - offset);
MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes, new MessageLog(), MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes, new MessageLog(),
monitor); 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)) { if (file.equals(systemKextFile)) {
processSystemKext(languageService, program, monitor); processSystemKext(languageService, program, monitor);