ghidra/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java

210 lines
7.5 KiB
Java

/* ###
* 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 help.screenshot;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Set;
import org.apache.commons.io.FilenameUtils;
import org.junit.*;
import ghidra.app.util.bin.format.pdb.PdbInfo;
import ghidra.app.util.bin.format.pdb.PdbInfoDotNet;
import ghidra.app.util.datatype.microsoft.GUID;
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;
public class PdbScreenShots extends GhidraScreenShotGenerator {
private static final String GUID1_STR = "012345670123012301230123456789AB";
private int tx;
private File temporaryDir;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
temporaryDir = createTempDirectory("example_pdb");
tx = program.startTransaction("set analyzed flag");
Options proplist = program.getOptions(Program.PROGRAM_INFO);
proplist.setBoolean(Program.ANALYZED_OPTION_NAME, false);
PdbInfo pdbInfo = PdbInfoDotNet.fromValues("HelloWorld.pdb", 1, new GUID(GUID1_STR));
pdbInfo.serializeToOptions(proplist);
proplist.setString("Executable Location",
new File(temporaryDir, program.getName()).getPath());
}
@Override
@After
public void tearDown() throws Exception {
program.endTransaction(tx, false);
super.tearDown();
}
@Test
public void testSymbolServerConfig_Screenshot() throws IOException {
PdbPlugin.saveSymbolServerServiceConfig(null);
ConfigPdbDialog configPdbDialog = new ConfigPdbDialog();
showDialogWithoutBlocking(tool, configPdbDialog);
waitForSwing();
captureDialog(ConfigPdbDialog.class, 410, 280);
}
@Test
public void testSymbolServerConfig_Configured() throws IOException {
File localSymbolStore1Root = new File(temporaryDir, "symbols");
LocalSymbolStore.create(localSymbolStore1Root, 1);
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/")));
SymbolServerService symbolServerService =
new SymbolServerService(localSymbolStore1, symbolServers);
PdbPlugin.saveSymbolServerServiceConfig(symbolServerService);
ConfigPdbDialog configPdbDialog = new ConfigPdbDialog();
configPdbDialog.setSymbolServerService("/home/user/symbols", symbolServers);
showDialogWithoutBlocking(tool, configPdbDialog);
waitForSwing();
captureDialog(ConfigPdbDialog.class, 410, 280);
}
@Test
public void testLoadPdb_Initial_Screenshot() {
LoadPdbDialog loadPdbDialog = new LoadPdbDialog(program);
showDialogWithoutBlocking(tool, loadPdbDialog);
captureDialog(loadPdbDialog);
pressButtonByText(loadPdbDialog, "Cancel");
}
@Test
public void testSymbolServerConfig_AddButtonMenu() throws IOException {
File localSymbolStore1Root = new File(temporaryDir, "symbols");
LocalSymbolStore.create(localSymbolStore1Root, 1);
LocalSymbolStore localSymbolStore1 = new LocalSymbolStore(localSymbolStore1Root);
SymbolServerService symbolServerService =
new SymbolServerService(localSymbolStore1, List.of());
PdbPlugin.saveSymbolServerServiceConfig(symbolServerService);
ConfigPdbDialog configPdbDialog = new ConfigPdbDialog();
showDialogWithoutBlocking(tool, configPdbDialog);
waitForSwing();
runSwing(() -> {
configPdbDialog.pushAddLocationButton();
});
waitForSwing();
captureMenu();
}
@Test
public void testLoadPdb_Advanced_NeedsConfig() {
PdbPlugin.saveSymbolServerServiceConfig(null);
LoadPdbDialog choosePdbDialog = new LoadPdbDialog(program);
showDialogWithoutBlocking(tool, choosePdbDialog);
waitForSwing();
pressButtonByText(choosePdbDialog, "Advanced >>");
waitForSwing();
captureDialog(LoadPdbDialog.class, 600, 500);
pressButtonByText(choosePdbDialog, "Cancel");
}
@Test
public void testLoadPdb_Advanced_Screenshot() throws IOException {
// Show the advanced side of the LoadPdbDialog, with
// some faked search locations and search results so we
// can have pretty paths
File localSymbolStore1Root = new File(temporaryDir, "symbols");
LocalSymbolStore.create(localSymbolStore1Root, 1);
LocalSymbolStore localSymbolStore1 =
new LocalSymbolStoreWithFakePath(localSymbolStore1Root, "/home/user/symbols");
SameDirSymbolStoreWithFakePath sameDirSymbolStoreWithFakePath =
new SameDirSymbolStoreWithFakePath(temporaryDir, "/home/user/examples");
List<SymbolServer> symbolServers = List.of(sameDirSymbolStoreWithFakePath,
new HttpSymbolServer(URI.create("https://msdl.microsoft.com/download/symbols/")));
SymbolServerService symbolServerService =
new SymbolServerService(localSymbolStore1, symbolServers);
PdbPlugin.saveSymbolServerServiceConfig(symbolServerService);
LoadPdbDialog loadPdbDialog = new LoadPdbDialog(program);
showDialogWithoutBlocking(tool, loadPdbDialog);
waitForSwing();
pressButtonByText(loadPdbDialog, "Advanced >>");
List<SymbolFileLocation> symbolFileLocations = List.of(
new SymbolFileLocation("HelloWorld.pdb/" + GUID1_STR + "1/HelloWorld.pdb",
localSymbolStore1, SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 1)),
new SymbolFileLocation("HelloWorld.pdb/" + GUID1_STR + "2/HelloWorld.pdb",
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);
runSwing(() -> {
loadPdbDialog.setSearchOptions(findOptions);
loadPdbDialog.setSearchResults(symbolFileLocations, findOptions);
loadPdbDialog.selectRowByLocation(symbolFileLocations.get(0));
});
waitForSwing();
captureDialog(LoadPdbDialog.class, 600, 600);
pressButtonByText(loadPdbDialog, "Cancel");
}
private static class LocalSymbolStoreWithFakePath extends LocalSymbolStore {
private String fakeRootDirPath;
public LocalSymbolStoreWithFakePath(File rootDir, String fakeRootDirPath) {
super(rootDir);
this.fakeRootDirPath = fakeRootDirPath;
}
@Override
public String getDescriptiveName() {
return fakeRootDirPath;
}
@Override
public String getFileLocation(String filename) {
return FilenameUtils.concat(fakeRootDirPath, filename);
}
}
private static class SameDirSymbolStoreWithFakePath extends SameDirSymbolStore {
private String fakeRootDirPath;
public SameDirSymbolStoreWithFakePath(File rootDir, String fakeRootDirPath) {
super(rootDir);
this.fakeRootDirPath = fakeRootDirPath;
}
@Override
public String getDescriptiveName() {
return String.format(PROGRAMS_IMPORT_LOCATION_DESCRIPTION_STR + " - %s",
fakeRootDirPath);
}
@Override
public String getFileLocation(String filename) {
return FilenameUtils.concat(fakeRootDirPath, filename);
}
}
}