GP-2628 Add 'Search|For Encoded Strings'

This commit is contained in:
dev747368
2023-11-30 18:14:29 -05:00
parent 5fd01c739d
commit c91e9aac3f
41 changed files with 3716 additions and 72 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}