Merge remote-tracking branch 'origin/GP-3282_ghidragon_analysisflag--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-04-05 07:34:25 -04:00
commit fba01cde18
21 changed files with 215 additions and 152 deletions

View file

@ -95,8 +95,8 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
protected void intoProject(DomainObject obj) { protected void intoProject(DomainObject obj) {
waitForDomainObject(obj); waitForDomainObject(obj);
DomainFolder rootFolder = tool.getProject() DomainFolder rootFolder = tool.getProject()
.getProjectData() .getProjectData()
.getRootFolder(); .getRootFolder();
waitForCondition(() -> { waitForCondition(() -> {
try { try {
rootFolder.createFile(obj.getName(), obj, monitor); rootFolder.createFile(obj.getName(), obj, monitor);
@ -141,7 +141,7 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
try (Transaction tx = program.openTransaction("Assemble")) { try (Transaction tx = program.openTransaction("Assemble")) {
Address entry = addr(program, 0x00400000); Address entry = addr(program, 0x00400000);
program.getMemory() program.getMemory()
.createInitializedBlock(".text", entry, 0x1000, (byte) 0, monitor, false); .createInitializedBlock(".text", entry, 0x1000, (byte) 0, monitor, false);
Assembler asm = Assembler asm =
Assemblers.getAssembler(program.getLanguage(), StackUnwinderTest.NO_16BIT_CALLS); Assemblers.getAssembler(program.getLanguage(), StackUnwinderTest.NO_16BIT_CALLS);
AssemblyBuffer buf = new AssemblyBuffer(asm, entry); AssemblyBuffer buf = new AssemblyBuffer(asm, entry);
@ -193,9 +193,9 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
dis.disassemble(entry, null); dis.disassemble(entry, null);
Function function = program.getFunctionManager() Function function = program.getFunctionManager()
.createFunction("fib", entry, .createFunction("fib", entry,
new AddressSet(entry, entry.add(bytes.length - 1)), new AddressSet(entry, entry.add(bytes.length - 1)),
SourceType.USER_DEFINED); SourceType.USER_DEFINED);
function.updateFunction("__cdecl", function.updateFunction("__cdecl",
new ReturnParameterImpl(UnsignedIntegerDataType.dataType, program), new ReturnParameterImpl(UnsignedIntegerDataType.dataType, program),
@ -231,7 +231,7 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createFibonacciProgramX86_32(); Function function = createFibonacciProgramX86_32();
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
Address entry = function.getEntryPoint(); Address entry = function.getEntryPoint();
programManager.openProgram(program); programManager.openProgram(program);
@ -271,9 +271,9 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
tb.trace.getBreakpointManager() tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr,
Set.of(), Set.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
} }
EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor, EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor,

View file

@ -128,6 +128,20 @@
Analyzers in the Analysis menu. Only those analyzers which support one-shot use and are Analyzers in the Analysis menu. Only those analyzers which support one-shot use and are
applicable to the current program will be available within the One Shot sub-menu.</P> applicable to the current program will be available within the One Shot sub-menu.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<H3><A name="Ask_To_Analyze"></A>Ask To Analyze</H3>
<BLOCKQUOTE>
<P> When opening a program for the first time, you will be asked if you want to analyze the
program. If you respond "Yes", The <A href= "#Auto_Analysis_Option">Auto Analysis Options</A>
dialog will appear, allowing you to begin analyzing the program. If you decide not to
analyze the program, you have the choice of having Ghidra asking you again the next time
you open the program. If you pick the "No" options, Ghidra will continue to ask you to
every time you open the program. If you pick "No (Don't ask again)" Ghidra will never ask you to
analyze the program again, but you can still manually initiate analysis at any time.
If you choose not to have Ghidra ask again, it will set a property in the program called
"Should Ask To Analyze" to false. Since this changes a property in the program, the program
now has changes that need to be saved. </P>
</BLOCKQUOTE>
<H2><A name="Auto_Analysis_Option"></A> <A name= <H2><A name="Auto_Analysis_Option"></A> <A name=
"ghidra_app_plugin_analysis_AutoAnalysisPlugin_AnalysisOptionsDialog"></A> <A name= "ghidra_app_plugin_analysis_AutoAnalysisPlugin_AnalysisOptionsDialog"></A> <A name=
@ -199,9 +213,7 @@
<LI>Delete - Deletes the currently selected named configuration.</LI> <LI>Delete - Deletes the currently selected named configuration.</LI>
</UL> </UL>
</BLOCKQUOTE> </BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H2><A name="Auto_Analyzers"></A>Auto Analyzers</H2> <H2><A name="Auto_Analyzers"></A>Auto Analyzers</H2>
<BLOCKQUOTE> <BLOCKQUOTE>

View file

@ -72,7 +72,8 @@ public class PropertyListMergeManager implements MergeResolver {
* resultProgram and latestProgram start out the same * resultProgram and latestProgram start out the same
*/ */
public PropertyListMergeManager(ProgramMultiUserMergeManager mergeManager, public PropertyListMergeManager(ProgramMultiUserMergeManager mergeManager,
Program resultProgram, Program myProgram, Program originalProgram, Program latestProgram) { Program resultProgram, Program myProgram, Program originalProgram,
Program latestProgram) {
this.mergeManager = mergeManager; this.mergeManager = mergeManager;
this.resultProgram = resultProgram; this.resultProgram = resultProgram;
this.myProgram = myProgram; this.myProgram = myProgram;
@ -142,7 +143,8 @@ public class PropertyListMergeManager implements MergeResolver {
currentMonitor.setProgress(i); currentMonitor.setProgress(i);
String myName = myNames.get(i); String myName = myNames.get(i);
int progress = (int) (((float) (i / myNamesCount)) * 100); int progress = (int) (((float) (i / myNamesCount)) * 100);
mergeManager.updateProgress(progress, "Merging property list for " + myName + "..."); mergeManager.updateProgress(progress,
"Merging property list for " + myName + "...");
boolean isInLatest = latestNames.contains(myName); boolean isInLatest = latestNames.contains(myName);
boolean isInOrig = origNames.contains(myName); boolean isInOrig = origNames.contains(myName);
if (!isInLatest && !isInOrig) { if (!isInLatest && !isInOrig) {
@ -277,11 +279,6 @@ public class PropertyListMergeManager implements MergeResolver {
// value was not modified in my program or it was changed the same as in latest // value was not modified in my program or it was changed the same as in latest
return; return;
} }
if (propertyName.equals(Program.ANALYZED) && Boolean.TRUE.equals(myValue)) {
// If my version sets "Analyzed" to true, then it should result in true.
setValue(resultList, propertyName, myList.getType(propertyName), Boolean.TRUE);
return;
}
if (SystemUtilities.isEqual(resultValue, origValue)) { if (SystemUtilities.isEqual(resultValue, origValue)) {
// no change by latest - use my value // no change by latest - use my value
setValue(resultList, propertyName, myList.getType(propertyName), myValue); setValue(resultList, propertyName, myList.getType(propertyName), myValue);

View file

@ -53,7 +53,7 @@ public class AnalysisBackgroundCommand extends MergeableBackgroundCommand {
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(DomainObject obj, TaskMonitor monitor) {
if (markAsAnalyzed) { if (markAsAnalyzed) {
GhidraProgramUtilities.setAnalyzedFlag((Program) obj, true); GhidraProgramUtilities.markProgramAnalyzed((Program) obj);
} }
mgr.startAnalysis(monitor); mgr.startAnalysis(monitor);
return true; return true;
@ -63,12 +63,12 @@ public class AnalysisBackgroundCommand extends MergeableBackgroundCommand {
@Override @Override
public MergeableBackgroundCommand mergeCommands(MergeableBackgroundCommand command) { public MergeableBackgroundCommand mergeCommands(MergeableBackgroundCommand command) {
SystemUtilities.assertTrue(command instanceof AnalysisBackgroundCommand, SystemUtilities.assertTrue(command instanceof AnalysisBackgroundCommand,
"This code assumes that the " "This code assumes that the " +
+ "two commands are both AnalysisBackgroundCommands and this is not the case."); "two commands are both AnalysisBackgroundCommands and this is not the case.");
AnalysisBackgroundCommand abc = (AnalysisBackgroundCommand) command; AnalysisBackgroundCommand abc = (AnalysisBackgroundCommand) command;
SystemUtilities.assertTrue(mgr == abc.mgr, "This code assumes that the " SystemUtilities.assertTrue(mgr == abc.mgr, "This code assumes that the " +
+ "managers of the two commands are the same instance and this is not the case."); "managers of the two commands are the same instance and this is not the case.");
// once we encounter a markAsAnalyzed value that is true, then leave it on // once we encounter a markAsAnalyzed value that is true, then leave it on
markAsAnalyzed = markAsAnalyzed | abc.markAsAnalyzed; markAsAnalyzed = markAsAnalyzed | abc.markAsAnalyzed;

View file

@ -359,8 +359,8 @@ class AnalysisPanel extends JPanel implements PropertyChangeListener {
} }
File saveFile = getOptionsSaveFile(saveName); File saveFile = getOptionsSaveFile(saveName);
if (saveFile.exists() && OptionDialog.CANCEL_OPTION == OptionDialog if (saveFile.exists() && OptionDialog.CANCEL_OPTION == OptionDialog
.showOptionDialogWithCancelAsDefaultButton(this, "Overwrite Configuration", .showOptionDialogWithCancelAsDefaultButton(this, "Overwrite Configuration",
"Overwrite existing configuration file: " + saveName + " ?", "Overwrite")) { "Overwrite existing configuration file: " + saveName + " ?", "Overwrite")) {
return; return;
} }
FileOptions currentOptions = getCurrentOptionsAsFileOptions(); FileOptions currentOptions = getCurrentOptionsAsFileOptions();
@ -687,7 +687,7 @@ class AnalysisPanel extends JPanel implements PropertyChangeListener {
GenericOptionsComponent.createOptionComponent(childState); GenericOptionsComponent.createOptionComponent(childState);
HelpLocation helpLoc = analysisOptions HelpLocation helpLoc = analysisOptions
.getHelpLocation(analyzerName + Options.DELIMITER_STRING + childOptionName); .getHelpLocation(analyzerName + Options.DELIMITER_STRING + childOptionName);
if (helpLoc != null) { if (helpLoc != null) {
help.registerHelp(comp, helpLoc); help.registerHelp(comp, helpLoc);
} }
@ -775,7 +775,7 @@ class AnalysisPanel extends JPanel implements PropertyChangeListener {
private boolean isAnalyzed() { private boolean isAnalyzed() {
Options options = programs.get(0).getOptions(Program.PROGRAM_INFO); Options options = programs.get(0).getOptions(Program.PROGRAM_INFO);
return options.getBoolean(Program.ANALYZED, false); return options.getBoolean(Program.ANALYZED_OPTION_NAME, false);
} }
private Options[] loadPossibleOptionsChoicesForComboBox() { private Options[] loadPossibleOptionsChoicesForComboBox() {

View file

@ -132,7 +132,7 @@ class AnalyzeAllOpenProgramsTask extends Task {
AutoAnalysisManager manager = AutoAnalysisManager.getAnalysisManager(program); AutoAnalysisManager manager = AutoAnalysisManager.getAnalysisManager(program);
initializeAnalysisOptions(program, prototypeAnalysisOptions, manager); initializeAnalysisOptions(program, prototypeAnalysisOptions, manager);
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
analyzeStrategy.analyzeProgram(program, manager, monitor); analyzeStrategy.analyzeProgram(program, manager, monitor);
} }

View file

@ -1048,8 +1048,8 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
} }
public void registerOptions() { public void registerOptions() {
Options options = program.getOptions(Program.ANALYSIS_PROPERTIES); registerGlobalAnalyisOptions();
registerOptions(options); registerAnalyzerOptions();
} }
public void initializeOptions() { public void initializeOptions() {
@ -1075,7 +1075,18 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
dataTasks.optionsChanged(options); dataTasks.optionsChanged(options);
} }
public void registerOptions(Options options) { private void registerGlobalAnalyisOptions() {
Options options = program.getOptions(Program.PROGRAM_INFO);
options.registerOption(Program.ANALYZED_OPTION_NAME, false, null,
"Indicates if program has ever been analyzed");
options.registerOption(Program.ASK_TO_ANALYZE_OPTION_NAME, true, null,
"Indicates if user should be prompted to analyze an unanalyzed program when opened");
}
public void registerAnalyzerOptions() {
Options options = program.getOptions(Program.ANALYSIS_PROPERTIES);
byteTasks.registerOptions(options); byteTasks.registerOptions(options);
functionTasks.registerOptions(options); functionTasks.registerOptions(options);
functionModifierChangedTasks.registerOptions(options); functionModifierChangedTasks.registerOptions(options);
@ -1106,13 +1117,16 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
Swing.assertSwingThread("Asking to analyze must be on the swing thread!"); Swing.assertSwingThread("Asking to analyze must be on the swing thread!");
if (GhidraProgramUtilities.shouldAskToAnalyze(program)) { if (GhidraProgramUtilities.shouldAskToAnalyze(program)) {
// initialize the analyzed flag to a non-null value to indicate we at least asked String name = HTMLUtilities.escapeHTML(program.getDomainFile().getName());
GhidraProgramUtilities.setAnalyzedFlag(program, false); HelpLocation help = new HelpLocation("AutoAnalysisPlugin", "Ask_To_Analyze");
int result = OptionDialog.showOptionNoCancelDialog(tool.getToolFrame(), "Analyze?",
"<html>" + name + " has not been analyzed. Would you like to analyze it now?",
"Yes", "No", "No (Don't ask again)", OptionDialog.QUESTION_MESSAGE, help);
int answer = OptionDialog.showYesNoDialog(tool.getToolFrame(), "Analyze", if (result == OptionDialog.OPTION_THREE) {
"<html>" + HTMLUtilities.escapeHTML(program.getDomainFile().getName()) + GhidraProgramUtilities.markProgramNotToAskToAnalyze(program);
" has not been analyzed. Would you like to analyze it now?"); }
return answer == OptionDialog.OPTION_ONE; //Analyze return result == OptionDialog.OPTION_ONE; //Analyze
} }
return false; return false;
} }
@ -1271,12 +1285,12 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
testLen = spacer.length() - 5; testLen = spacer.length() - 5;
} }
taskTimesStringBuf taskTimesStringBuf
.append(" " + element + spacer.substring(testLen) + secString + "\n"); .append(" " + element + spacer.substring(testLen) + secString + "\n");
} }
taskTimesStringBuf.append("-----------------------------------------------------\n"); taskTimesStringBuf.append("-----------------------------------------------------\n");
taskTimesStringBuf taskTimesStringBuf
.append(" Total Time " + (int) (totalTaskTime / 1000.00) + " secs\n"); .append(" Total Time " + (int) (totalTaskTime / 1000.00) + " secs\n");
taskTimesStringBuf.append("-----------------------------------------------------\n"); taskTimesStringBuf.append("-----------------------------------------------------\n");
return taskTimesStringBuf.toString(); return taskTimesStringBuf.toString();

View file

@ -188,7 +188,7 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
// check if this is the first time this program is being analyzed. If so, // check if this is the first time this program is being analyzed. If so,
// schedule a callback when it is completed to send a FirstTimeAnalyzedPluginEvent // schedule a callback when it is completed to send a FirstTimeAnalyzedPluginEvent
boolean isAnalyzed = GhidraProgramUtilities.isAnalyzedFlagSet(program); boolean isAnalyzed = GhidraProgramUtilities.isAnalyzed(program);
if (!isAnalyzed) { if (!isAnalyzed) {
analysisMgr.addListener(new FirstTimeAnalyzedCallback()); analysisMgr.addListener(new FirstTimeAnalyzedCallback());
} }

View file

@ -457,7 +457,7 @@ public class GhidraScriptEditorComponentProvider extends ComponentProvider {
// //
// Cancel // Cancel
// //
if (choice == OptionDialog.OPTION_THREE) { if (choice == OptionDialog.CANCEL_OPTION) {
// Cancel // Cancel
return; return;
} }

View file

@ -878,7 +878,7 @@ public class HeadlessAnalyzer {
// Get parent folder to pass to GhidraScript // Get parent folder to pass to GhidraScript
File parentFile = new File(c.getResource(c.getSimpleName() + ".class").toURI()) File parentFile = new File(c.getResource(c.getSimpleName() + ".class").toURI())
.getParentFile(); .getParentFile();
currScript = (GhidraScript) c.getConstructor().newInstance(); currScript = (GhidraScript) c.getConstructor().newInstance();
currScript.setScriptArgs(scriptArgs); currScript.setScriptArgs(scriptArgs);
@ -1019,7 +1019,7 @@ public class HeadlessAnalyzer {
mgr.startAnalysis(TaskMonitor.DUMMY); // kick start mgr.startAnalysis(TaskMonitor.DUMMY); // kick start
Msg.info(this, "REPORT: Analysis succeeded for file: " + fileAbsolutePath); Msg.info(this, "REPORT: Analysis succeeded for file: " + fileAbsolutePath);
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
} }
else { else {
HeadlessTimedTaskMonitor timerMonitor = HeadlessTimedTaskMonitor timerMonitor =
@ -1042,7 +1042,7 @@ public class HeadlessAnalyzer {
timerMonitor.cancel(); timerMonitor.cancel();
Msg.info(this, "REPORT: Analysis succeeded for file: " + fileAbsolutePath); Msg.info(this, "REPORT: Analysis succeeded for file: " + fileAbsolutePath);
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
} }
} }
} }
@ -1559,7 +1559,7 @@ public class HeadlessAnalyzer {
return false; return false;
} }
} }
// Save // Save
for (Loaded<Program> loaded : loadResults) { for (Loaded<Program> loaded : loadResults) {
if (!loaded.getDomainObject().isTemporary()) { if (!loaded.getDomainObject().isTemporary()) {

View file

@ -124,7 +124,6 @@ public abstract class AbstractProgramLoader implements Loader {
MessageLog messageLog, Object consumer, TaskMonitor monitor) throws IOException, MessageLog messageLog, Object consumer, TaskMonitor monitor) throws IOException,
CancelledException, VersionException, LoadException { CancelledException, VersionException, LoadException {
if (!loadSpec.isComplete()) { if (!loadSpec.isComplete()) {
throw new LoadException("Load spec is incomplete"); throw new LoadException("Load spec is incomplete");
} }
@ -369,7 +368,7 @@ public abstract class AbstractProgramLoader implements Loader {
fsrl = fsrl.withMD5(md5); fsrl = fsrl.withMD5(md5);
} }
prog.getOptions(Program.PROGRAM_INFO) prog.getOptions(Program.PROGRAM_INFO)
.setString(ProgramMappingService.PROGRAM_SOURCE_FSRL, fsrl.toString()); .setString(ProgramMappingService.PROGRAM_SOURCE_FSRL, fsrl.toString());
} }
prog.setExecutableMD5(md5); prog.setExecutableMD5(md5);
String sha256 = computeBinarySHA256(provider); String sha256 = computeBinarySHA256(provider);
@ -498,17 +497,19 @@ public abstract class AbstractProgramLoader implements Loader {
boolean anchorSymbols = shouldAnchorSymbols(options); boolean anchorSymbols = shouldAnchorSymbols(options);
List<AddressLabelInfo> labels = lang.getDefaultSymbols(); List<AddressLabelInfo> labels = lang.getDefaultSymbols();
for (AddressLabelInfo info : labels) { for (AddressLabelInfo info : labels) {
createSymbol(program, info.getLabel(), info.getAddress(), info.isEntry(), info.isPrimary(), anchorSymbols); createSymbol(program, info.getLabel(), info.getAddress(), info.isEntry(),
info.isPrimary(), anchorSymbols);
} }
} }
GhidraProgramUtilities.removeAnalyzedFlag(program); GhidraProgramUtilities.resetAnalysisFlags(program);
} }
finally { finally {
program.endTransaction(id, true); program.endTransaction(id, true);
} }
} }
private static void createSymbol(Program program, String labelname, Address address, boolean isEntry, boolean isPrimary, boolean anchorSymbols) { private static void createSymbol(Program program, String labelname, Address address,
boolean isEntry, boolean isPrimary, boolean anchorSymbols) {
SymbolTable symTable = program.getSymbolTable(); SymbolTable symTable = program.getSymbolTable();
Address addr = address; Address addr = address;
Symbol s = symTable.getPrimarySymbol(addr); Symbol s = symTable.getPrimarySymbol(addr);

View file

@ -389,7 +389,7 @@ public class ProgramXmlMgr {
//if instructions were imported, then remove the "needs analyzed" property //if instructions were imported, then remove the "needs analyzed" property
if (options.isInstructions()) { if (options.isInstructions()) {
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
} }
return log; return log;

View file

@ -15,9 +15,8 @@
*/ */
package ghidra.plugins.fsbrowser.tasks; package ghidra.plugins.fsbrowser.tasks;
import java.util.List;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import ghidra.app.services.ProgramManager; import ghidra.app.services.ProgramManager;
import ghidra.formats.gfilesystem.*; import ghidra.formats.gfilesystem.*;
@ -140,7 +139,7 @@ public class GFileSystemLoadKernelTask extends Task {
file.getParentFile().getPath()); file.getParentFile().getPath());
String fileName = ProjectDataUtils.getUniqueName(folder, program.getName()); String fileName = ProjectDataUtils.getUniqueName(folder, program.getName());
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
folder.createFile(fileName, program, monitor); folder.createFile(fileName, program, monitor);

View file

@ -136,10 +136,10 @@ public class ProgramBuilder {
CompilerSpec compilerSpec = compilerSpecID == null ? language.getDefaultCompilerSpec() CompilerSpec compilerSpec = compilerSpecID == null ? language.getDefaultCompilerSpec()
: language.getCompilerSpecByID(new CompilerSpecID(compilerSpecID)); : language.getCompilerSpecByID(new CompilerSpecID(compilerSpecID));
program = new ProgramDB(name, language, compilerSpec, consumer == null ? this : consumer); program = new ProgramDB(name, language, compilerSpec, consumer == null ? this : consumer);
setAnalyzed(true); setAnalyzed();
program.setTemporary(true); // ignore changes program.setTemporary(true); // ignore changes
} }
/** /**
* Construct program builder using a full language object rather than a language id string * Construct program builder using a full language object rather than a language id string
* @param name program name * @param name program name
@ -150,7 +150,7 @@ public class ProgramBuilder {
throws Exception { throws Exception {
CompilerSpec compilerSpec = language.getDefaultCompilerSpec(); CompilerSpec compilerSpec = language.getDefaultCompilerSpec();
program = new ProgramDB(name, language, compilerSpec, this); program = new ProgramDB(name, language, compilerSpec, this);
setAnalyzed(true); setAnalyzed();
program.setTemporary(true); // ignore changes program.setTemporary(true); // ignore changes
} }
@ -281,10 +281,9 @@ public class ProgramBuilder {
/** /**
* This prevents the 'ask to analyze' dialog from showing when called with {@code true} * This prevents the 'ask to analyze' dialog from showing when called with {@code true}
* @param analyzed true to mark the program as analyzed
*/ */
public void setAnalyzed(boolean analyzed) { public void setAnalyzed() {
GhidraProgramUtilities.setAnalyzedFlag(program, analyzed); GhidraProgramUtilities.markProgramAnalyzed(program);
} }
public MemoryBlock createMemory(String name, String address, int size) { public MemoryBlock createMemory(String name, String address, int size) {
@ -321,8 +320,8 @@ public class ProgramBuilder {
return tx(() -> { return tx(() -> {
return program.getMemory() return program.getMemory()
.createInitializedBlock(name, addr(address), size, (byte) 0, TaskMonitor.DUMMY, .createInitializedBlock(name, addr(address), size, (byte) 0, TaskMonitor.DUMMY,
true); true);
}); });
} }

View file

@ -25,8 +25,9 @@ public class GhidraProgramUtilities {
} }
/** /**
* returns the current program, given a tool, if a program is opened; * Returns the current program for the given tool or null if no program is open.
* otherwise returns null. * @param tool the tool get get the current program for
* @return the current program for the given tool or null if no program is open
*/ */
public static Program getCurrentProgram(PluginTool tool) { public static Program getCurrentProgram(PluginTool tool) {
ProgramManager pmService = tool.getService(ProgramManager.class); ProgramManager pmService = tool.getService(ProgramManager.class);
@ -34,11 +35,13 @@ public class GhidraProgramUtilities {
} }
/** /**
* Returns true if the program does not contain the analyzed flag. The assumption is that a * Returns true if the user should be asked to analyze. They will only be asked if the program
* non-null value means that the user has already made a decision about analyzing. * hasn't already been analyzed (analyzed flag property is false or null) or the
* "ask to analyze" flag property is true or null (default is true unless explicitly set to
* false).
* *
* @param program the program to check for the property * @param program the program to check for the property
* @return true if the program does not contain the analyzed flag * @return true if the user should be prompted to analyze the program
*/ */
public static boolean shouldAskToAnalyze(Program program) { public static boolean shouldAskToAnalyze(Program program) {
@ -48,20 +51,27 @@ public class GhidraProgramUtilities {
} }
Options options = program.getOptions(Program.PROGRAM_INFO); Options options = program.getOptions(Program.PROGRAM_INFO);
return !options.contains(Program.ANALYZED); // older programs don't have a "Ask" property, so check analyzed flag
boolean isAnalyzed = options.getBoolean(Program.ANALYZED_OPTION_NAME, false);
if (isAnalyzed) {
return false;
}
return options.getBoolean(Program.ASK_TO_ANALYZE_OPTION_NAME, true);
} }
/** /**
* Removes the analyzed flag from the program properties. * Resets the analysis flags to the program defaults
* With this property removed, the user will be prompted to analyze the * With this reset, the user will be prompted to analyze the
* program the next time it is opened. * program the next time it is opened.
* @param program the program containing the property to be removed * @param program the program whose analysis flags should be reset
*/ */
public static void removeAnalyzedFlag(Program program) { public static void resetAnalysisFlags(Program program) {
int transactionID = program.startTransaction(Program.ANALYZED); int transactionID = program.startTransaction("Reset Analysis Flags");
try { try {
Options options = program.getOptions(Program.PROGRAM_INFO); Options options = program.getOptions(Program.PROGRAM_INFO);
options.removeOption(Program.ANALYZED); options.removeOption(Program.ANALYZED_OPTION_NAME);
options.removeOption(Program.ASK_TO_ANALYZE_OPTION_NAME);
} }
finally { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
@ -69,21 +79,28 @@ public class GhidraProgramUtilities {
} }
/** /**
* Sets the analyzed flag to the specified value. * Marks the program has having been analyzed
* @param program the program to set property * @param program the program to set property
* @param analyzed the analyzed flag
*/ */
public static void setAnalyzedFlag(Program program, boolean analyzed) { public static void markProgramAnalyzed(Program program) {
Options options = program.getOptions(Program.PROGRAM_INFO); Options options = program.getOptions(Program.PROGRAM_INFO);
// once the program is analyzed, register the value, so it won't keep writing it to the database. int transactionID = program.startTransaction("Mark Program Analyzed");
if (analyzed && !options.isRegistered(Program.ANALYZED)) {
options.registerOption(Program.ANALYZED, false, null,
"Indicates if program has been analyzed");
}
int transactionID = program.startTransaction(Program.ANALYZED);
try { try {
options.setBoolean(Program.ANALYZED, analyzed); options.setBoolean(Program.ANALYZED_OPTION_NAME, true);
options.setBoolean(Program.ASK_TO_ANALYZE_OPTION_NAME, false);
}
finally {
program.endTransaction(transactionID, true);
}
}
public static void markProgramNotToAskToAnalyze(Program program) {
Options options = program.getOptions(Program.PROGRAM_INFO);
int transactionID = program.startTransaction("Mark Program To Not Ask To Analyze");
try {
options.setBoolean(Program.ASK_TO_ANALYZE_OPTION_NAME, false);
} }
finally { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
@ -95,17 +112,10 @@ public class GhidraProgramUtilities {
* @param program the program to test to see if it has been analyzed * @param program the program to test to see if it has been analyzed
* @return true if the program has been analyzed at least once. * @return true if the program has been analyzed at least once.
*/ */
public static boolean isAnalyzedFlagSet(Program program) { public static boolean isAnalyzed(Program program) {
Options options = program.getOptions(Program.PROGRAM_INFO); Options options = program.getOptions(Program.PROGRAM_INFO);
// we first have to check if the flag has even been created because checking the flag return options.getBoolean(Program.ANALYZED_OPTION_NAME, false);
// directly causes it to be created if it doesn't exist and we unfortunately use the
// existence of the flag to know whether or not to ask the user if they want to start
// analysis
if (!options.isRegistered(Program.ANALYZED)) {
return false;
}
return options.getBoolean(Program.ANALYZED, false);
} }
} }

View file

@ -256,9 +256,9 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
// By default, create test output within a directory at the same level as the // By default, create test output within a directory at the same level as the
// development repositories // development repositories
outputRoot = Application.getApplicationRootDirectory() outputRoot = Application.getApplicationRootDirectory()
.getParentFile() .getParentFile()
.getParentFile() .getParentFile()
.getCanonicalPath(); .getCanonicalPath();
} }
catch (IOException e) { catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -1562,7 +1562,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
setAnalysisOptions(program.getOptions(Program.ANALYSIS_PROPERTIES)); setAnalysisOptions(program.getOptions(Program.ANALYSIS_PROPERTIES));
GhidraProgramUtilities.setAnalyzedFlag(program, true); GhidraProgramUtilities.markProgramAnalyzed(program);
// Remove all single-byte functions created by Elf importer // Remove all single-byte functions created by Elf importer
// NOTE: This is a known issues with optimized code and symbols marked as ElfSymbol.STT_FUNC // NOTE: This is a known issues with optimized code and symbols marked as ElfSymbol.STT_FUNC
@ -1670,7 +1670,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
RegisterValue thumbMode = new RegisterValue(tReg, BigInteger.ONE); RegisterValue thumbMode = new RegisterValue(tReg, BigInteger.ONE);
try { try {
program.getProgramContext() program.getProgramContext()
.setRegisterValue(functionAddr, functionAddr, thumbMode); .setRegisterValue(functionAddr, functionAddr, thumbMode);
} }
catch (ContextChangeException e) { catch (ContextChangeException e) {
throw new AssertException(e); throw new AssertException(e);
@ -1684,7 +1684,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
RegisterValue thumbMode = new RegisterValue(isaModeReg, BigInteger.ONE); RegisterValue thumbMode = new RegisterValue(isaModeReg, BigInteger.ONE);
try { try {
program.getProgramContext() program.getProgramContext()
.setRegisterValue(functionAddr, functionAddr, thumbMode); .setRegisterValue(functionAddr, functionAddr, thumbMode);
} }
catch (ContextChangeException e) { catch (ContextChangeException e) {
throw new AssertException(e); throw new AssertException(e);
@ -1909,7 +1909,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
if (absoluteGzfFilePath.exists()) { if (absoluteGzfFilePath.exists()) {
program = getGzfProgram(outputDir, gzfCachePath); program = getGzfProgram(outputDir, gzfCachePath);
if (program != null && !MD5Utilities.getMD5Hash(testFile.file) if (program != null && !MD5Utilities.getMD5Hash(testFile.file)
.equals(program.getExecutableMD5())) { .equals(program.getExecutableMD5())) {
// remove obsolete GZF cache file // remove obsolete GZF cache file
env.release(program); env.release(program);
program = null; program = null;
@ -1934,7 +1934,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
} }
else { else {
program = env.getGhidraProject() program = env.getGhidraProject()
.importProgram(testFile.file, language, compilerSpec); .importProgram(testFile.file, language, compilerSpec);
} }
program.addConsumer(this); program.addConsumer(this);
env.getGhidraProject().close(program); env.getGhidraProject().close(program);
@ -1955,8 +1955,8 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
if (!program.getLanguageID().equals(language.getLanguageID()) || if (!program.getLanguageID().equals(language.getLanguageID()) ||
!program.getCompilerSpec() !program.getCompilerSpec()
.getCompilerSpecID() .getCompilerSpecID()
.equals(compilerSpec.getCompilerSpecID())) { .equals(compilerSpec.getCompilerSpecID())) {
throw new IOException((usingCachedGZF ? "Cached " : "") + throw new IOException((usingCachedGZF ? "Cached " : "") +
"Program has incorrect language/compiler spec (" + program.getLanguageID() + "Program has incorrect language/compiler spec (" + program.getLanguageID() +
"/" + program.getCompilerSpec().getCompilerSpecID() + "): " + "/" + program.getCompilerSpec().getCompilerSpecID() + "): " +
@ -2121,7 +2121,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
testFileDigest.append(nameAndAddr); testFileDigest.append(nameAndAddr);
testFileDigest.append(" (GroupInfo @ "); testFileDigest.append(" (GroupInfo @ ");
testFileDigest testFileDigest
.append(testGroup.controlBlock.getInfoStructureAddress().toString(true)); .append(testGroup.controlBlock.getInfoStructureAddress().toString(true));
testFileDigest.append(")"); testFileDigest.append(")");
if (duplicateTests.contains(testGroup.testGroupName)) { if (duplicateTests.contains(testGroup.testGroupName)) {
testFileDigest.append(" *DUPLICATE*"); testFileDigest.append(" *DUPLICATE*");

View file

@ -18,6 +18,7 @@ package ghidra.app.util.pdb;
import ghidra.app.util.bin.format.pdb.PdbParserConstants; import ghidra.app.util.bin.format.pdb.PdbParserConstants;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.GhidraProgramUtilities;
/** /**
* Storage of PDB-related attributes * Storage of PDB-related attributes
@ -47,9 +48,7 @@ public class PdbProgramAttributes {
pdbLoaded = propList.contains(PdbParserConstants.PDB_LOADED) pdbLoaded = propList.contains(PdbParserConstants.PDB_LOADED)
? propList.getBoolean(PdbParserConstants.PDB_LOADED, false) ? propList.getBoolean(PdbParserConstants.PDB_LOADED, false)
: false; : false;
programAnalyzed = propList.contains(Program.ANALYZED) programAnalyzed = GhidraProgramUtilities.isAnalyzed(program);
? propList.getBoolean(Program.ANALYZED, false)
: false;
pdbSignature = propList.contains(PdbParserConstants.PDB_SIGNATURE) pdbSignature = propList.contains(PdbParserConstants.PDB_SIGNATURE)
? propList.getString(PdbParserConstants.PDB_SIGNATURE, null) ? propList.getString(PdbParserConstants.PDB_SIGNATURE, null)
: null; : null;
@ -141,5 +140,4 @@ public class PdbProgramAttributes {
return programAnalyzed; return programAnalyzed;
} }
} }

View file

@ -15,12 +15,11 @@
*/ */
package pdb; package pdb;
import java.util.*;
import java.util.stream.Collectors;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
@ -39,6 +38,7 @@ import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.framework.preferences.Preferences; import ghidra.framework.preferences.Preferences;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.GhidraProgramUtilities;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
@ -75,22 +75,22 @@ public class PdbPlugin extends Plugin {
private void createActions() { private void createActions() {
new ActionBuilder("Load PDB File", this.getName()) new ActionBuilder("Load PDB File", this.getName())
.supportsDefaultToolContext(true) .supportsDefaultToolContext(true)
.withContext(ProgramActionContext.class) .withContext(ProgramActionContext.class)
.validContextWhen(pac -> pac.getProgram() != null && .validContextWhen(pac -> pac.getProgram() != null &&
PdbAnalyzerCommon.canAnalyzeProgram(pac.getProgram())) PdbAnalyzerCommon.canAnalyzeProgram(pac.getProgram()))
.menuPath(ToolConstants.MENU_FILE, "Load PDB File...") .menuPath(ToolConstants.MENU_FILE, "Load PDB File...")
.menuGroup("Import PDB", "3") .menuGroup("Import PDB", "3")
.helpLocation(new HelpLocation(PDB_PLUGIN_HELP_TOPIC, "Load PDB File")) .helpLocation(new HelpLocation(PDB_PLUGIN_HELP_TOPIC, "Load PDB File"))
.onAction(pac -> loadPDB(pac)) .onAction(pac -> loadPDB(pac))
.buildAndInstall(tool); .buildAndInstall(tool);
new ActionBuilder("Symbol Server Config", this.getName()) new ActionBuilder("Symbol Server Config", this.getName())
.menuPath(ToolConstants.MENU_EDIT, "Symbol Server Config") .menuPath(ToolConstants.MENU_EDIT, "Symbol Server Config")
.menuGroup(ToolConstants.TOOL_OPTIONS_MENU_GROUP) .menuGroup(ToolConstants.TOOL_OPTIONS_MENU_GROUP)
.helpLocation(new HelpLocation(PDB_PLUGIN_HELP_TOPIC, "Symbol Server Config")) .helpLocation(new HelpLocation(PDB_PLUGIN_HELP_TOPIC, "Symbol Server Config"))
.onAction(ac -> configPDB()) .onAction(ac -> configPDB())
.buildAndInstall(tool); .buildAndInstall(tool);
} }
private void configPDB() { private void configPDB() {
@ -107,8 +107,7 @@ public class PdbPlugin extends Plugin {
return; return;
} }
boolean analyzed = boolean analyzed = GhidraProgramUtilities.isAnalyzed(program);
program.getOptions(Program.PROGRAM_INFO).getBoolean(Program.ANALYZED, false);
if (analyzed) { if (analyzed) {
int response = int response =
@ -147,8 +146,8 @@ public class PdbPlugin extends Plugin {
LoadPdbTask loadPdbTask = new LoadPdbTask(program, pdbFile, LoadPdbTask loadPdbTask = new LoadPdbTask(program, pdbFile,
loadPdbResults.useMsDiaParser, loadPdbResults.control, dataTypeManagerService); loadPdbResults.useMsDiaParser, loadPdbResults.control, dataTypeManagerService);
TaskBuilder.withTask(loadPdbTask) TaskBuilder.withTask(loadPdbTask)
.setStatusTextAlignment(SwingConstants.LEADING) .setStatusTextAlignment(SwingConstants.LEADING)
.setLaunchDelay(0); .setLaunchDelay(0);
new TaskLauncher(loadPdbTask, null, 0); new TaskLauncher(loadPdbTask, null, 0);
// Check for error messages & exceptions and handle them here // Check for error messages & exceptions and handle them here
@ -282,15 +281,15 @@ public class PdbPlugin extends Plugin {
SymbolServerInstanceCreatorContext symbolServerInstanceCreatorContext) { SymbolServerInstanceCreatorContext symbolServerInstanceCreatorContext) {
SymbolServer temporarySymbolServer = SymbolServer temporarySymbolServer =
symbolServerInstanceCreatorContext.getSymbolServerInstanceCreatorRegistry() symbolServerInstanceCreatorContext.getSymbolServerInstanceCreatorRegistry()
.newSymbolServer(Preferences.getProperty(SYMBOL_STORAGE_DIR_OPTION, "", true), .newSymbolServer(Preferences.getProperty(SYMBOL_STORAGE_DIR_OPTION, "", true),
symbolServerInstanceCreatorContext); symbolServerInstanceCreatorContext);
SymbolStore symbolStore = SymbolStore symbolStore =
(temporarySymbolServer instanceof SymbolStore) ? (SymbolStore) temporarySymbolServer (temporarySymbolServer instanceof SymbolStore) ? (SymbolStore) temporarySymbolServer
: new SameDirSymbolStore(symbolServerInstanceCreatorContext.getRootDir()); : new SameDirSymbolStore(symbolServerInstanceCreatorContext.getRootDir());
List<SymbolServer> symbolServers = List<SymbolServer> symbolServers =
symbolServerInstanceCreatorContext.getSymbolServerInstanceCreatorRegistry() symbolServerInstanceCreatorContext.getSymbolServerInstanceCreatorRegistry()
.createSymbolServersFromPathList(getSymbolSearchPaths(), .createSymbolServersFromPathList(getSymbolSearchPaths(),
symbolServerInstanceCreatorContext); symbolServerInstanceCreatorContext);
return new SymbolServerService(symbolStore, symbolServers); return new SymbolServerService(symbolStore, symbolServers);
} }
@ -307,9 +306,9 @@ public class PdbPlugin extends Plugin {
symbolServerService.getSymbolStore().getName()); symbolServerService.getSymbolStore().getName());
String path = symbolServerService.getSymbolServers() String path = symbolServerService.getSymbolServers()
.stream() .stream()
.map(SymbolServer::getName) .map(SymbolServer::getName)
.collect(Collectors.joining(";")); .collect(Collectors.joining(";"));
Preferences.setProperty(SYMBOL_SEARCH_PATH_OPTION, path); Preferences.setProperty(SYMBOL_SEARCH_PATH_OPTION, path);
} }
else { else {

View file

@ -310,7 +310,7 @@ public class OptionDialog extends DialogComponentProvider {
return ps; return ps;
} }
}; };
panel.add(label, BorderLayout.WEST); panel.add(label, BorderLayout.WEST);
panel.add(textPanel, BorderLayout.CENTER); panel.add(textPanel, BorderLayout.CENTER);
return panel; return panel;
@ -764,7 +764,7 @@ public class OptionDialog extends DialogComponentProvider {
return Swing.runNow(() -> { return Swing.runNow(() -> {
OptionDialog info = OptionDialog info =
new OptionDialog(title, message, option1, option2, PLAIN_MESSAGE, icon, false); new OptionDialog(title, message, option1, option2, PLAIN_MESSAGE, icon, false);
return info.show(); return info.show(parent);
}); });
} }
@ -794,7 +794,39 @@ public class OptionDialog extends DialogComponentProvider {
return Swing.runNow(() -> { return Swing.runNow(() -> {
OptionDialog info = new OptionDialog(title, message, option1, option2, option3, OptionDialog info = new OptionDialog(title, message, option1, option2, option3,
messageType, null, false); messageType, null, false);
return info.show(); return info.show(parent);
});
}
/**
* Static helper method to easily display an three-option dialog with no Cancel button.
* The dialog will remain until the user presses the
* Option1, Option 2, or Option 3 button.
*
* @param parent The parent component of this dialog. If the given component is
* a frame or dialog, then the component will be used to parent the option dialog.
* Otherwise, the parent frame or dialog will be found by traversing up the given
* component's parent hierarchy. Also, null can be used to not parent the dialog at all,
* but this promotes poor dialog behavior
* @param title The String to be placed in the dialogs title area
* @param message The information message to be displayed in the dialog
* @param option1 The text to place on the first option button
* @param option2 The text to place on the second option button
* @param option3 The text to place on the third option button
* @param messageType used to specify a default icon, can be ERROR_MESSAGE,
* INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE)
* @param help The help location for this dialog
* @return The options selected by the user. 1 for the first option and
* 2 for the second option. 0 is returned if the operation is cancelled
*/
public static int showOptionNoCancelDialog(Component parent, String title, String message,
String option1, String option2, String option3, int messageType, HelpLocation help) {
return Swing.runNow(() -> {
OptionDialog info = new OptionDialog(title, message, option1, option2, option3,
messageType, null, false);
info.setHelpLocation(help);
return info.show(parent);
}); });
} }

View file

@ -51,26 +51,28 @@ public interface Program extends DataTypeManagerDomainObject {
public static final String ANALYSIS_PROPERTIES = "Analyzers"; public static final String ANALYSIS_PROPERTIES = "Analyzers";
public static final String DISASSEMBLER_PROPERTIES = "Disassembler"; public static final String DISASSEMBLER_PROPERTIES = "Disassembler";
/** Name of program information property list */ /** Options for storing program info */
public static final String PROGRAM_INFO = "Program Information"; public static final String PROGRAM_INFO = "Program Information";
/** Name of program settings property list */
public static final String PROGRAM_SETTINGS = "Program Settings";
/** Name of boolean analyzed property */ /** Name of boolean analyzed property */
public static final String ANALYZED = "Analyzed"; public static final String ANALYZED_OPTION_NAME = "Analyzed";
/** Name of date created property */ /** Property to control if user should be asked to analyze when unanalyzed program opened */
public static final String ASK_TO_ANALYZE_OPTION_NAME = "Should Ask To Analyze";
/** Date created property */
public static final String DATE_CREATED = "Date Created"; public static final String DATE_CREATED = "Date Created";
/** Name of ghidra version property */ /** Ghidra version property */
public static final String CREATED_WITH_GHIDRA_VERSION = "Created With Ghidra Version"; public static final String CREATED_WITH_GHIDRA_VERSION = "Created With Ghidra Version";
/** Name of ghidra preferred root namespace category property */ /** Ghidra preferred root namespace category property */
public static final String PREFERRED_ROOT_NAMESPACE_CATEGORY_PROPERTY = public static final String PREFERRED_ROOT_NAMESPACE_CATEGORY_PROPERTY =
"Preferred Root Namespace Category"; "Preferred Root Namespace Category";
/** Creation date to ask for analysis */
/** Creation date for analysis */
public static final String ANALYSIS_START_DATE = "2007-Jan-01"; public static final String ANALYSIS_START_DATE = "2007-Jan-01";
/** Format string of analysis date */ /** Format string of analysis date */
public static final String ANALYSIS_START_DATE_FORMAT = "yyyy-MMM-dd"; public static final String ANALYSIS_START_DATE_FORMAT = "yyyy-MMM-dd";
/** A date from January 1, 1970 */ /** A date from January 1, 1970 */
public static final Date JANUARY_1_1970 = new Date(0); public static final Date JANUARY_1_1970 = new Date(0);
/** The maximum number of operands for any assembly language */ /** The maximum number of operands for any assembly language */
public final static int MAX_OPERANDS = 16; public final static int MAX_OPERANDS = 16;

View file

@ -49,7 +49,7 @@ public class PdbScreenShots extends GhidraScreenShotGenerator {
temporaryDir = createTempDirectory("example_pdb"); temporaryDir = createTempDirectory("example_pdb");
tx = program.startTransaction("set analyzed flag"); tx = program.startTransaction("set analyzed flag");
Options proplist = program.getOptions(Program.PROGRAM_INFO); Options proplist = program.getOptions(Program.PROGRAM_INFO);
proplist.setBoolean(Program.ANALYZED, false); proplist.setBoolean(Program.ANALYZED_OPTION_NAME, false);
PdbInfo pdbInfo = PdbInfoDotNet.fromValues("HelloWorld.pdb", 1, new GUID(GUID1_STR)); PdbInfo pdbInfo = PdbInfoDotNet.fromValues("HelloWorld.pdb", 1, new GUID(GUID1_STR));
pdbInfo.serializeToOptions(proplist); pdbInfo.serializeToOptions(proplist);
proplist.setString("Executable Location", proplist.setString("Executable Location",