mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-22 01:32:08 +08:00
Merge remote-tracking branch 'origin/GP-4735_dev747368_pdb_trusted_symbolserver--SQUASHED'
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -19,13 +19,9 @@
|
||||
//The ~/symbols directory should already exist and be initialized as a symbol
|
||||
//storage location.
|
||||
//@category PDB
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import ghidra.app.plugin.core.analysis.PdbAnalyzer;
|
||||
import ghidra.app.plugin.core.analysis.PdbUniversalAnalyzer;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import pdb.PdbPlugin;
|
||||
import pdb.symbolserver.*;
|
||||
@@ -38,16 +34,11 @@ public class PdbSymbolServerExamplePrescript extends GhidraScript {
|
||||
File symDir = new File(homeDir, "symbols");
|
||||
LocalSymbolStore localSymbolStore = new LocalSymbolStore(symDir);
|
||||
HttpSymbolServer msSymbolServer =
|
||||
new HttpSymbolServer(URI.create("https://msdl.microsoft.com/download/symbols/"));
|
||||
HttpSymbolServer.createTrusted("https://msdl.microsoft.com/download/symbols/");
|
||||
SymbolServerService symbolServerService =
|
||||
new SymbolServerService(localSymbolStore, List.of(msSymbolServer));
|
||||
|
||||
PdbPlugin.saveSymbolServerServiceConfig(symbolServerService);
|
||||
|
||||
// You only need to enable the "allow remote" option on the specific
|
||||
// analyzer you are using
|
||||
PdbUniversalAnalyzer.setAllowRemoteOption(currentProgram, true);
|
||||
PdbAnalyzer.setAllowRemoteOption(currentProgram, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.AccessMode;
|
||||
import java.util.List;
|
||||
|
||||
@@ -44,8 +43,8 @@ public class GetMSDownloadLinkScript extends GhidraScript {
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
SymbolServerService symbolService =
|
||||
new SymbolServerService(new SameDirSymbolStore(null), List.of(
|
||||
new HttpSymbolServer(URI.create(MS_PUBLIC_SYMBOL_SERVER_URL))));
|
||||
new SymbolServerService(new SameDirSymbolStore(null),
|
||||
List.of(HttpSymbolServer.createTrusted(MS_PUBLIC_SYMBOL_SERVER_URL)));
|
||||
|
||||
File f = askFile("File To Scan", "Select");
|
||||
if (f == null) {
|
||||
@@ -63,9 +62,7 @@ public class GetMSDownloadLinkScript extends GhidraScript {
|
||||
", sizeOfImage: " + Integer.toHexString(sizeOfImage));
|
||||
SymbolFileInfo symbolFileInfo = SymbolFileInfo.fromValues(f.getName().toLowerCase(),
|
||||
Integer.toHexString(timeDateStamp), sizeOfImage);
|
||||
List<SymbolFileLocation> findResults =
|
||||
symbolService.find(symbolFileInfo, FindOption.of(FindOption.ALLOW_REMOTE),
|
||||
monitor);
|
||||
List<SymbolFileLocation> findResults = symbolService.find(symbolFileInfo, monitor);
|
||||
if (findResults.isEmpty()) {
|
||||
println("Not found on " + MS_PUBLIC_SYMBOL_SERVER_URL);
|
||||
return;
|
||||
|
||||
+15
-15
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -42,7 +42,7 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
||||
|
||||
private static final String ERROR_TITLE = "Error in PDB Analyzer";
|
||||
|
||||
private boolean searchRemoteLocations = false;
|
||||
private boolean searchUntrustedLocations = false;
|
||||
|
||||
// only try once per transaction due to extensive error logging which may get duplicated
|
||||
private long lastTransactionId = -1;
|
||||
@@ -85,7 +85,7 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
||||
return false;
|
||||
}
|
||||
|
||||
File pdbFile = PdbAnalyzerCommon.findPdb(this, program, searchRemoteLocations, monitor);
|
||||
File pdbFile = PdbAnalyzerCommon.findPdb(this, program, searchUntrustedLocations, monitor);
|
||||
if (pdbFile == null) {
|
||||
// warnings have already been logged
|
||||
return false;
|
||||
@@ -138,15 +138,15 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
||||
@Override
|
||||
public void registerOptions(Options options, Program program) {
|
||||
|
||||
options.registerOption(PdbAnalyzerCommon.OPTION_NAME_SEARCH_REMOTE_LOCATIONS,
|
||||
searchRemoteLocations, null,
|
||||
PdbAnalyzerCommon.OPTION_DESCRIPTION_SEARCH_REMOTE_LOCATIONS);
|
||||
options.registerOption(PdbAnalyzerCommon.OPTION_NAME_SEARCH_UNTRUSTED_LOCATIONS,
|
||||
searchUntrustedLocations, null,
|
||||
PdbAnalyzerCommon.OPTION_DESCRIPTION_SEARCH_UNTRUSTED_LOCATIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optionsChanged(Options options, Program program) {
|
||||
searchRemoteLocations = options.getBoolean(
|
||||
PdbAnalyzerCommon.OPTION_NAME_SEARCH_REMOTE_LOCATIONS, searchRemoteLocations);
|
||||
searchUntrustedLocations = options.getBoolean(
|
||||
PdbAnalyzerCommon.OPTION_NAME_SEARCH_UNTRUSTED_LOCATIONS, searchUntrustedLocations);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,18 +165,18 @@ public class PdbAnalyzer extends AbstractAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the "allow remote" option that will be used by the analyzer when it is next invoked
|
||||
* Sets the "allow untrusted" option that will be used by the analyzer when it is next invoked
|
||||
* on the specified program.
|
||||
* <p>
|
||||
* Normally when the analyzer attempts to locate a matching PDB file it
|
||||
* will default to NOT searching remote symbol servers. A headless script could
|
||||
* use this method to allow the analyzer to search remote symbol servers.
|
||||
* will default to NOT searching untrusted symbol servers. A headless script could
|
||||
* use this method to allow the analyzer to search untrusted symbol servers.
|
||||
*
|
||||
* @param program {@link Program}
|
||||
* @param allowRemote boolean flag, true means analyzer can search remote symbol
|
||||
* @param allowUntrusted boolean flag, true means analyzer can search untrusted symbol
|
||||
* servers
|
||||
*/
|
||||
public static void setAllowRemoteOption(Program program, boolean allowRemote) {
|
||||
PdbAnalyzerCommon.setAllowRemoteOption(NAME, program, allowRemote);
|
||||
public static void setAllowUntrustedOption(Program program, boolean allowUntrusted) {
|
||||
PdbAnalyzerCommon.setAllowUntrustedOption(NAME, program, allowUntrusted);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-9
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -33,9 +33,9 @@ import pdb.symbolserver.SymbolFileInfo;
|
||||
* Shared configuration values and pdb searching logic
|
||||
*/
|
||||
public class PdbAnalyzerCommon {
|
||||
static final String OPTION_DESCRIPTION_SEARCH_REMOTE_LOCATIONS =
|
||||
"If checked, allow searching remote symbol servers for PDB files.";
|
||||
static final String OPTION_NAME_SEARCH_REMOTE_LOCATIONS = "Search remote symbol servers";
|
||||
static final String OPTION_DESCRIPTION_SEARCH_UNTRUSTED_LOCATIONS =
|
||||
"If checked, allow searching untrusted symbol servers for PDB files.";
|
||||
static final String OPTION_NAME_SEARCH_UNTRUSTED_LOCATIONS = "Search untrusted symbol servers";
|
||||
|
||||
static final String OPTION_DESCRIPTION_PDB_FILE = "Path to a manually chosen PDB file.";
|
||||
static final String OPTION_NAME_PDB_FILE = "PDB File";
|
||||
@@ -101,12 +101,13 @@ public class PdbAnalyzerCommon {
|
||||
*
|
||||
* @param analyzerName name of analyzer
|
||||
* @param program {@link Program}
|
||||
* @param allowRemote boolean flag, true means the analyzer can search remote
|
||||
* @param allowUntrusted boolean flag, true means the analyzer can search remote
|
||||
* symbol servers
|
||||
*/
|
||||
static void setAllowRemoteOption(String analyzerName, Program program, boolean allowRemote) {
|
||||
static void setAllowUntrustedOption(String analyzerName, Program program, boolean allowUntrusted) {
|
||||
Options options = program.getOptions(Program.ANALYSIS_PROPERTIES);
|
||||
options.setBoolean(analyzerName + "." + OPTION_NAME_SEARCH_REMOTE_LOCATIONS, allowRemote);
|
||||
options.setBoolean(analyzerName + "." + OPTION_NAME_SEARCH_UNTRUSTED_LOCATIONS,
|
||||
allowUntrusted);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +142,7 @@ public class PdbAnalyzerCommon {
|
||||
: null;
|
||||
if (pdbFile == null) {
|
||||
Set<FindOption> findOpts = allowRemote
|
||||
? FindOption.of(FindOption.ALLOW_REMOTE)
|
||||
? FindOption.of(FindOption.ALLOW_UNTRUSTED)
|
||||
: FindOption.NO_OPTIONS;
|
||||
pdbFile = PdbPlugin.findPdb(program, findOpts, monitor);
|
||||
}
|
||||
|
||||
+15
-15
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -83,7 +83,7 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
private File DEFAULT_FORCE_LOAD_FILE = new File(DEFAULT_SYMBOLS_DIR, "sample.pdb");
|
||||
private File forceLoadFile;
|
||||
|
||||
private boolean searchRemoteLocations = false;
|
||||
private boolean searchUntrustedLocations = false;
|
||||
|
||||
//==============================================================================================
|
||||
// Additional instance data
|
||||
@@ -164,7 +164,7 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
pdbFile = forceLoadFile;
|
||||
}
|
||||
else {
|
||||
pdbFile = PdbAnalyzerCommon.findPdb(this, program, searchRemoteLocations, monitor);
|
||||
pdbFile = PdbAnalyzerCommon.findPdb(this, program, searchUntrustedLocations, monitor);
|
||||
}
|
||||
if (pdbFile == null) {
|
||||
// warnings have already been logged
|
||||
@@ -262,9 +262,9 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
options.registerOption(OPTION_NAME_FORCELOAD_FILE, OptionType.FILE_TYPE,
|
||||
DEFAULT_FORCE_LOAD_FILE, null, OPTION_DESCRIPTION_FORCELOAD_FILE);
|
||||
}
|
||||
options.registerOption(PdbAnalyzerCommon.OPTION_NAME_SEARCH_REMOTE_LOCATIONS,
|
||||
searchRemoteLocations, null,
|
||||
PdbAnalyzerCommon.OPTION_DESCRIPTION_SEARCH_REMOTE_LOCATIONS);
|
||||
options.registerOption(PdbAnalyzerCommon.OPTION_NAME_SEARCH_UNTRUSTED_LOCATIONS,
|
||||
searchUntrustedLocations, null,
|
||||
PdbAnalyzerCommon.OPTION_DESCRIPTION_SEARCH_UNTRUSTED_LOCATIONS);
|
||||
|
||||
pdbReaderOptions.registerOptions(options);
|
||||
pdbApplicatorOptions.registerAnalyzerOptions(options);
|
||||
@@ -281,8 +281,8 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
forceLoadFile = options.getFile(OPTION_NAME_FORCELOAD_FILE, forceLoadFile);
|
||||
}
|
||||
|
||||
searchRemoteLocations = options.getBoolean(
|
||||
PdbAnalyzerCommon.OPTION_NAME_SEARCH_REMOTE_LOCATIONS, searchRemoteLocations);
|
||||
searchUntrustedLocations = options.getBoolean(
|
||||
PdbAnalyzerCommon.OPTION_NAME_SEARCH_UNTRUSTED_LOCATIONS, searchUntrustedLocations);
|
||||
|
||||
pdbReaderOptions.loadOptions(options);
|
||||
pdbApplicatorOptions.loadAnalyzerOptions(options);
|
||||
@@ -312,19 +312,19 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the "allow remote" option that will be used by the analyzer when it is next invoked
|
||||
* Sets the "allow untrusted" option that will be used by the analyzer when it is next invoked
|
||||
* on the specified program.
|
||||
* <p>
|
||||
* Normally when the analyzer attempts to locate a matching PDB file it
|
||||
* will default to NOT searching remote symbol servers. A headless script could
|
||||
* use this method to allow the analyzer to search remote symbol servers.
|
||||
* will default to NOT searching untrusted symbol servers. A headless script could
|
||||
* use this method to allow the analyzer to search untrusted symbol servers.
|
||||
*
|
||||
* @param program {@link Program}
|
||||
* @param allowRemote boolean flag, true means analyzer can search remote symbol
|
||||
* @param allowUntrusted boolean flag, true means analyzer can search remote symbol
|
||||
* servers
|
||||
*/
|
||||
public static void setAllowRemoteOption(Program program, boolean allowRemote) {
|
||||
PdbAnalyzerCommon.setAllowRemoteOption(NAME, program, allowRemote);
|
||||
public static void setAllowUntrustedOption(Program program, boolean allowUntrusted) {
|
||||
PdbAnalyzerCommon.setAllowUntrustedOption(NAME, program, allowUntrusted);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -136,11 +136,6 @@ public class ContainerFileSymbolServer implements SymbolServer {
|
||||
return fsFSRL.withPath(filename).toPrettyFullpathString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContainerFileSymbolServer: [ fsrl: %s ]".formatted(fsFSRL);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -114,11 +114,6 @@ public class DisabledSymbolServer implements SymbolServer {
|
||||
return delegate.getFileLocation(filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return delegate.isLocal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("DisabledSymbolServer: [ %s ]", delegate.toString());
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,18 +15,16 @@
|
||||
*/
|
||||
package pdb.symbolserver;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Options that control how Pdb files are searched for on a SymbolServer.
|
||||
*/
|
||||
public enum FindOption {
|
||||
/**
|
||||
* Allow connections to remote symbol servers
|
||||
* Allow connections to untrusted symbol servers
|
||||
*/
|
||||
ALLOW_REMOTE,
|
||||
ALLOW_UNTRUSTED,
|
||||
/**
|
||||
* Only return the first result
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -25,23 +25,31 @@ import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import ghidra.net.HttpClients;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.CancelledListener;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import pdb.symbolserver.SymbolServer.MutableTrust;
|
||||
|
||||
/**
|
||||
* A {@link SymbolServer} that is accessed via HTTP.
|
||||
* <p>
|
||||
*
|
||||
*/
|
||||
public class HttpSymbolServer extends AbstractSymbolServer {
|
||||
public class HttpSymbolServer extends AbstractSymbolServer implements MutableTrust {
|
||||
private static final String GHIDRA_USER_AGENT = "Ghidra_HttpSymbolServer_client";
|
||||
private static final int HTTP_STATUS_OK = HttpURLConnection.HTTP_OK;
|
||||
private static final int HTTP_REQUEST_TIMEOUT_MS = 10 * 1000; // 10 seconds
|
||||
|
||||
/**
|
||||
* pattern to match an optional "!" in front of a typical url string
|
||||
*/
|
||||
private static final Pattern NAMEPAT = Pattern.compile("(\\!?)(http(s?)://.*)");
|
||||
|
||||
/**
|
||||
* Predicate that tests if the location string is an instance of a HttpSymbolServer location.
|
||||
*
|
||||
@@ -49,10 +57,48 @@ public class HttpSymbolServer extends AbstractSymbolServer {
|
||||
* @return boolean true if the string should be handled by the HttpSymbolServer class
|
||||
*/
|
||||
public static boolean isHttpSymbolServerLocation(String locationString) {
|
||||
return locationString.startsWith("http://") || locationString.startsWith("https://");
|
||||
return NAMEPAT.matcher(locationString).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HttpSymbolServer instance from a locationString.
|
||||
*
|
||||
* @param locationString string previously returned by {@link #getName()}
|
||||
* @param context {@link SymbolServerInstanceCreatorContext}
|
||||
* @return new instance
|
||||
*/
|
||||
public static SymbolServer createInstance(String locationString,
|
||||
SymbolServerInstanceCreatorContext context) {
|
||||
Matcher m = NAMEPAT.matcher(locationString);
|
||||
if (!m.matches()) {
|
||||
return null;
|
||||
}
|
||||
boolean isTrusted = "!".equals(m.group(1));
|
||||
String url = m.group(2);
|
||||
return new HttpSymbolServer(URI.create(url), isTrusted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a trusted http symbol server
|
||||
*
|
||||
* @param url string url
|
||||
* @return new {@link HttpSymbolServer} instance
|
||||
*/
|
||||
public static HttpSymbolServer createTrusted(String url) {
|
||||
return new HttpSymbolServer(URI.create(url), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an untrusted http symbol server
|
||||
* @param url string url
|
||||
* @return new {@link HttpSymbolServer} instance
|
||||
*/
|
||||
public static HttpSymbolServer createUntrusted(String url) {
|
||||
return new HttpSymbolServer(URI.create(url), false);
|
||||
}
|
||||
|
||||
private final URI serverURI;
|
||||
private boolean trusted;
|
||||
|
||||
/**
|
||||
* Creates a new instance of a HttpSymbolServer.
|
||||
@@ -60,13 +106,29 @@ public class HttpSymbolServer extends AbstractSymbolServer {
|
||||
* @param serverURI URI / URL of the symbol server
|
||||
*/
|
||||
public HttpSymbolServer(URI serverURI) {
|
||||
this(serverURI, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of a HttpSymbolServer.
|
||||
*
|
||||
* @param serverURI URI / URL of the symbol server
|
||||
* @param isTrusted flag, if true the the http server can be trusted when querying and downloading
|
||||
*/
|
||||
public HttpSymbolServer(URI serverURI, boolean isTrusted) {
|
||||
String path = serverURI.getPath();
|
||||
this.serverURI =
|
||||
path.endsWith("/") ? serverURI : serverURI.resolve(serverURI.getPath() + "/");
|
||||
this.trusted = isTrusted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return (trusted ? "!" : "") + serverURI.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescriptiveName() {
|
||||
return serverURI.toString();
|
||||
}
|
||||
|
||||
@@ -170,14 +232,19 @@ public class HttpSymbolServer extends AbstractSymbolServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
public boolean isTrusted() {
|
||||
return trusted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrusted(boolean isTrusted) {
|
||||
this.trusted = isTrusted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("HttpSymbolServer: [ url: %s, storageLevel: %d]", serverURI.toString(),
|
||||
storageLevel);
|
||||
return String.format("HttpSymbolServer: [ url: %s, trusted: %b, storageLevel: %d]",
|
||||
serverURI.toString(), trusted, storageLevel);
|
||||
}
|
||||
|
||||
private String logPrefix() {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -371,11 +371,6 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor
|
||||
return new SymbolServerInputStream(new FileInputStream(file), file.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("LocalSymbolStore: [ rootDir: %s, storageLevel: %d]",
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -20,6 +20,7 @@ import java.util.*;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import pdb.symbolserver.SymbolServer.StatusRequiresContext;
|
||||
|
||||
/**
|
||||
* A Pdb symbol server / symbol store, similar to the {@link LocalSymbolStore},
|
||||
@@ -27,7 +28,7 @@ import ghidra.util.task.TaskMonitor;
|
||||
* <p>
|
||||
*
|
||||
*/
|
||||
public class SameDirSymbolStore implements SymbolStore {
|
||||
public class SameDirSymbolStore implements SymbolStore, StatusRequiresContext {
|
||||
|
||||
/**
|
||||
* Descriptive string
|
||||
@@ -166,11 +167,6 @@ public class SameDirSymbolStore implements SymbolStore {
|
||||
return getFile(filename).getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("SameDirSymbolStore: [ dir: %s ]", rootDir);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -17,8 +17,7 @@ package pdb.symbolserver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -29,6 +28,27 @@ import ghidra.util.task.TaskMonitor;
|
||||
*
|
||||
*/
|
||||
public interface SymbolServer {
|
||||
/**
|
||||
* Optional add-on interface for {@link SymbolServer}s that flag server types as requiring a
|
||||
* valid context object to be queried for {@link SymbolServer#isValid(TaskMonitor)}
|
||||
*/
|
||||
interface StatusRequiresContext {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional add-on interface for {@link SymbolServer}s that allow their trusted-ness value to
|
||||
* be modified.
|
||||
*/
|
||||
public interface MutableTrust {
|
||||
|
||||
/**
|
||||
* Sets the trusted attribute of this symbol server.
|
||||
*
|
||||
* @param isTrusted boolean flag, if true this symbolserver will be marked as trusted
|
||||
*/
|
||||
void setTrusted(boolean isTrusted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the symbol server, suitable to use as the identity of this instance,
|
||||
@@ -55,6 +75,16 @@ public interface SymbolServer {
|
||||
*/
|
||||
boolean isValid(TaskMonitor monitor);
|
||||
|
||||
/**
|
||||
* Returns true if this {@link SymbolServer} is 'trusted', meaning
|
||||
* it can be searched without security issues / warning the user.
|
||||
*
|
||||
* @return boolean true if this symbolserver is trusted, false if untrusted
|
||||
*/
|
||||
default boolean isTrusted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the raw filename exists in the symbol server.
|
||||
*
|
||||
@@ -103,10 +133,13 @@ public interface SymbolServer {
|
||||
String getFileLocation(String filename);
|
||||
|
||||
/**
|
||||
* Returns true if this {@link SymbolServer} is 'local', meaning
|
||||
* it can be searched without security issues / warning the user.
|
||||
* Returns the number of configured symbol servers that are considered 'untrusted'.
|
||||
*
|
||||
* @return boolean true if this symbolserver is 'local', false if remote
|
||||
* @param symbolServers list of {@link SymbolServer}s
|
||||
* @return number of untrusted symbol servers
|
||||
*/
|
||||
boolean isLocal();
|
||||
static int getUntrustedCount(Collection<SymbolServer> symbolServers) {
|
||||
return (int) symbolServers.stream().filter(ss -> !ss.isTrusted()).count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,7 +16,6 @@
|
||||
package pdb.symbolserver;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -167,7 +166,7 @@ public class SymbolServerInstanceCreatorRegistry {
|
||||
registerSymbolServerInstanceCreator(0, DisabledSymbolServer::isDisabledSymbolServerLocation,
|
||||
DisabledSymbolServer::createInstance);
|
||||
registerSymbolServerInstanceCreator(100, HttpSymbolServer::isHttpSymbolServerLocation,
|
||||
(loc, context) -> new HttpSymbolServer(URI.create(loc)));
|
||||
HttpSymbolServer::createInstance);
|
||||
registerSymbolServerInstanceCreator(200, SameDirSymbolStore::isSameDirLocation,
|
||||
SameDirSymbolStore::createInstance);
|
||||
registerSymbolServerInstanceCreator(300, LocalSymbolStore::isLocalSymbolStoreLocation,
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,11 +15,10 @@
|
||||
*/
|
||||
package pdb.symbolserver;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -31,8 +30,7 @@ import pdb.PdbUtils;
|
||||
|
||||
/**
|
||||
* A (lowercase-'S') service that searches for and fetches symbol files
|
||||
* from a set of local and remote {@link SymbolServer symbolservers}. (not to be
|
||||
* confused with a Plugin service)
|
||||
* from a set of {@link SymbolServer symbolservers}. (not to be confused with a Plugin service)
|
||||
* <p>
|
||||
* Instances of this class are meant to be easily created when needed
|
||||
* and just as easily thrown away when not used or when the search
|
||||
@@ -50,9 +48,8 @@ public class SymbolServerService {
|
||||
/**
|
||||
* Creates a new SymbolServerService instance.
|
||||
* <p>
|
||||
* @param symbolStore a {@link SymbolStore} - where all
|
||||
* remote files are placed when downloaded. Also treated as a SymbolServer
|
||||
* and searched first
|
||||
* @param symbolStore a {@link SymbolStore} - where all remote files are placed when
|
||||
* downloaded. Also treated as a SymbolServer and searched first
|
||||
* @param symbolServers a list of {@link SymbolServer symbol servers} - searched in order
|
||||
*/
|
||||
public SymbolServerService(SymbolStore symbolStore, List<SymbolServer> symbolServers) {
|
||||
@@ -91,19 +88,6 @@ public class SymbolServerService {
|
||||
return new ArrayList<>(symbolServers.subList(1, symbolServers.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of configured symbol servers that are considered 'remote'.
|
||||
* @return number of remote symbol servers
|
||||
*/
|
||||
public int getRemoteSymbolServerCount() {
|
||||
int remoteSymbolServerCount = (int) getSymbolServers()
|
||||
.stream()
|
||||
.filter(ss -> !ss.isLocal())
|
||||
.count();
|
||||
|
||||
return remoteSymbolServerCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches all {@link SymbolServer symbol servers} for a matching pdb symbol file.
|
||||
*
|
||||
@@ -150,9 +134,9 @@ public class SymbolServerService {
|
||||
|
||||
for_each_symbol_server_loop: for (SymbolServer symbolServer : symbolServers) {
|
||||
monitor.checkCancelled();
|
||||
if (!symbolServer.isLocal() && !findOptions.contains(FindOption.ALLOW_REMOTE)) {
|
||||
if (!symbolServer.isTrusted() && !findOptions.contains(FindOption.ALLOW_UNTRUSTED)) {
|
||||
Msg.debug(this,
|
||||
logPrefix() + ": skipping non-local symbol server " +
|
||||
logPrefix() + ": skipping untrusted symbol server " +
|
||||
symbolServer.getDescriptiveName());
|
||||
continue;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -72,6 +72,8 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
||||
ExtensionFileFilter.forExtensions("Microsoft Program Databases", "pdb", "pd_", "pdb.xml");
|
||||
|
||||
private static final SymbolFileInfo UNKNOWN_SYMFILE = makeUnknownSymbolFileInstance("");
|
||||
private static final List<WellKnownSymbolServerLocation> knownSymbolServers =
|
||||
WellKnownSymbolServerLocation.loadAll();
|
||||
|
||||
public static class LoadPdbResults {
|
||||
public File pdbFile;
|
||||
@@ -270,7 +272,7 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
||||
return SymbolFileInfo.fromValues(pdbPath, uid, age);
|
||||
}
|
||||
|
||||
private void searchForPdbs(boolean allowRemote) {
|
||||
private void searchForPdbs(boolean allowUntrusted) {
|
||||
if (pdbAgeTextField.getText().isBlank() ||
|
||||
pdbAgeTextField.getValue() > NumericUtilities.MAX_UNSIGNED_INT32_AS_LONG) {
|
||||
Msg.showWarn(this, null, "Bad PDB Age", "Invalid PDB Age value");
|
||||
@@ -282,8 +284,8 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
||||
return;
|
||||
}
|
||||
Set<FindOption> findOptions = symbolFilePanel.getFindOptions();
|
||||
if (allowRemote) {
|
||||
findOptions.add(FindOption.ALLOW_REMOTE);
|
||||
if (allowUntrusted) {
|
||||
findOptions.add(FindOption.ALLOW_UNTRUSTED);
|
||||
}
|
||||
executeMonitoredRunnable("Search for PDBs", true, true, 0, monitor -> {
|
||||
try {
|
||||
@@ -316,10 +318,11 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
||||
setHelpLocation(new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "Load PDB File"));
|
||||
|
||||
addStatusTextSupplier(() -> lastSearchOptions != null && advancedToggleButton.isSelected()
|
||||
? SymbolServerPanel.getSymbolServerWarnings(symbolServerService.getSymbolServers())
|
||||
? WellKnownSymbolServerLocation.getWarningsFor(knownSymbolServers,
|
||||
symbolServerService.getSymbolServers())
|
||||
: null);
|
||||
addStatusTextSupplier(this::getSelectedPdbNoticeText);
|
||||
addStatusTextSupplier(this::getAllowRemoteWarning);
|
||||
addStatusTextSupplier(this::getAllowUntrustedWarning);
|
||||
addStatusTextSupplier(this::getFoundCountInfo);
|
||||
|
||||
addButtons();
|
||||
@@ -600,12 +603,13 @@ public class LoadPdbDialog extends DialogComponentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private StatusText getAllowRemoteWarning() {
|
||||
int remoteSymbolServerCount = symbolServerService.getRemoteSymbolServerCount();
|
||||
private StatusText getAllowUntrustedWarning() {
|
||||
int untrustedSymbolServerCount =
|
||||
SymbolServer.getUntrustedCount(symbolServerService.getSymbolServers());
|
||||
return lastSearchOptions != null && advancedToggleButton.isSelected() &&
|
||||
remoteSymbolServerCount != 0 && !lastSearchOptions.contains(FindOption.ALLOW_REMOTE)
|
||||
untrustedSymbolServerCount != 0 && !lastSearchOptions.contains(FindOption.ALLOW_UNTRUSTED)
|
||||
? new StatusText(
|
||||
"Remote servers were excluded. Use \"Search All\" button to also search remote servers.",
|
||||
"Untrusted servers were excluded. Use \"Search All\" button to also include untrusted servers.",
|
||||
MessageType.INFO, false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -39,7 +39,7 @@ import pdb.symbolserver.FindOption;
|
||||
*/
|
||||
class SymbolFilePanel extends JPanel {
|
||||
interface SearchCallback {
|
||||
void searchForPdbs(boolean allowRemote);
|
||||
void searchForPdbs(boolean allowUntrusted);
|
||||
}
|
||||
|
||||
static final String SEARCH_OPTIONS_HELP_ANCHOR = "PDB_Search_Search_Options";
|
||||
@@ -149,10 +149,10 @@ class SymbolFilePanel extends JPanel {
|
||||
}
|
||||
|
||||
private JPanel buildButtonPanel() {
|
||||
searchLocalButton = new JButton("Search Local");
|
||||
searchLocalButton.setToolTipText("Search local symbol servers only.");
|
||||
searchLocalButton = new JButton("Search");
|
||||
searchLocalButton.setToolTipText("Search trusted symbol servers only.");
|
||||
searchAllButton = new JButton("Search All");
|
||||
searchAllButton.setToolTipText("Search local and remote symbol servers.");
|
||||
searchAllButton.setToolTipText("Search trusted and untrusted symbol servers.");
|
||||
|
||||
ignorePdbUid = new GCheckBox("Ignore GUID/ID");
|
||||
ignorePdbUid.setToolTipText(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,8 +15,12 @@
|
||||
*/
|
||||
package pdb.symbolserver.ui;
|
||||
|
||||
import static pdb.symbolserver.ui.SymbolServerRow.LocationStatus.*;
|
||||
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import pdb.symbolserver.DisabledSymbolServer;
|
||||
import pdb.symbolserver.SymbolServer;
|
||||
import pdb.symbolserver.SymbolServer.MutableTrust;
|
||||
|
||||
/**
|
||||
* Represents a row in the {@link SymbolServerTableModel}
|
||||
@@ -59,6 +63,16 @@ class SymbolServerRow {
|
||||
}
|
||||
}
|
||||
|
||||
boolean isTrusted() {
|
||||
return symbolServer.isTrusted();
|
||||
}
|
||||
|
||||
void setTrusted(boolean isTrusted) {
|
||||
if (symbolServer instanceof MutableTrust sswt) {
|
||||
sswt.setTrusted(isTrusted);
|
||||
}
|
||||
}
|
||||
|
||||
LocationStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
@@ -67,6 +81,12 @@ class SymbolServerRow {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
void updateStatus(TaskMonitor monitor) {
|
||||
if (!(symbolServer instanceof SymbolServer.StatusRequiresContext)) {
|
||||
this.status = symbolServer.isValid(monitor) ? VALID : INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("SymbolServerRow: [ status: %s, server: %s]", status.toString(),
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,30 +15,28 @@
|
||||
*/
|
||||
package pdb.symbolserver.ui;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static pdb.symbolserver.ui.SymbolServerRow.LocationStatus.INVALID;
|
||||
import static pdb.symbolserver.ui.SymbolServerRow.LocationStatus.VALID;
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.FontMetrics;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
import docking.widgets.table.*;
|
||||
import generic.theme.GIcon;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.framework.plugintool.ServiceProviderStub;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.table.column.AbstractGColumnRenderer;
|
||||
import ghidra.util.table.column.GColumnRenderer;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import pdb.symbolserver.SymbolServer;
|
||||
import resources.Icons;
|
||||
|
||||
/**
|
||||
* Table model for the {@link SymbolServerPanel} table
|
||||
* Table model for the {@link ConfigPdbDialog} table
|
||||
*/
|
||||
class SymbolServerTableModel
|
||||
extends GDynamicColumnTableModel<SymbolServerRow, List<SymbolServerRow>> {
|
||||
@@ -64,9 +62,7 @@ class SymbolServerTableModel
|
||||
}
|
||||
|
||||
List<SymbolServer> getSymbolServers() {
|
||||
return rows.stream()
|
||||
.map(SymbolServerRow::getSymbolServer)
|
||||
.collect(toList());
|
||||
return rows.stream().map(SymbolServerRow::getSymbolServer).collect(toList());
|
||||
}
|
||||
|
||||
void addSymbolServer(SymbolServer ss) {
|
||||
@@ -92,26 +88,6 @@ class SymbolServerTableModel
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
void refreshSymbolServerLocationStatus() {
|
||||
List<SymbolServerRow> rowsCopy = new ArrayList<>(this.rows);
|
||||
TaskLauncher.launchNonModal("Refresh Symbol Server Location Status", monitor -> {
|
||||
monitor.initialize(rowsCopy.size());
|
||||
monitor.setMessage("Refreshing symbol server status");
|
||||
try {
|
||||
for (SymbolServerRow row : rowsCopy) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
monitor.setMessage("Checking " + row.getSymbolServer().getName());
|
||||
row.setStatus(row.getSymbolServer().isValid(monitor) ? VALID : INVALID);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Swing.runLater(SymbolServerTableModel.this::fireTableDataChanged);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void moveRow(int rowIndex, int deltaIndex) {
|
||||
int destIndex = rowIndex + deltaIndex;
|
||||
if (rowIndex < 0 || rowIndex >= rows.size() || destIndex < 0 || destIndex >= rows.size()) {
|
||||
@@ -159,18 +135,24 @@ class SymbolServerTableModel
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
DynamicTableColumn<SymbolServerRow, ?, ?> column = getColumn(columnIndex);
|
||||
if (column instanceof EnabledColumn) {
|
||||
if (column instanceof EnabledColumn && aValue instanceof Boolean) {
|
||||
SymbolServerRow row = getRowObject(rowIndex);
|
||||
row.setEnabled((Boolean) aValue);
|
||||
dataChanged = true;
|
||||
fireTableDataChanged();
|
||||
}
|
||||
else if (column instanceof TrustedColumn && aValue instanceof Boolean) {
|
||||
SymbolServerRow row = getRowObject(rowIndex);
|
||||
row.setTrusted((Boolean) aValue);
|
||||
dataChanged = true;
|
||||
fireTableDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
DynamicTableColumn<SymbolServerRow, ?, ?> column = getColumn(columnIndex);
|
||||
return column instanceof EnabledColumn;
|
||||
return column instanceof EnabledColumn || column instanceof TrustedColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,6 +160,7 @@ class SymbolServerTableModel
|
||||
TableColumnDescriptor<SymbolServerRow> descriptor = new TableColumnDescriptor<>();
|
||||
|
||||
descriptor.addVisibleColumn(new EnabledColumn());
|
||||
descriptor.addVisibleColumn(new TrustedColumn());
|
||||
descriptor.addVisibleColumn(new StatusColumn());
|
||||
descriptor.addVisibleColumn(new LocationColumn());
|
||||
|
||||
@@ -187,9 +170,10 @@ class SymbolServerTableModel
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
private static class StatusColumn extends
|
||||
AbstractDynamicTableColumnStub<SymbolServerRow, SymbolServerRow.LocationStatus> {
|
||||
AbstractDynamicTableColumnStub<SymbolServerRow, SymbolServerRow.LocationStatus>
|
||||
implements TableColumnInitializer {
|
||||
|
||||
private static final Icon VALID_ICON = Icons.get("images/checkmark_green.gif");
|
||||
private static final Icon VALID_ICON = new GIcon("icon.checkmark.green");
|
||||
private static final Icon INVALID_ICON = Icons.ERROR_ICON;
|
||||
|
||||
private static Icon[] icons = new Icon[] { null, VALID_ICON, INVALID_ICON };
|
||||
@@ -206,7 +190,7 @@ class SymbolServerTableModel
|
||||
|
||||
@Override
|
||||
public String getColumnDisplayName(Settings settings) {
|
||||
return "";
|
||||
return "Status";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,14 +203,23 @@ class SymbolServerTableModel
|
||||
return renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTableColumn(TableColumn col, FontMetrics fm, int padding) {
|
||||
int colWidth = fm.stringWidth("Status") + padding;
|
||||
col.setPreferredWidth(colWidth);
|
||||
col.setMaxWidth(colWidth * 2);
|
||||
col.setMinWidth(colWidth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class EnabledColumn
|
||||
extends AbstractDynamicTableColumnStub<SymbolServerRow, Boolean> {
|
||||
extends AbstractDynamicTableColumnStub<SymbolServerRow, Boolean>
|
||||
implements TableColumnInitializer {
|
||||
|
||||
@Override
|
||||
public String getColumnDisplayName(Settings settings) {
|
||||
return "";
|
||||
return "Enabled";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -240,6 +233,43 @@ class SymbolServerTableModel
|
||||
return "Enabled";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTableColumn(TableColumn col, FontMetrics fm, int padding) {
|
||||
int colWidth = fm.stringWidth("Enabled") + padding;
|
||||
col.setPreferredWidth(colWidth);
|
||||
col.setMaxWidth(colWidth * 2);
|
||||
col.setMinWidth(colWidth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TrustedColumn
|
||||
extends AbstractDynamicTableColumnStub<SymbolServerRow, Boolean>
|
||||
implements TableColumnInitializer {
|
||||
|
||||
@Override
|
||||
public String getColumnDisplayName(Settings settings) {
|
||||
return "Trusted";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue(SymbolServerRow rowObject, Settings settings,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
return rowObject.isTrusted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
return "Trusted";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTableColumn(TableColumn col, FontMetrics fm, int padding) {
|
||||
int colWidth = fm.stringWidth("Trusted") + padding;
|
||||
col.setPreferredWidth(colWidth);
|
||||
col.setMaxWidth(colWidth * 2);
|
||||
col.setMinWidth(colWidth);
|
||||
}
|
||||
}
|
||||
|
||||
private static class LocationColumn
|
||||
@@ -305,5 +335,6 @@ class SymbolServerTableModel
|
||||
public String getFilterString(E t, Settings settings) {
|
||||
return t == null ? "" : t.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package pdb.symbolserver.ui;
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.widgets.table.*;
|
||||
|
||||
/**
|
||||
* For Pdb symbolserver gui stuff only.
|
||||
*
|
||||
* Add on interface for DynamicTableColumn classes that let them control aspects of the
|
||||
* matching TableColumn.
|
||||
*/
|
||||
public interface TableColumnInitializer {
|
||||
/**
|
||||
* Best called during {@link DialogComponentProvider#dialogShown} or
|
||||
* {@link ComponentProvider#componentShown}
|
||||
*
|
||||
* @param table table component
|
||||
* @param model table model
|
||||
*/
|
||||
static void initializeTableColumns(GTable table, GDynamicColumnTableModel<?, ?> model) {
|
||||
TableColumnModel colModel = table.getColumnModel();
|
||||
|
||||
FontMetrics fm = table.getTableHeader().getFontMetrics(table.getTableHeader().getFont());
|
||||
int padding = fm.stringWidth("WW"); // w.a.g. for the left+right padding on the header column component
|
||||
|
||||
for (int colIndex = 0; colIndex < model.getColumnCount(); colIndex++) {
|
||||
DynamicTableColumn<?, ?, ?> dtableCol = model.getColumn(colIndex);
|
||||
if (dtableCol instanceof TableColumnInitializer colInitializer) {
|
||||
TableColumn tableCol = colModel.getColumn(colIndex);
|
||||
colInitializer.initializeTableColumn(tableCol, fm, padding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to allow the initializer to modify the specified TableColumn
|
||||
*
|
||||
* @param col {@link TableColumn}
|
||||
* @param fm {@link FontMetrics} used by the table header gui component
|
||||
* @param padding padding to use in the column
|
||||
*/
|
||||
void initializeTableColumn(TableColumn col, FontMetrics fm, int padding);
|
||||
}
|
||||
+40
-54
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -17,68 +17,27 @@ package pdb.symbolserver.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.MessageType;
|
||||
import ghidra.util.Msg;
|
||||
import pdb.symbolserver.SymbolServer;
|
||||
import pdb.symbolserver.ui.LoadPdbDialog.StatusText;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
/**
|
||||
* Represents a well-known symbol server location.
|
||||
* <p>
|
||||
* See the PDB_SYMBOL_SERVER_URLS.pdburl file.
|
||||
* @param location url string
|
||||
* @param locationCategory grouping criteria
|
||||
* @param warning string
|
||||
* @param fileOrigin file name that contained this info
|
||||
*/
|
||||
class WellKnownSymbolServerLocation {
|
||||
private String locationCategory;
|
||||
private String location;
|
||||
private String warning;
|
||||
private String fileOrigin;
|
||||
|
||||
WellKnownSymbolServerLocation(String location, String locationCategory, String warning,
|
||||
String fileOrigin) {
|
||||
this.location = location;
|
||||
this.locationCategory = locationCategory;
|
||||
this.warning = warning;
|
||||
this.fileOrigin = fileOrigin;
|
||||
}
|
||||
|
||||
String getLocationCategory() {
|
||||
return locationCategory;
|
||||
}
|
||||
|
||||
String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
String getWarning() {
|
||||
return warning;
|
||||
}
|
||||
|
||||
String getFileOrigin() {
|
||||
return fileOrigin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(location, locationCategory, warning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
WellKnownSymbolServerLocation other = (WellKnownSymbolServerLocation) obj;
|
||||
return Objects.equals(location, other.location) &&
|
||||
Objects.equals(locationCategory, other.locationCategory) &&
|
||||
Objects.equals(warning, other.warning);
|
||||
}
|
||||
public record WellKnownSymbolServerLocation(String location, String locationCategory,
|
||||
String warning, String fileOrigin) {
|
||||
|
||||
/**
|
||||
* Loads all symbol server location files (*.pdburl) and returns a list of entries.
|
||||
@@ -103,10 +62,37 @@ class WellKnownSymbolServerLocation {
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.warn(WellKnownSymbolServerLocation.class, "Unable to read pdburl file: " + file);
|
||||
Msg.warn(WellKnownSymbolServerLocation.class,
|
||||
"Unable to read pdburl file: " + file);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted StatusText containing all the warnings published by any untrusted
|
||||
* {@link WellKnownSymbolServerLocation} found in the list of symbolservers.
|
||||
*
|
||||
* @param knownSymbolServers list
|
||||
* @param symbolServers list
|
||||
* @return StatusText
|
||||
*/
|
||||
public static StatusText getWarningsFor(List<WellKnownSymbolServerLocation> knownSymbolServers,
|
||||
List<SymbolServer> symbolServers) {
|
||||
Map<String, String> warningsByLocation = new HashMap<>();
|
||||
for (WellKnownSymbolServerLocation ssloc : knownSymbolServers) {
|
||||
if (ssloc.warning() != null && !ssloc.warning().isBlank()) {
|
||||
warningsByLocation.put(ssloc.location(), ssloc.warning());
|
||||
}
|
||||
}
|
||||
String warning = symbolServers.stream()
|
||||
.filter(symbolServer -> !symbolServer.isTrusted())
|
||||
.map(symbolServer -> warningsByLocation.get(symbolServer.getName()))
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.joining("<br>\n"));
|
||||
|
||||
return !warning.isEmpty() ? new StatusText(warning, MessageType.WARNING, false) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -21,14 +21,16 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import pdb.symbolserver.SymbolServer.MutableTrust;
|
||||
|
||||
/**
|
||||
* A "remote" symbol server that answers affirmatively for any query.
|
||||
*/
|
||||
public class DummySymbolServer implements SymbolServer {
|
||||
public class DummySymbolServer implements SymbolServer, MutableTrust {
|
||||
|
||||
private final byte[] dummyPayload;
|
||||
private final boolean returnCompressedFilenames;
|
||||
private boolean trusted;
|
||||
|
||||
public DummySymbolServer(String dummyPayload) {
|
||||
this(dummyPayload.getBytes(), false);
|
||||
@@ -78,8 +80,13 @@ public class DummySymbolServer implements SymbolServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
public boolean isTrusted() {
|
||||
return trusted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrusted(boolean isTrusted) {
|
||||
this.trusted = isTrusted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,16 +15,14 @@
|
||||
*/
|
||||
package pdb.symbolserver;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -128,14 +126,14 @@ public class SymbolServerServiceTest extends AbstractGenericTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Remote() throws IOException, CancelledException {
|
||||
public void test_Trusted() throws IOException, CancelledException {
|
||||
String payload = "testdummy";
|
||||
SymbolServerService symbolServerService =
|
||||
new SymbolServerService(localSymbolStore1,
|
||||
List.of(localSymbolStore2, new DummySymbolServer(payload)));
|
||||
SymbolFileInfo searchPdb = SymbolFileInfo.fromValues("file1.pdb", "11223344", 0);
|
||||
List<SymbolFileLocation> results =
|
||||
symbolServerService.find(searchPdb, FindOption.of(FindOption.ALLOW_REMOTE),
|
||||
symbolServerService.find(searchPdb, FindOption.of(FindOption.ALLOW_UNTRUSTED),
|
||||
TaskMonitor.DUMMY);
|
||||
|
||||
assertEquals(1, results.size());
|
||||
@@ -148,8 +146,9 @@ public class SymbolServerServiceTest extends AbstractGenericTest {
|
||||
@Test
|
||||
public void test_NoRemote() throws CancelledException {
|
||||
String payload = "testdummy";
|
||||
DummySymbolServer dummySymbolServer = new DummySymbolServer(payload);
|
||||
SymbolServerService symbolServerService =
|
||||
new SymbolServerService(localSymbolStore1, List.of(new DummySymbolServer(payload)));
|
||||
new SymbolServerService(localSymbolStore1, List.of(dummySymbolServer));
|
||||
SymbolFileInfo searchPdb = SymbolFileInfo.fromValues("file1.pdb", "11223344", 0);
|
||||
List<SymbolFileLocation> results =
|
||||
symbolServerService.find(searchPdb, FindOption.NO_OPTIONS, TaskMonitor.DUMMY);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -31,8 +31,7 @@ import ghidra.framework.options.Options;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import pdb.PdbPlugin;
|
||||
import pdb.symbolserver.*;
|
||||
import pdb.symbolserver.ui.ConfigPdbDialog;
|
||||
import pdb.symbolserver.ui.LoadPdbDialog;
|
||||
import pdb.symbolserver.ui.*;
|
||||
|
||||
public class PdbScreenShots extends GhidraScreenShotGenerator {
|
||||
|
||||
@@ -64,7 +63,7 @@ public class PdbScreenShots extends GhidraScreenShotGenerator {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSymbolServerConfig_Screenshot() throws IOException {
|
||||
public void testSymbolServerConfig_Screenshot() {
|
||||
PdbPlugin.saveSymbolServerServiceConfig(null);
|
||||
ConfigPdbDialog configPdbDialog = new ConfigPdbDialog();
|
||||
showDialogWithoutBlocking(tool, configPdbDialog);
|
||||
@@ -79,7 +78,7 @@ public class PdbScreenShots extends GhidraScreenShotGenerator {
|
||||
LocalSymbolStore localSymbolStore1 = new LocalSymbolStore(localSymbolStore1Root);
|
||||
SameDirSymbolStore sameDirSymbolStore = new SameDirSymbolStore(null);
|
||||
List<SymbolServer> symbolServers = List.of(sameDirSymbolStore,
|
||||
new HttpSymbolServer(URI.create("https://msdl.microsoft.com/download/symbols/")));
|
||||
HttpSymbolServer.createTrusted("https://msdl.microsoft.com/download/symbols/"));
|
||||
SymbolServerService symbolServerService =
|
||||
new SymbolServerService(localSymbolStore1, symbolServers);
|
||||
PdbPlugin.saveSymbolServerServiceConfig(symbolServerService);
|
||||
@@ -88,7 +87,7 @@ public class PdbScreenShots extends GhidraScreenShotGenerator {
|
||||
configPdbDialog.setSymbolServerService("/home/user/symbols", symbolServers);
|
||||
showDialogWithoutBlocking(tool, configPdbDialog);
|
||||
waitForSwing();
|
||||
captureDialog(ConfigPdbDialog.class, 410, 280);
|
||||
captureDialog(ConfigPdbDialog.class, 520, 280);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,12 +111,29 @@ public class PdbScreenShots extends GhidraScreenShotGenerator {
|
||||
showDialogWithoutBlocking(tool, configPdbDialog);
|
||||
waitForSwing();
|
||||
runSwing(() -> {
|
||||
configPdbDialog.setWellknownSymbolServers(createFakeWellKnowns());
|
||||
configPdbDialog.pushAddLocationButton();
|
||||
});
|
||||
waitForSwing();
|
||||
captureMenu();
|
||||
}
|
||||
|
||||
List<WellKnownSymbolServerLocation> createFakeWellKnowns() {
|
||||
// due to module dependencies, this screen shot test can't see the contents of the normal
|
||||
// PDBURL file loaded from the 'z public release' module.
|
||||
return List.of( // should be same as the PDB_SYMBOL_SERVERS.PDBURL file
|
||||
new WellKnownSymbolServerLocation("", "https://msdl.microsoft.com/download/symbols/",
|
||||
"WARNING: Check your organization's security policy before downloading files from the internet.",
|
||||
"screen shot"),
|
||||
new WellKnownSymbolServerLocation("",
|
||||
"https://chromium-browser-symsrv.commondatastorage.googleapis.com",
|
||||
"WARNING: Check your organization's security policy before downloading files from the internet.",
|
||||
"screen shot"),
|
||||
new WellKnownSymbolServerLocation("", "https://symbols.mozilla.org/",
|
||||
"WARNING: Check your organization's security policy before downloading files from the internet.",
|
||||
"screen shot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadPdb_Advanced_NeedsConfig() {
|
||||
PdbPlugin.saveSymbolServerServiceConfig(null);
|
||||
@@ -158,7 +174,7 @@ public class PdbScreenShots extends GhidraScreenShotGenerator {
|
||||
localSymbolStore1, SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 2)),
|
||||
new SymbolFileLocation("HelloWorld.pdb", sameDirSymbolStoreWithFakePath,
|
||||
SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 1)));
|
||||
Set<FindOption> findOptions = FindOption.of(FindOption.ALLOW_REMOTE, FindOption.ANY_AGE);
|
||||
Set<FindOption> findOptions = FindOption.of(FindOption.ALLOW_UNTRUSTED, FindOption.ANY_AGE);
|
||||
runSwing(() -> {
|
||||
loadPdbDialog.setSearchOptions(findOptions);
|
||||
loadPdbDialog.setSearchResults(symbolFileLocations, findOptions);
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -99,7 +99,7 @@ public class SymbolServerService2Test extends AbstractGhidraHeadedIntegrationTes
|
||||
|
||||
List<SymbolFileLocation> results =
|
||||
symbolServerService.find(SymbolFileInfo.fromValues("test.pdb", "11223344", 1),
|
||||
FindOption.of(FindOption.ALLOW_REMOTE), TaskMonitor.DUMMY);
|
||||
FindOption.of(FindOption.ALLOW_UNTRUSTED), TaskMonitor.DUMMY);
|
||||
|
||||
assertEquals(1, results.size());
|
||||
System.out.println(results.get(0).getLocationStr());
|
||||
@@ -118,7 +118,7 @@ public class SymbolServerService2Test extends AbstractGhidraHeadedIntegrationTes
|
||||
|
||||
List<SymbolFileLocation> results =
|
||||
symbolServerService.find(SymbolFileInfo.fromValues("test.pdb", "11223344", 1),
|
||||
FindOption.of(FindOption.ALLOW_REMOTE), TaskMonitor.DUMMY);
|
||||
FindOption.of(FindOption.ALLOW_UNTRUSTED), TaskMonitor.DUMMY);
|
||||
|
||||
assertEquals(1, results.size());
|
||||
System.out.println(results.get(0).getLocationStr());
|
||||
|
||||
Reference in New Issue
Block a user