mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GT-3076 PDB Do not automatically include path: check-in and certify
This commit is contained in:
parent
6da0d9340d
commit
99a916e1ba
6 changed files with 162 additions and 99 deletions
|
@ -46,6 +46,16 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
private String symbolsRepositoryPath = SYMBOLPATH_OPTION_DEFAULT_VALUE;
|
||||
|
||||
//==============================================================================================
|
||||
// Include the PE-Header-Specified PDB path for searching for appropriate PDB file.
|
||||
private static final String OPTION_NAME_INCLUDE_PE_PDB_PATH =
|
||||
"Unsafe: Include PE PDB Path in PDB Search";
|
||||
private static final String OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH =
|
||||
"If checked, specifically searching for PDB in PE-Header-Specified Location.";
|
||||
|
||||
private boolean includePeSpecifiedPdbPath = false;
|
||||
|
||||
//==============================================================================================
|
||||
public PdbAnalyzer() {
|
||||
super(NAME, DESCRIPTION, AnalyzerType.BYTE_ANALYZER);
|
||||
setDefaultEnablement(true);
|
||||
|
@ -60,7 +70,7 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
|||
return true;
|
||||
}
|
||||
|
||||
File pdb = lookForPdb(program, log);
|
||||
File pdb = lookForPdb(program, includePeSpecifiedPdbPath, log);
|
||||
|
||||
if (pdb == null) {
|
||||
return false;
|
||||
|
@ -74,13 +84,13 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
|||
// object existence indicates missing PDB has already been reported
|
||||
}
|
||||
|
||||
File lookForPdb(Program program, MessageLog log) {
|
||||
File lookForPdb(Program program, boolean includePeSpecifiedPdbPath, MessageLog log) {
|
||||
String message = "";
|
||||
File pdb;
|
||||
|
||||
try {
|
||||
|
||||
pdb = PdbParser.findPDB(program, symbolsRepositoryPath);
|
||||
pdb = PdbParser.findPDB(program, includePeSpecifiedPdbPath, symbolsRepositoryPath);
|
||||
|
||||
if (pdb == null) {
|
||||
|
||||
|
@ -182,6 +192,9 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
|||
options.registerOption(SYMBOLPATH_OPTION_NAME, SYMBOLPATH_OPTION_DEFAULT_VALUE, null,
|
||||
SYMBOLPATH_OPTION_DESCRIPTION);
|
||||
}
|
||||
|
||||
options.registerOption(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath, null,
|
||||
OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -192,6 +205,9 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
Preferences.setProperty(PdbParser.PDB_STORAGE_PROPERTY, symbolPath);
|
||||
Preferences.store();
|
||||
|
||||
includePeSpecifiedPdbPath =
|
||||
options.getBoolean(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath);
|
||||
}
|
||||
|
||||
public void setSymbolsRepositoryPath(String symbolPath) {
|
||||
|
|
|
@ -73,7 +73,7 @@ class ApplyFunctions {
|
|||
cmd.applyTo(program, monitor);
|
||||
}
|
||||
|
||||
pdbParser.createSymbol(address, name, true, log, monitor);
|
||||
pdbParser.createSymbol(address, name, true, log);
|
||||
|
||||
Function function = listing.getFunctionAt(address);
|
||||
if (function == null) {
|
||||
|
|
|
@ -117,7 +117,7 @@ class ApplySymbols {
|
|||
|
||||
// Don't create label for Data since a separate symbol should also exist with a better name
|
||||
if (!"Data".equals(tag) &&
|
||||
!pdbParser.createSymbol(address, name, forcePrimary, log, monitor)) {
|
||||
!pdbParser.createSymbol(address, name, forcePrimary, log)) {
|
||||
log.appendMsg("Unable to create symbol " + name + " at " + address);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ class ApplySymbols {
|
|||
if (name.startsWith(MS_STRING_PREFIX)) {
|
||||
// TODO: Should this be handled by the demangler instead of here?
|
||||
boolean isUnicode = isUnicode(name);
|
||||
pdbParser.createString(isUnicode, address, log, monitor);
|
||||
pdbParser.createString(isUnicode, address, log);
|
||||
}
|
||||
////////////
|
||||
// Commented out the following for now, because it appears to be doing things it
|
||||
|
@ -171,13 +171,13 @@ class ApplySymbols {
|
|||
// }
|
||||
// }
|
||||
else if (isGuidLabel(name, address, program)) {
|
||||
pdbParser.createData(address, new GuidDataType(), log, monitor);
|
||||
pdbParser.createData(address, new GuidDataType(), log);
|
||||
}
|
||||
else if (tag.equals("Data")) {
|
||||
if (datatype.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
pdbParser.createData(address, datatype, log, monitor);
|
||||
pdbParser.createData(address, datatype, log);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ public class PdbParser {
|
|||
/**
|
||||
* Parse the PDB file, enforcing pre-conditions and post-conditions.
|
||||
*
|
||||
* @throws IOException if there was a file I/O issue
|
||||
* @throws IOException If an I/O error occurs
|
||||
* @throws PdbException if there was a problem during processing
|
||||
*/
|
||||
public void parse() throws IOException, PdbException {
|
||||
|
@ -241,6 +241,12 @@ public class PdbParser {
|
|||
// NTDDK has not been parsed
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the set of command line arguments for the pdb.exe process
|
||||
* @param noValidation do not ask for GUID/Signature, Age validation
|
||||
* @return the array of arguments for the command line
|
||||
* @throws PdbException if the appropriate set of GUID/Signature, Age values is not available
|
||||
*/
|
||||
private String[] getCommandLineArray(boolean noValidation) throws PdbException {
|
||||
|
||||
File pdbExeFile;
|
||||
|
@ -273,7 +279,7 @@ public class PdbParser {
|
|||
private void completeDefferedTypeParsing(ApplyDataTypes applyDataTypes,
|
||||
ApplyTypeDefs applyTypeDefs, MessageLog log) throws CancelledException {
|
||||
|
||||
defineClasses(monitor, log);
|
||||
defineClasses(log);
|
||||
|
||||
if (applyDataTypes != null) {
|
||||
applyDataTypes.buildDataTypes(monitor);
|
||||
|
@ -304,9 +310,6 @@ public class PdbParser {
|
|||
|
||||
checkPdbLoaded();
|
||||
|
||||
if (monitor == null) {
|
||||
monitor = TaskMonitor.DUMMY;
|
||||
}
|
||||
errHandler.setMessageLog(log);
|
||||
Msg.debug(this, "Found PDB for " + program.getName());
|
||||
try {
|
||||
|
@ -423,7 +426,7 @@ public class PdbParser {
|
|||
}
|
||||
}
|
||||
|
||||
private void defineClasses(TaskMonitor monitor, MessageLog log) throws CancelledException {
|
||||
private void defineClasses(MessageLog log) throws CancelledException {
|
||||
// create namespace and classes in an ordered fashion use tree map
|
||||
monitor.initialize(namespaceMap.size());
|
||||
for (SymbolPath path : namespaceMap.keySet()) {
|
||||
|
@ -500,8 +503,8 @@ public class PdbParser {
|
|||
* age match the program's GUID/Signature and age.
|
||||
*
|
||||
* @param skipValidation true if we should skip checking that GUID/Signature and age match
|
||||
* @throws PdbException
|
||||
* @throws IOException
|
||||
* @throws PdbException If issue running the pdb.exe process
|
||||
* @throws IOException If an I/O error occurs
|
||||
*/
|
||||
private void processPdbContents(boolean skipValidation) throws PdbException, IOException {
|
||||
InputStream in = null;
|
||||
|
@ -555,8 +558,8 @@ public class PdbParser {
|
|||
* Check to see if GUID and age in XML file matches GUID/Signature and age of binary
|
||||
*
|
||||
* @param in InputStream for XML file
|
||||
* @throws IOException
|
||||
* @throws PdbException
|
||||
* @throws IOException If an I/O error occurs
|
||||
* @throws PdbException If error parsing the PDB.XML data
|
||||
*/
|
||||
private void verifyPdbSignature(InputStream in) throws IOException, PdbException {
|
||||
|
||||
|
@ -648,7 +651,7 @@ public class PdbParser {
|
|||
* Translate signature to GUID form. A signature is usually 8 characters long. A GUID
|
||||
* has 32 characters and its subparts are separated by '-' characters.
|
||||
*
|
||||
* @param pdbSignature
|
||||
* @param pdbSignature signature for conversion
|
||||
* @return reformatted String
|
||||
*/
|
||||
private String reformatSignatureToGuidForm(String pdbSignature) {
|
||||
|
@ -740,13 +743,12 @@ public class PdbParser {
|
|||
dataMgr);
|
||||
}
|
||||
|
||||
void createString(boolean isUnicode, Address address, MessageLog log, TaskMonitor monitor) {
|
||||
void createString(boolean isUnicode, Address address, MessageLog log) {
|
||||
DataType dataType = isUnicode ? new UnicodeDataType() : new StringDataType();
|
||||
createData(address, dataType, log, monitor);
|
||||
createData(address, dataType, log);
|
||||
}
|
||||
|
||||
void createData(Address address, String datatype, MessageLog log, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
void createData(Address address, String datatype, MessageLog log) throws CancelledException {
|
||||
WrappedDataType wrappedDt = getDataTypeParser().findDataType(datatype);
|
||||
if (wrappedDt == null) {
|
||||
log.appendMsg("Error: Failed to resolve datatype " + datatype + " at " + address);
|
||||
|
@ -755,11 +757,11 @@ public class PdbParser {
|
|||
Msg.debug(this, "Did not apply zero length array data " + datatype + " at " + address);
|
||||
}
|
||||
else {
|
||||
createData(address, wrappedDt.getDataType(), log, monitor);
|
||||
createData(address, wrappedDt.getDataType(), log);
|
||||
}
|
||||
}
|
||||
|
||||
void createData(Address address, DataType dataType, MessageLog log, TaskMonitor monitor) {
|
||||
void createData(Address address, DataType dataType, MessageLog log) {
|
||||
DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(program.getMemory(), address);
|
||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer);
|
||||
if (dti == null) {
|
||||
|
@ -767,12 +769,12 @@ public class PdbParser {
|
|||
"Error: Failed to apply datatype " + dataType.getName() + " at " + address);
|
||||
}
|
||||
else {
|
||||
createData(address, dti.getDataType(), dti.getLength(), log, monitor);
|
||||
createData(address, dti.getDataType(), dti.getLength(), log);
|
||||
}
|
||||
}
|
||||
|
||||
private void createData(Address address, DataType dataType, int dataTypeLength, MessageLog log,
|
||||
TaskMonitor monitor) {
|
||||
private void createData(Address address, DataType dataType, int dataTypeLength,
|
||||
MessageLog log) {
|
||||
|
||||
// Ensure that we do not clear previously established code and data
|
||||
Data existingData = null;
|
||||
|
@ -924,7 +926,7 @@ public class PdbParser {
|
|||
}
|
||||
|
||||
boolean createSymbol(Address address, String symbolPathString, boolean forcePrimary,
|
||||
MessageLog log, TaskMonitor monitor) throws CancelledException {
|
||||
MessageLog log) {
|
||||
|
||||
try {
|
||||
Namespace namespace = program.getGlobalNamespace();
|
||||
|
@ -992,7 +994,7 @@ public class PdbParser {
|
|||
* Get the category path associated with the namespace qualified data type name
|
||||
* @param namespaceQualifiedDataTypeName data type name
|
||||
* @param addPdbRoot true if PDB root category should be used, otherwise it will be omitted
|
||||
* @return
|
||||
* @return the category path
|
||||
*/
|
||||
CategoryPath getCategory(String namespaceQualifiedDataTypeName, boolean addPdbRoot) {
|
||||
String[] names = namespaceQualifiedDataTypeName.split(Namespace.NAMESPACE_DELIMITER);
|
||||
|
@ -1047,12 +1049,12 @@ public class PdbParser {
|
|||
* @throws PdbException if there was a problem with the PDB attributes
|
||||
*/
|
||||
public static File findPDB(Program program) throws PdbException {
|
||||
return findPDB(getPdbAttributes(program), null, null);
|
||||
return findPDB(getPdbAttributes(program), false, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the PDB has previously been loaded for the specified program.
|
||||
* @param program
|
||||
* @param program program for which to find a matching PDB
|
||||
* @return true if PDB has already been loaded
|
||||
*/
|
||||
public static boolean isAlreadyLoaded(Program program) {
|
||||
|
@ -1064,12 +1066,15 @@ public class PdbParser {
|
|||
* location where symbols are stored.
|
||||
*
|
||||
* @param program program for which to find a matching PDB
|
||||
* @param includePeSpecifiedPdbPath to also check the PE-header-specified PDB path
|
||||
* @param symbolsRepositoryPath location where downloaded symbols are stored
|
||||
* @return matching PDB for program, or null
|
||||
* @throws PdbException if there was a problem with the PDB attributes
|
||||
*/
|
||||
public static File findPDB(Program program, String symbolsRepositoryPath) throws PdbException {
|
||||
return findPDB(getPdbAttributes(program), symbolsRepositoryPath, null);
|
||||
public static File findPDB(Program program, boolean includePeSpecifiedPdbPath,
|
||||
String symbolsRepositoryPath) throws PdbException {
|
||||
return findPDB(getPdbAttributes(program), includePeSpecifiedPdbPath, symbolsRepositoryPath,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1077,13 +1082,15 @@ public class PdbParser {
|
|||
* type of file to search from (.pdb or .pdb.xml).
|
||||
*
|
||||
* @param pdbAttributes PDB attributes associated with the program
|
||||
* @param includePeSpecifiedPdbPath to also check the PE-header-specified PDB path
|
||||
* @param symbolsRepositoryPath location of the local symbols repository (can be null)
|
||||
* @param fileType type of file to search for (can be null)
|
||||
* @return matching PDB file (or null, if not found)
|
||||
* @throws PdbException if there was a problem with the PDB attributes
|
||||
*/
|
||||
public static File findPDB(PdbProgramAttributes pdbAttributes, String symbolsRepositoryPath,
|
||||
PdbFileType fileType) throws PdbException {
|
||||
public static File findPDB(PdbProgramAttributes pdbAttributes,
|
||||
boolean includePeSpecifiedPdbPath, String symbolsRepositoryPath, PdbFileType fileType)
|
||||
throws PdbException {
|
||||
|
||||
// Store potential names of PDB files and potential locations of those files,
|
||||
// so that all possible combinations can be searched.
|
||||
|
@ -1103,7 +1110,7 @@ public class PdbParser {
|
|||
}
|
||||
|
||||
return checkPathsForPdb(symbolsRepositoryPath, guidSubdirPaths, potentialPdbNames, fileType,
|
||||
pdbAttributes);
|
||||
pdbAttributes, includePeSpecifiedPdbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1130,16 +1137,16 @@ public class PdbParser {
|
|||
* @param fileType file type to search for (can be null)
|
||||
* @param pdbAttributes PDB attributes associated with the program
|
||||
* @return matching PDB file, if found (else null)
|
||||
* @throws PdbException
|
||||
*/
|
||||
private static File checkPathsForPdb(String symbolsRepositoryPath, Set<String> guidSubdirPaths,
|
||||
List<String> potentialPdbNames, PdbFileType fileType,
|
||||
PdbProgramAttributes pdbAttributes) {
|
||||
PdbProgramAttributes pdbAttributes, boolean includePeSpecifiedPdbPath) {
|
||||
|
||||
File foundPdb = null;
|
||||
Set<File> symbolsRepoPaths =
|
||||
getSymbolsRepositoryPaths(symbolsRepositoryPath, guidSubdirPaths);
|
||||
Set<File> predefinedPaths = getPredefinedPaths(guidSubdirPaths, pdbAttributes);
|
||||
Set<File> predefinedPaths =
|
||||
getPredefinedPaths(guidSubdirPaths, pdbAttributes, includePeSpecifiedPdbPath);
|
||||
boolean fileTypeSpecified = (fileType != null), checkForXml;
|
||||
|
||||
// If the file type is specified, look for that type of file only.
|
||||
|
@ -1216,11 +1223,11 @@ public class PdbParser {
|
|||
|
||||
// Get list of "paths we know about" to search for PDBs
|
||||
private static Set<File> getPredefinedPaths(Set<String> guidSubdirPaths,
|
||||
PdbProgramAttributes pdbAttributes) {
|
||||
PdbProgramAttributes pdbAttributes, boolean includePeSpecifiedPdbPath) {
|
||||
|
||||
Set<File> predefinedPaths = new LinkedHashSet<>();
|
||||
|
||||
getPathsFromAttributes(pdbAttributes, predefinedPaths);
|
||||
getPathsFromAttributes(pdbAttributes, includePeSpecifiedPdbPath, predefinedPaths);
|
||||
getWindowsPaths(guidSubdirPaths, predefinedPaths);
|
||||
getLibraryPaths(guidSubdirPaths, predefinedPaths);
|
||||
|
||||
|
@ -1265,12 +1272,12 @@ public class PdbParser {
|
|||
}
|
||||
|
||||
private static void getPathsFromAttributes(PdbProgramAttributes pdbAttributes,
|
||||
Set<File> predefinedPaths) {
|
||||
boolean includePeSpecifiedPdbPath, Set<File> predefinedPaths) {
|
||||
if (pdbAttributes != null) {
|
||||
|
||||
String currentPath = pdbAttributes.getPdbFile();
|
||||
|
||||
if (currentPath != null) {
|
||||
if (currentPath != null && includePeSpecifiedPdbPath) {
|
||||
File parentDir = new File(currentPath).getParentFile();
|
||||
|
||||
if (parentDir != null && parentDir.exists()) {
|
||||
|
@ -1294,10 +1301,10 @@ public class PdbParser {
|
|||
* Returns the first PDB-type file found. Assumes list of potentialPdbDirs is in the order
|
||||
* in which the directories should be searched.
|
||||
*
|
||||
* @param potentialPdbDirs
|
||||
* @param potentialPdbNames
|
||||
* @param potentialPdbDirs potential PDB directories
|
||||
* @param potentialPdbNames potential PDB names
|
||||
* @param findXML - if true, only searches for the .pdb.xml version of the .pdb file
|
||||
* @return
|
||||
* @return the first file found
|
||||
*/
|
||||
private static File checkForPDBorXML(Set<File> potentialPdbDirs, List<String> potentialPdbNames,
|
||||
boolean findXML) {
|
||||
|
|
|
@ -19,16 +19,17 @@ import java.io.*;
|
|||
import java.net.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.ProgramActionContext;
|
||||
import ghidra.app.context.ProgramContextAction;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.script.AskDialog;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.app.util.bin.format.pdb.*;
|
||||
import ghidra.app.util.bin.format.pdb.PdbParser.PdbFileType;
|
||||
|
@ -79,7 +80,8 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
// Store last-selected value(s) for askXxx methods
|
||||
private static String serverUrl = null;
|
||||
private static File localDir = null;
|
||||
static PdbFileType fileType = PdbFileType.PDB;
|
||||
private PdbFileType fileType = PdbFileType.PDB;
|
||||
private boolean includePePdbPath = false;
|
||||
|
||||
enum RetrieveFileType {
|
||||
PDB, XML, CAB
|
||||
|
@ -98,6 +100,14 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
urlProperties.setProperty("User-Agent", "Microsoft-Symbol-Server/6.3.9600.17298");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PdbFileType}
|
||||
* @param fileType the {@link PdbFileType}
|
||||
*/
|
||||
public void setPdbFileType(PdbFileType fileType) {
|
||||
this.fileType = fileType;
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
ProgramContextAction downloadPdbAction =
|
||||
new ProgramContextAction("Download_PDB_File", this.getName()) {
|
||||
|
@ -172,9 +182,9 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
*
|
||||
* @param program program for which to retrieve the PDB file
|
||||
* @return the retrieved PDB file (could be in .pdb or .xml form)
|
||||
* @throws CancelledException
|
||||
* @throws IOException
|
||||
* @throws PdbException
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws IOException if an I/O issue occurred
|
||||
* @throws PdbException if there was a problem with the PDB attributes
|
||||
*/
|
||||
private PdbFileAndStatus getPdbFile(Program program)
|
||||
throws CancelledException, IOException, PdbException {
|
||||
|
@ -185,6 +195,9 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
// 1. Ask if user wants .pdb or .pdb.xml file
|
||||
fileType = askForFileExtension();
|
||||
|
||||
// 1.5 Ask if should search PE-specified PDB path.
|
||||
includePePdbPath = askIncludePeHeaderPdbPath();
|
||||
|
||||
String symbolEnv = System.getenv(symbolServerEnvVar);
|
||||
if (symbolEnv != null) {
|
||||
parseSymbolEnv(symbolEnv);
|
||||
|
@ -194,8 +207,8 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
localDir = askForLocalStorageLocation();
|
||||
|
||||
// 3. See if PDB can be found locally
|
||||
File pdbFile =
|
||||
PdbParser.findPDB(pdbAttributes, localDir.getAbsolutePath(), fileType);
|
||||
File pdbFile = PdbParser.findPDB(pdbAttributes, includePePdbPath,
|
||||
localDir.getAbsolutePath(), fileType);
|
||||
|
||||
// 4. If not found locally, ask if it should be retrieved
|
||||
if (pdbFile != null && pdbFile.getName().endsWith(fileType.toString())) {
|
||||
|
@ -280,22 +293,35 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
}
|
||||
|
||||
private PdbFileType askForFileExtension() throws CancelledException {
|
||||
|
||||
//@formatter:off
|
||||
AskDialog<PdbFileType> fileTypeDialog = new AskDialog<>(
|
||||
int choice = OptionDialog.showOptionDialog(
|
||||
null,
|
||||
"pdb or pdb.xml",
|
||||
"Download a .pdb or .pdb.xml file? (.pdb.xml can be processed on non-Windows systems)",
|
||||
AskDialog.STRING,
|
||||
Arrays.asList(PdbFileType.PDB, PdbFileType.XML),
|
||||
fileType);
|
||||
"PDB",
|
||||
"XML");
|
||||
//@formatter:on
|
||||
|
||||
if (fileTypeDialog.isCanceled()) {
|
||||
if (choice == OptionDialog.CANCEL_OPTION) {
|
||||
throw new CancelledException();
|
||||
}
|
||||
return (choice == OptionDialog.OPTION_ONE) ? PdbFileType.PDB : PdbFileType.XML;
|
||||
}
|
||||
|
||||
return fileTypeDialog.getChoiceValue();
|
||||
private boolean askIncludePeHeaderPdbPath() throws CancelledException {
|
||||
//@formatter:off
|
||||
int choice = OptionDialog.showOptionDialog(
|
||||
null,
|
||||
"PE-specified PDB Path",
|
||||
"Unsafe: Include PE-specified PDB Path in search for existing PDB",
|
||||
"Yes",
|
||||
"No");
|
||||
//@formatter:on
|
||||
|
||||
if (choice == OptionDialog.CANCEL_OPTION) {
|
||||
throw new CancelledException();
|
||||
}
|
||||
return (choice == OptionDialog.OPTION_ONE);
|
||||
}
|
||||
|
||||
String askForSymbolServerUrl() throws CancelledException {
|
||||
|
@ -384,7 +410,7 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
|
||||
fileChooser.setTitle("Select Location to Save Retrieved File");
|
||||
fileChooser.setApproveButtonText("OK");
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooser.DIRECTORIES_ONLY);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
|
||||
chosenDir[0] = fileChooser.getSelectedFile();
|
||||
|
||||
if (chosenDir[0] != null) {
|
||||
|
@ -420,7 +446,8 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
* @param fileUrl URL from which to download the file
|
||||
* @param fileDestination location at which to save the downloaded file
|
||||
* @return whether download/save succeeded
|
||||
* @throws IOException
|
||||
* @throws IOException if an I/O issue occurred
|
||||
* @throws PdbException if issue with PKI certificate
|
||||
*/
|
||||
boolean retrieveFile(String fileUrl, File fileDestination) throws IOException, PdbException {
|
||||
return retrieveFile(fileUrl, fileDestination, null);
|
||||
|
@ -433,7 +460,8 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
* @param fileDestination location at which to save the downloaded file
|
||||
* @param retrieveProperties optional HTTP request header values to be included (may be null)
|
||||
* @return whether download/save succeeded
|
||||
* @throws IOException
|
||||
* @throws IOException if an I/O issue occurred
|
||||
* @throws PdbException if issue with PKI certificate
|
||||
*/
|
||||
boolean retrieveFile(String fileUrl, File fileDestination, Properties retrieveProperties)
|
||||
throws IOException, PdbException {
|
||||
|
@ -534,8 +562,8 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
* @param cabFile file to expand/uncompress
|
||||
* @param targetFilename file to save uncompressed *.pdb to
|
||||
* @return the file that was uncompressed
|
||||
* @throws PdbException
|
||||
* @throws IOException
|
||||
* @throws PdbException if failure with cabinet extraction
|
||||
* @throws IOException if issue starting the {@link ProcessBuilder}
|
||||
*/
|
||||
File uncompressCabFile(File cabFile, String targetFilename) throws PdbException, IOException {
|
||||
|
||||
|
@ -608,6 +636,18 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a file, then move it to its final destination. URL for download is created by
|
||||
* combining downloadURL and PDB file attributes. Final move destination is also determined
|
||||
* by the PDB file attributes.
|
||||
*
|
||||
* @param pdbAttributes PDB attributes (GUID, age, potential PDB locations, etc.)
|
||||
* @param downloadUrl Root URL to search for the PDB
|
||||
* @param saveToLocation Final root directory to save the file
|
||||
* @return the downloaded and moved file
|
||||
* @throws IOException if an I/O issue occurred
|
||||
* @throws PdbException if issue with PKI certificate or cabinet extraction
|
||||
*/
|
||||
private File attemptToDownloadPdb(PdbProgramAttributes pdbAttributes, String downloadUrl,
|
||||
File saveToLocation) throws PdbException, IOException {
|
||||
|
||||
|
@ -647,11 +687,10 @@ public class PdbSymbolServerPlugin extends Plugin {
|
|||
* @param downloadUrl Root URL to search for the PDB
|
||||
* @param tempSaveDirectory Temporary local directory to save downloaded file (which will be moved)
|
||||
* @param finalSaveDirectory Final root directory to save the file
|
||||
* @param retrieveXml Whether to retrieve a .pdb.xml file or not
|
||||
* @param retrieveCabFile Whether to retrieve a .cab file or not
|
||||
* @return the downloaded and moved file
|
||||
* @throws IOException
|
||||
* @throws PdbException
|
||||
* @param retrieveFileType the {@link RetrieveFileType}
|
||||
* @return the downloaded and moved file
|
||||
* @throws IOException if an I/O issue occurred
|
||||
* @throws PdbException if issue with PKI certificate or cabinet extraction
|
||||
*/
|
||||
File downloadExtractAndMoveFile(PdbProgramAttributes pdbAttributes, String downloadUrl,
|
||||
File tempSaveDirectory, File finalSaveDirectory, RetrieveFileType retrieveFileType)
|
||||
|
|
|
@ -338,7 +338,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
createdFiles = null;
|
||||
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.NONE);
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
|
||||
// Should not find anything since repo is set to an invalid path
|
||||
assertNull(pdb);
|
||||
|
@ -361,7 +361,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, symbolsFolder.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -386,7 +386,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, symbolsFolder.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -414,7 +414,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, symbolsFolder.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdb.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -439,7 +439,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -467,7 +467,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, symbolsFolder.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -491,7 +491,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
// Should not find anything since repo is set to an invalid path
|
||||
assertNull(pdb);
|
||||
|
@ -512,7 +512,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, symbolsFolder.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -540,7 +540,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, symbolsFolder.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -565,7 +565,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -593,7 +593,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbFile.getParent());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -617,7 +617,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
|
||||
// Should not find anything since repo is set to an invalid path
|
||||
assertNull(pdb);
|
||||
|
@ -638,7 +638,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbFile.getParent());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -666,7 +666,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbFile.getParent());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -691,7 +691,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlFile.getParent());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlFile.getParent());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -722,7 +722,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -748,7 +748,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbFile.getParent());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -777,7 +777,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -805,7 +805,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -832,7 +832,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbFile.getParent());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -860,7 +860,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -886,7 +886,8 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
try {
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbFile.getParentFile().getAbsolutePath());
|
||||
File pdb =
|
||||
PdbParser.findPDB(testProgram, false, pdbFile.getParentFile().getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
|
||||
|
@ -914,7 +915,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -941,7 +942,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.NONE, PdbXmlLocation.NONE);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
assertNull(pdb);
|
||||
|
||||
}
|
||||
|
@ -961,7 +962,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.NONE, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, defaultSymbolsRepoPath);
|
||||
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
|
||||
assertNull(pdb);
|
||||
|
||||
}
|
||||
|
@ -981,7 +982,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
createdFiles = createFiles(PdbLocation.NONE, PdbXmlLocation.OWN_DIR);
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
assertNotNull(pdb);
|
||||
|
||||
|
@ -1061,7 +1062,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
buildPdbXml();
|
||||
|
||||
File pdb = PdbParser.findPDB(testProgram, pdbXmlDir.getAbsolutePath());
|
||||
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
|
||||
|
||||
AutoAnalysisManager mgr = AutoAnalysisManager.getAnalysisManager(testProgram);
|
||||
DataTypeManagerService dataTypeManagerService = mgr.getDataTypeManagerService();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue