/* ### * 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. */ /* * Created on Jun 7, 2006 */ package ghidra.app.plugin.core.datapreview; import static org.junit.Assert.*; import org.junit.*; import ghidra.app.events.ProgramActivatedPluginEvent; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin; import ghidra.app.plugin.core.datapreview.DataTypePreviewPlugin.DTPPTableModel; import ghidra.app.services.GoToService; import ghidra.program.database.ProgramBuilder; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.listing.Program; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.TestEnv; public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTest { private TestEnv env; private DataTypePreviewPlugin plugin; @Before public void setUp() throws Exception { env = new TestEnv(); env.getTool().addPlugin(CodeBrowserPlugin.class.getName()); env.getTool().addPlugin(DataTypeManagerPlugin.class.getName()); env.getTool().addPlugin(DataTypePreviewPlugin.class.getName()); plugin = getPlugin(env.getTool(), DataTypePreviewPlugin.class); env.showTool(); runSwing(() -> env.getTool().showComponentProvider(plugin.getProvider(), true)); } @After public void tearDown() throws Exception { env.dispose(); } @Test public void testPreview() throws Exception { DTPPTableModel model = plugin.getTableModel(); GoToService gotoService = plugin.getGoToService(); assertEquals(9, model.getRowCount()); model.add(new ByteDataType()); model.add(new CharDataType()); model.add(new DoubleDataType()); model.add(new QWordDataType()); model.add(new TerminatedUnicodeDataType()); assertEquals(9, model.getRowCount()); Program program = buildProgram(); env.open(program); gotoService.goTo(addr(program, 0x100df26)); assertEquals("54h", model.getValueAt(0, DTPPTableModel.PREVIEW_COL)); assertEquals("\"T\"", model.getValueAt(6, DTPPTableModel.PREVIEW_COL)); assertEquals("20006500680054h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL)); assertEquals( "u\"The Margin values are not correct. Either they are not numeric characters " + "or they don't fit the dimensions of the page. Try either entering a number " + "or decreasing the margins.\",02h,00h,\"&f\\aPage &p\"", model.getValueAt(7, DTPPTableModel.PREVIEW_COL)); gotoService.goTo(addr(program, 0x100e08c)); assertEquals("50h", model.getValueAt(0, DTPPTableModel.PREVIEW_COL)); assertEquals("'P'", model.getValueAt(1, DTPPTableModel.PREVIEW_COL)); assertEquals("9.346009625593543E-307", model.getValueAt(2, DTPPTableModel.PREVIEW_COL)); assertEquals("65006700610050h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL)); assertEquals("u\"Page &p\"", model.getValueAt(7, DTPPTableModel.PREVIEW_COL)); Structure struct = new StructureDataType("TestStruct", 0); struct.add(new FloatDataType(), 4, "FLOAT", null); struct.add(new DoubleDataType(), 5, "DOUBLE", null); struct.add(new WordDataType(), 2, "WORD", null); struct.add(new DWordDataType(), 4, "DWORD", null); struct.add(new StringDataType(), 10, "STRING", null); int id = program.startTransaction("add"); try { struct = (Structure) program.getDataTypeManager().addDataType(struct, DataTypeConflictHandler.REPLACE_HANDLER); } finally { program.endTransaction(id, true); } model.add(struct); assertEquals("8.908155E-39", model.getValueAt(4, DTPPTableModel.PREVIEW_COL)); assertEquals("6.119088925166103E-308", model.getValueAt(9, DTPPTableModel.PREVIEW_COL)); assertEquals("2600h", model.getValueAt(10, DTPPTableModel.PREVIEW_COL)); assertEquals("7000h", model.getValueAt(11, DTPPTableModel.PREVIEW_COL)); assertEquals("\"\\0\\0\\0\\0\\0\\0\\0\",0Eh,\"\\0f\"", model.getValueAt(12, DTPPTableModel.PREVIEW_COL)); assertEquals(14, model.getRowCount()); } private Program buildProgram() throws Exception { ProgramBuilder builder = new ProgramBuilder("notepad", ProgramBuilder._X86); builder.createMemory("test1", "0x0100d000", 0x1000); builder.createMemory("test2", "0x0100e000", 0x1000); // p_unicode "The Margin values are not correct. Either they are not numeric characters // or they don't fit the dimensions of the page. Try either entering a // number or decreasing the margins." builder.setBytes("0x100df24", "af 00 54 00 68 00 65 00 20 00 4d 00 61 00 72 00 " + "67 00 69 00 6e 00 20 00 76 00 61 00 6c 00 75 00 65 00 73 00 20 00 61 00 72 " + "00 65 00 20 00 6e 00 6f 00 74 00 20 00 63 00 6f 00 72 00 72 00 65 00 63 00 " + "74 00 2e 00 20 00 45 00 69 00 74 00 68 00 65 00 72 00 20 00 74 00 68 00 65 " + "00 79 00 20 00 61 00 72 00 65 00 20 00 6e 00 6f 00 74 00 20 00 6e 00 75 00 " + "6d 00 65 00 72 00 69 00 63 00 20 00 63 00 68 00 61 00 72 00 61 00 63 00 74 " + "00 65 00 72 00 73 00 20 00 6f 00 72 00 20 00 74 00 68 00 65 00 79 00 20 00 " + "64 00 6f 00 6e 00 27 00 74 00 20 00 66 00 69 00 74 00 20 00 74 00 68 00 65 " + "00 20 00 64 00 69 00 6d 00 65 00 6e 00 73 00 69 00 6f 00 6e 00 73 00 20 00 " + "6f 00 66 00 20 00 74 00 68 00 65 00 20 00 70 00 61 00 67 00 65 00 2e 00 20 " + "00 54 00 72 00 79 00 20 00 65 00 69 00 74 00 68 00 65 00 72 00 20 00 65 00 " + "6e 00 74 00 65 00 72 00 69 00 6e 00 67 00 20 00 61 00 20 00 6e 00 75 00 6d " + "00 62 00 65 00 72 00 20 00 6f 00 72 00 20 00 64 00 65 00 63 00 72 00 65 00 " + "61 00 73 00 69 00 6e 00 67 00 20 00 74 00 68 00 65 00 20 00 6d 00 61 00 72 " + "00 67 00 69 00 6e 00 73 00 2e 00"); // p_unicode "&f" builder.setBytes("0x0100e084", "02 00 26 00 66 00"); // p_unicode "Page &p" builder.setBytes("0x0100e08a", "07 00 50 00 61 00 67 00 65 00 20 00 26 00 70 00"); builder.setBytes("0x0100e09a", "00 00 00 00 00 00 00 00 0e 00 66 00 46 00 70 00 " + "50 00 74 00 54 00 64 00 44 00 63 00 43 00 72 00 52 00 6c 00 4c 00"); return builder.getProgram(); } @Test public void testPreviewOrgChange() throws Exception { DTPPTableModel model = plugin.getTableModel(); GoToService gotoService = plugin.getGoToService(); model.removeAll(); // Default size specified by DataOrganization // shortSize = 2; // integerSize = 4; // longSize = 4; // defaultAlignment = 1; plugin.addDataType(IntegerDataType.dataType); plugin.addDataType(LongDataType.dataType); plugin.addDataType(ShortDataType.dataType); Structure struct = new StructureDataType("test", 0); struct.setInternallyAligned(true); struct.add(IntegerDataType.dataType, "intField", ""); struct.add(LongDataType.dataType, "longField", ""); struct.add(ShortDataType.dataType, "shortField", ""); plugin.addDataType(struct); assertEquals(6, model.getRowCount()); Program program = buildProgram(); DataOrganizationImpl dataOrganization = (DataOrganizationImpl) program.getDataTypeManager().getDataOrganization(); dataOrganization.setLongSize(8); env.open(program); gotoService.goTo(addr(program, 0x100df26)); // TODO: The below values have not been confirmed, since variation in DataOrganization is not yet supported by this plugin assertEquals("680054h", model.getValueAt(0, DTPPTableModel.PREVIEW_COL));// 4-byte int assertEquals("20006500680054h", model.getValueAt(1, DTPPTableModel.PREVIEW_COL));// 8-byte long assertEquals("54h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 2-byte short assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 4-byte int at offset 0 assertEquals("61004D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 8-byte long at offset 4 assertEquals("72h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 12 // deactivate program plugin.getTool().firePluginEvent(new ProgramActivatedPluginEvent("Test", null)); waitForPostedSwingRunnables(); // NOTE: Altering data organization on-the-fly is not supported dataOrganization.setDefaultAlignment(2); dataOrganization.setShortSize(3); dataOrganization.setIntegerSize(3); dataOrganization.setLongSize(6); // activate program plugin.getTool().firePluginEvent(new ProgramActivatedPluginEvent("Test", program)); waitForPostedSwingRunnables(); gotoService.goTo(addr(program, 0x100df26)); assertEquals("680054h", model.getValueAt(0, DTPPTableModel.PREVIEW_COL));// 3-byte int assertEquals("6500680054h", model.getValueAt(1, DTPPTableModel.PREVIEW_COL));// 6-byte long assertEquals("680054h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 3-byte short assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 3-byte int at offset 0 assertEquals("4D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 6-byte long at offset 4 assertEquals("720061h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 3-byte short at offset 10 } private Address addr(Program prog, long offset) { return prog.getAddressFactory().getDefaultAddressSpace().getAddress(offset); } }