GP-4503 - Use GhidraScript askValues in two developer PDB scripts

This commit is contained in:
ghizard 2024-04-09 21:38:58 +00:00
parent c131adc670
commit f58072535e
2 changed files with 118 additions and 48 deletions

View file

@ -20,43 +20,74 @@
import java.io.File;
import java.io.IOException;
import db.Transaction;
import ghidra.app.script.GhidraScript;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.pdb.pdbapplicator.DefaultPdbApplicator;
import ghidra.app.util.pdb.pdbapplicator.PdbApplicatorOptions;
import ghidra.features.base.values.GhidraValuesMap;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.LanguageService;
import ghidra.program.model.lang.Processor;
import ghidra.program.model.mem.Memory;
import ghidra.program.util.DefaultLanguageService;
import ghidra.util.Msg;
import ghidra.util.MessageType;
public class PdbDeveloperApplyDummyScript extends GhidraScript {
private static final String PDB_PROMPT = "Choose a PDB file";
private static final String IMAGE_BASE_PROMPT = "Image Base";
@Override
protected void run() throws Exception {
File pdbFile = askFile("Choose a PDB file", "OK");
if (pdbFile == null) {
Msg.info(this, "Canceled execution due to no input file");
return;
}
if (!pdbFile.exists()) {
String message = pdbFile.getAbsolutePath() + " is not a valid file.";
Msg.info(this, message);
popup(message);
return;
}
LanguageService ls = DefaultLanguageService.getLanguageService();
Processor processor_x86 = Processor.findOrPossiblyCreateProcessor("x86");
Language x86 = ls.getDefaultLanguage(processor_x86);
ProgramDB program = new ProgramDB("Test", x86, x86.getDefaultCompilerSpec(), this);
Address imageBase =
program.getAddressFactory().getDefaultAddressSpace().getAddress(0x400000L);
GhidraValuesMap values = new GhidraValuesMap();
values.defineFile(PDB_PROMPT, null);
values.defineAddress(IMAGE_BASE_PROMPT, imageBase, program);
// Validator for values
values.setValidator((valueMap, status) -> {
File file = valueMap.getFile(PDB_PROMPT);
if (file == null) {
status.setStatusText("PDB file must be selected.", MessageType.ERROR);
return false;
}
if (!file.exists()) {
status.setStatusText(file.getAbsolutePath() + " is not a valid file.",
MessageType.ERROR);
return false;
}
String fileName = file.getAbsolutePath();
if (!fileName.endsWith(".pdb") && !fileName.endsWith(".PDB")) {
status.setStatusText("Expected .pdb file extenstion (got '" + fileName + "').",
MessageType.ERROR);
return false;
}
// We do not need to check the existence of an image base because we provide a default
// value
return true;
});
// asks the script to show a dialog where the user can give values for all the items
// in the ValuesMap.
values = askValues("Enter Values", null, values);
File pdbFile = values.getFile(PDB_PROMPT);
String pdbFileName = pdbFile.getAbsolutePath();
if (!pdbFileName.endsWith(".pdb") && !pdbFileName.endsWith(".PDB")) {
String message = "Aborting: Expected input file to have extension of type .pdb (got '" +
pdbFileName + "').";
Msg.info(this, message);
popup(message);
return;
}
imageBase = values.getAddress(IMAGE_BASE_PROMPT);
MessageLog log = new MessageLog();
@ -64,10 +95,9 @@ public class PdbDeveloperApplyDummyScript extends GhidraScript {
PdbReaderOptions pdbReaderOptions = new PdbReaderOptions();
PdbApplicatorOptions pdbApplicatorOptions = new PdbApplicatorOptions();
LanguageService ls = DefaultLanguageService.getLanguageService();
Processor processor_x86 = Processor.findOrPossiblyCreateProcessor("x86");
Language x86 = ls.getDefaultLanguage(processor_x86);
ProgramDB program = new ProgramDB("Test", x86, x86.getDefaultCompilerSpec(), this);
try (Transaction tx = program.openTransaction("Set Image Base")) {
program.setImageBase(imageBase, true);
}
ProgramManager programManager = state.getTool().getService(ProgramManager.class);
programManager.openProgram(program);

View file

@ -19,39 +19,79 @@
import java.io.*;
import docking.widgets.values.GValuesMap;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
import ghidra.util.Msg;
import ghidra.features.base.values.GhidraValuesMap;
import ghidra.util.*;
public class PdbDeveloperDumpScript extends GhidraScript {
private static final String PDB_PROMPT = "Choose a PDB file";
private static final String OUTPUT_PROMPT = "Choose an output file";
private static boolean validatePdb(GValuesMap valueMap, StatusListener status) {
File file = valueMap.getFile(PDB_PROMPT);
if (file == null) {
status.setStatusText("PDB file must be selected.", MessageType.ERROR);
return false;
}
if (!file.exists()) {
status.setStatusText(file.getAbsolutePath() + " is not a valid file.",
MessageType.ERROR);
return false;
}
String fileName = file.getAbsolutePath();
if (!fileName.endsWith(".pdb") && !fileName.endsWith(".PDB")) {
status.setStatusText("Expected .pdb file extenstion (got '" + fileName + "').",
MessageType.ERROR);
return false;
}
// We do not need to check the existence of an image base because we provide a default
// value
return true;
}
private static boolean validateOutput(GValuesMap valueMap, StatusListener status) {
File file = valueMap.getFile(OUTPUT_PROMPT);
// File will exist, as we supplied a default value
String fileName = file.getAbsolutePath();
if (fileName.endsWith(".pdb") || fileName.endsWith(".PDB")) {
status.setStatusText("Output file may not end with .pdb (got '" + fileName + "').",
MessageType.ERROR);
return false;
}
return true;
}
@Override
protected void run() throws Exception {
File pdbFile = askFile("Choose a PDB file", "OK");
if (pdbFile == null) {
Msg.info(this, "Canceled execution due to no input file");
return;
}
if (!pdbFile.exists()) {
String message = pdbFile.getAbsolutePath() + " is not a valid file.";
Msg.info(this, message);
popup(message);
return;
}
String pdbFileName = pdbFile.getAbsolutePath();
if (!pdbFileName.endsWith(".pdb") && !pdbFileName.endsWith(".PDB")) {
String message = "Aborting: Expected input file to have extension of type .pdb (got '" +
pdbFileName + "').";
Msg.info(this, message);
popup(message);
return;
}
File dumpFile = askFile("Choose an output file", "OK");
if (dumpFile == null) {
Msg.info(this, "Canceled execution due to no output file");
return;
}
GhidraValuesMap values = new GhidraValuesMap();
values.defineFile(PDB_PROMPT, null);
values.setValidator((valueMap, status) -> {
return validatePdb(valueMap, status);
});
values = askValues("Enter Values", null, values);
File pdbFile = values.getFile(PDB_PROMPT);
String pdbFileName = pdbFile.getAbsolutePath();
// creating a default output and asking again; PDB file should retain its current value
// from above
String outputFileName = pdbFileName + ".txt";
values.defineFile(OUTPUT_PROMPT, new File(outputFileName));
values.setValidator((valueMap, status) -> {
if (!validatePdb(valueMap, status)) {
return false;
}
return validateOutput(valueMap, status);
});
values = askValues("Enter Values", null, values);
pdbFile = values.getFile(PDB_PROMPT); // might have changed
pdbFileName = pdbFile.getAbsolutePath(); // might have changed
File dumpFile = values.getFile(OUTPUT_PROMPT);
if (dumpFile.exists()) {
if (!askYesNo("Confirm Overwrite", "Overwrite file: " + dumpFile.getName())) {
Msg.info(this, "Operation canceled");