mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-2628 Add 'Search|For Encoded Strings'
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
/* ###
|
||||
* 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.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ghidra.app.plugin.core.strings.EncodedStringsDialog;
|
||||
import ghidra.app.plugin.core.strings.EncodedStringsPlugin;
|
||||
import ghidra.app.services.ProgramManager;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.test.ToyProgramBuilder;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
public class EncodedStringsDialogScreenShots extends GhidraScreenShotGenerator {
|
||||
|
||||
private EncodedStringsPlugin plugin;
|
||||
|
||||
public EncodedStringsDialogScreenShots() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
plugin = env.addPlugin(EncodedStringsPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadProgram() throws Exception {
|
||||
|
||||
ToyProgramBuilder builder = new ToyProgramBuilder("String Examples", false);
|
||||
builder.createMemory("RAM", "0x0", 0x2000);
|
||||
|
||||
builder.createString("0x100", "Hello World!\n", StandardCharsets.US_ASCII, true, null);
|
||||
|
||||
builder.createString("0x150", bytes(0, 1, 2, 3, 4, 0x80, 0x81, 0x82, 0x83),
|
||||
StandardCharsets.US_ASCII, null);
|
||||
|
||||
builder.createString("0x200", "\u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54",
|
||||
StandardCharsets.UTF_16, true, null);
|
||||
|
||||
builder.createString("0x250", "Exception %s\n\tline: %d\n", StandardCharsets.US_ASCII, true,
|
||||
null);
|
||||
|
||||
builder.createString("0x330", "A: \u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54",
|
||||
StandardCharsets.UTF_8, true, null);
|
||||
|
||||
builder.createString("0x450",
|
||||
"Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue",
|
||||
StandardCharsets.US_ASCII, true, null);
|
||||
|
||||
program = builder.getProgram();
|
||||
|
||||
runSwing(() -> {
|
||||
ProgramManager pm = tool.getService(ProgramManager.class);
|
||||
pm.openProgram(program.getDomainFile());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHelpTopicName() {
|
||||
return HelpTopics.SEARCH;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedStringsDialog_initial() {
|
||||
positionListingTop(0x50);
|
||||
makeSelection(0x50, 0x500);
|
||||
performAction(plugin.getSearchForEncodedStringsAction());
|
||||
|
||||
EncodedStringsDialog dialog = waitForDialogComponent(EncodedStringsDialog.class);
|
||||
waitForTableModel(dialog.getStringModel());
|
||||
|
||||
captureDialog(600, 300);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedStringsDialog_advancedoptions() {
|
||||
positionListingTop(0x50);
|
||||
makeSelection(0x50, 0x500);
|
||||
performAction(plugin.getSearchForEncodedStringsAction());
|
||||
|
||||
EncodedStringsDialog dialog = waitForDialogComponent(EncodedStringsDialog.class);
|
||||
Swing.runNow(() -> {
|
||||
dialog.setShowAdvancedOptions(true);
|
||||
dialog.setShowScriptOptions(true);
|
||||
dialog.setAllowAnyScriptOption(true);
|
||||
dialog.setRequireValidStringOption(false);
|
||||
dialog.setSelectedCharset("UTF-8");
|
||||
});
|
||||
waitForTableModel(dialog.getStringModel());
|
||||
|
||||
captureDialog(600, 450);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.plugin.core.strings;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.Character.UnicodeScript;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.action.DockingActionIf;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.AbstractStringDataType;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.test.*;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
public class EncodedStringsDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
private TestEnv env;
|
||||
private ProgramDB program;
|
||||
private PluginTool tool;
|
||||
private MemoryBlock ram;
|
||||
private DockingActionIf encodedStringsAction;
|
||||
private EncodedStringsDialog dialog;
|
||||
private EncodedStringsTableModel tableModel;
|
||||
private EncodedStringsPlugin plugin;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
env = new TestEnv();
|
||||
program = buildProgram();
|
||||
ram = program.getMemory().getBlock("RAM");
|
||||
tool = env.launchDefaultTool(program);
|
||||
plugin = env.addPlugin(EncodedStringsPlugin.class);
|
||||
encodedStringsAction = plugin.getSearchForEncodedStringsAction();
|
||||
}
|
||||
|
||||
private ProgramDB buildProgram() throws Exception {
|
||||
ToyProgramBuilder builder = new ToyProgramBuilder("String Examples", false);
|
||||
builder.createMemory("RAM", "0x0", 0x500);
|
||||
|
||||
builder.createString("0x100", "Hello World!\n", StandardCharsets.US_ASCII, true, null);
|
||||
builder.createString("0x10e", "Next string", StandardCharsets.US_ASCII, true, null);
|
||||
|
||||
builder.createString("0x150", bytes(0, 1, 2, 3, 4, 0x80, 0x81, 0x82, 0x83),
|
||||
StandardCharsets.US_ASCII, null);
|
||||
|
||||
builder.createString("0x200", "\u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54",
|
||||
StandardCharsets.UTF_16, true, null);
|
||||
|
||||
builder.createString("0x250", "Exception %s\n\tline: %d\n", StandardCharsets.US_ASCII, true,
|
||||
null);
|
||||
|
||||
builder.createString("0x330", "A: \u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54",
|
||||
StandardCharsets.UTF_8, true, null);
|
||||
|
||||
builder.createString("0x450",
|
||||
"Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue",
|
||||
StandardCharsets.US_ASCII, true, null);
|
||||
|
||||
return builder.getProgram();
|
||||
}
|
||||
|
||||
private Address addr(long offset) {
|
||||
return ram.getStart().getNewAddress(offset);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
closeDialog();
|
||||
env.dispose();
|
||||
}
|
||||
|
||||
private void closeDialog() {
|
||||
if (dialog != null) {
|
||||
close(dialog);
|
||||
dialog = null;
|
||||
tableModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void showDialog(AddressRange range) {
|
||||
closeDialog();
|
||||
makeSelection(tool, program, range.getMinAddress(), range.getMaxAddress());
|
||||
performAction(encodedStringsAction, false);
|
||||
dialog = waitForDialogComponent(EncodedStringsDialog.class);
|
||||
tableModel = dialog.getStringModel();
|
||||
waitForTableModel(tableModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultUSASCII() {
|
||||
showDialog(ram.getAddressRange());
|
||||
assertEquals(3, tableModel.getRowCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleString() {
|
||||
showDialog(new AddressRangeImpl(addr(0x100), addr(0x100)));
|
||||
assertEquals(1, tableModel.getRowCount());
|
||||
EncodedStringsRow row0 = tableModel.getRowObject(0);
|
||||
assertEquals("Hello World!\n", row0.stringInfo().stringValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTF8() {
|
||||
showDialog(ram.getAddressRange());
|
||||
Swing.runNow(() -> {
|
||||
dialog.setSelectedCharset("UTF-8");
|
||||
});
|
||||
waitForTableModel(tableModel);
|
||||
assertEquals(4, tableModel.getRowCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTF8_Nonstdctrlchars() {
|
||||
showDialog(ram.getAddressRange());
|
||||
Swing.runNow(() -> {
|
||||
dialog.setShowAdvancedOptions(true);
|
||||
dialog.setExcludeNonStdCtrlChars(false);
|
||||
dialog.setSelectedCharset("UTF-8");
|
||||
});
|
||||
waitForTableModel(tableModel);
|
||||
assertEquals(5, tableModel.getRowCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTF8_HanScript() {
|
||||
showDialog(ram.getAddressRange());
|
||||
Swing.runNow(() -> {
|
||||
dialog.setShowAdvancedOptions(true);
|
||||
dialog.setRequireValidStringOption(false);
|
||||
dialog.setSelectedCharset("UTF-8");
|
||||
});
|
||||
waitForTableModel(tableModel);
|
||||
assertEquals(4, tableModel.getRowCount());
|
||||
Swing.runNow(() -> {
|
||||
dialog.setShowScriptOptions(true);
|
||||
dialog.setShowAdvancedOptions(true);
|
||||
dialog.setRequireValidStringOption(false);
|
||||
dialog.setAllowAnyScriptOption(false);
|
||||
dialog.setAllowLatinScriptOption(true);
|
||||
dialog.setAllowCommonScriptOption(true);
|
||||
dialog.setRequiredScript(UnicodeScript.HAN);
|
||||
});
|
||||
waitForTableModel(tableModel);
|
||||
assertEquals(1, tableModel.getRowCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateString() {
|
||||
Data data = program.getListing().getDataAt(addr(0x100));
|
||||
assertFalse(data.isDefined());
|
||||
|
||||
showDialog(ram.getAddressRange());
|
||||
assertEquals(3, tableModel.getRowCount());
|
||||
dialog.getCreateButton().doClick();
|
||||
|
||||
waitForSwing();
|
||||
|
||||
data = program.getListing().getDataAt(addr(0x100));
|
||||
assertNotNull(data);
|
||||
assertTrue(data.getDataType() instanceof AbstractStringDataType);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user