mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GT-3570_adamopolous_scalar_search_issue'
This commit is contained in:
commit
534fd5253a
3 changed files with 92 additions and 79 deletions
|
@ -19,29 +19,15 @@ import java.awt.Component;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.*;
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.SwingConstants;
|
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
|
|
||||||
import docking.widgets.table.AbstractDynamicTableColumn;
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.DiscoverableTableUtils;
|
|
||||||
import docking.widgets.table.GTableCellRenderingData;
|
|
||||||
import docking.widgets.table.TableColumnDescriptor;
|
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.address.AddressRange;
|
|
||||||
import ghidra.program.model.address.AddressRangeIterator;
|
|
||||||
import ghidra.program.model.address.AddressSet;
|
|
||||||
import ghidra.program.model.data.Resource;
|
import ghidra.program.model.data.Resource;
|
||||||
import ghidra.program.model.listing.CodeUnit;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.listing.Data;
|
|
||||||
import ghidra.program.model.listing.DataIterator;
|
|
||||||
import ghidra.program.model.listing.Instruction;
|
|
||||||
import ghidra.program.model.listing.InstructionIterator;
|
|
||||||
import ghidra.program.model.listing.Listing;
|
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
import ghidra.program.model.symbol.Reference;
|
import ghidra.program.model.symbol.Reference;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
|
@ -52,10 +38,7 @@ import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.table.AddressBasedTableModel;
|
import ghidra.util.table.AddressBasedTableModel;
|
||||||
import ghidra.util.table.column.AbstractGColumnRenderer;
|
import ghidra.util.table.column.AbstractGColumnRenderer;
|
||||||
import ghidra.util.table.column.GColumnRenderer;
|
import ghidra.util.table.column.GColumnRenderer;
|
||||||
import ghidra.util.table.field.AddressTableColumn;
|
import ghidra.util.table.field.*;
|
||||||
import ghidra.util.table.field.FunctionNameTableColumn;
|
|
||||||
import ghidra.util.table.field.PreviewTableColumn;
|
|
||||||
import ghidra.util.table.field.ProgramLocationTableColumn;
|
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,12 +217,8 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Scalar scalar = rowObject.getScalar();
|
Scalar scalar = rowObject.getScalar();
|
||||||
long value = scalar.getSignedValue();
|
long value = scalar.isSigned() ? scalar.getSignedValue() : scalar.getUnsignedValue();
|
||||||
if (value < minValue) {
|
if ((value < minValue) || (value > maxValue)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value > maxValue) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,22 +15,22 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.scalartable;
|
package ghidra.app.plugin.core.scalartable;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.table.constraint.*;
|
|
||||||
import docking.widgets.table.constraint.provider.LongEditorProvider;
|
|
||||||
import generic.test.category.NightlyCategory;
|
import generic.test.category.NightlyCategory;
|
||||||
import ghidra.app.cmd.data.CreateDataCmd;
|
import ghidra.app.cmd.data.CreateDataCmd;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||||
import ghidra.base.widgets.table.constraint.provider.ScalarToLongColumnTypeMapper;
|
|
||||||
import ghidra.framework.cmd.Command;
|
import ghidra.framework.cmd.Command;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
|
@ -39,7 +39,6 @@ import ghidra.program.model.address.AddressSet;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.lang.LanguageID;
|
import ghidra.program.model.lang.LanguageID;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.TestEnv;
|
import ghidra.test.TestEnv;
|
||||||
import ghidra.util.exception.RollbackException;
|
import ghidra.util.exception.RollbackException;
|
||||||
|
@ -74,8 +73,6 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
private static final String NESTED_STRUCTURE_DATA_ADDRESS = "00400000";
|
private static final String NESTED_STRUCTURE_DATA_ADDRESS = "00400000";
|
||||||
|
|
||||||
private static final int HEX_COLUMN = ScalarSearchModel.HEX_COLUMN;
|
|
||||||
|
|
||||||
private int nestedStructureLength;
|
private int nestedStructureLength;
|
||||||
|
|
||||||
private Program program;
|
private Program program;
|
||||||
|
@ -86,8 +83,8 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
private ScalarSearchProvider provider;
|
private ScalarSearchProvider provider;
|
||||||
private DataTypeManager dataTypeManager;
|
private DataTypeManager dataTypeManager;
|
||||||
|
|
||||||
private int maxScalarVal;
|
private long maxScalarVal;
|
||||||
private int minScalarVal;
|
private long minScalarVal;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
@ -96,7 +93,7 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
program = buildProgram();
|
program = buildProgram();
|
||||||
|
|
||||||
int defaultPointerSize = program.getDefaultPointerSize();
|
int defaultPointerSize = program.getDefaultPointerSize();
|
||||||
maxScalarVal = (int) Math.pow(2, (defaultPointerSize * 8));
|
maxScalarVal = (long) Math.pow(2, (defaultPointerSize * 8) + 1);
|
||||||
minScalarVal = -maxScalarVal;
|
minScalarVal = -maxScalarVal;
|
||||||
|
|
||||||
dataTypeManager = program.getDataTypeManager();
|
dataTypeManager = program.getDataTypeManager();
|
||||||
|
@ -250,6 +247,74 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertNestedScalarsInTable(p);
|
assertNestedScalarsInTable(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that a signed scalar can be found using its decimal
|
||||||
|
* value.
|
||||||
|
* <p>
|
||||||
|
* The instruction being targeted is at <b>00401090</b>:
|
||||||
|
* <code>SUB ESP,-0x34</code>
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchSpecificSignedScalarDecimal() throws Exception {
|
||||||
|
searchProgramAndDisplayResults(program, null, -52, -52);
|
||||||
|
List<ScalarRowObject> results = getTableData();
|
||||||
|
assertTrue(results.size() == 1);
|
||||||
|
assertAllRowsEqualTo(-52);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that a signed scalar can be found using its hex
|
||||||
|
* value.
|
||||||
|
* <p>
|
||||||
|
* The instruction being targeted is at <b>00401090</b>:
|
||||||
|
* <code>SUB ESP,-0x34</code>
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchSpecificSignedScalarHex() throws Exception {
|
||||||
|
searchProgramAndDisplayResults(program, null, -0x34, -0x34);
|
||||||
|
List<ScalarRowObject> results = getTableData();
|
||||||
|
assertTrue(results.size() == 1);
|
||||||
|
assertAllRowsEqualTo(-0x34);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that an unsigned scalar can be found using its decimal
|
||||||
|
* value.
|
||||||
|
* <p>
|
||||||
|
* The instruction being targeted is at <b>004010a0</b>:
|
||||||
|
* <code>MOV EAX,0xcc</code>
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchSpecificUnsignedScalarDecimal() throws Exception {
|
||||||
|
searchProgramAndDisplayResults(program, null, 204, 204);
|
||||||
|
List<ScalarRowObject> results = getTableData();
|
||||||
|
assertTrue(results.size() == 1);
|
||||||
|
assertAllRowsEqualTo(204);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that an unsigned scalar can be found using its hex
|
||||||
|
* value.
|
||||||
|
* <p>
|
||||||
|
* The instruction being targeted is at <b>004010a0</b>:
|
||||||
|
* <code>MOV EAX,0xcc</code>
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchSpecificUnsignedScalarHex() throws Exception {
|
||||||
|
searchProgramAndDisplayResults(program, null, 0xcc, 0xcc);
|
||||||
|
List<ScalarRowObject> results = getTableData();
|
||||||
|
assertTrue(results.size() == 1);
|
||||||
|
assertAllRowsEqualTo(0xcc);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertAllRowsEqualTo(int value) {
|
private void assertAllRowsEqualTo(int value) {
|
||||||
|
|
||||||
ScalarSearchModel model = provider.getScalarModel();
|
ScalarSearchModel model = provider.getScalarModel();
|
||||||
|
@ -294,7 +359,6 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAllRowsLessThan(int value) {
|
private void assertAllRowsLessThan(int value) {
|
||||||
|
|
||||||
ScalarSearchModel model = provider.getScalarModel();
|
ScalarSearchModel model = provider.getScalarModel();
|
||||||
waitForTableModel(model);
|
waitForTableModel(model);
|
||||||
|
|
||||||
|
@ -464,43 +528,6 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
runSwing(() -> field.setValue(value));
|
runSwing(() -> field.setValue(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This is for when we move to the column-based filtering mechanism, removing the filter fields
|
|
||||||
private void setFilterValues_Future(int min, int max) {
|
|
||||||
|
|
||||||
GTableFilterPanel<ScalarRowObject> panel = provider.getFilterPanel();
|
|
||||||
ColumnBasedTableFilter<ScalarRowObject> filter =
|
|
||||||
new ColumnBasedTableFilter<>(panel.getTableFilterModel());
|
|
||||||
|
|
||||||
filter.addConstraintSet(LogicOperation.AND, HEX_COLUMN, atLeast(min));
|
|
||||||
filter.addConstraintSet(LogicOperation.AND, HEX_COLUMN, atMost(max));
|
|
||||||
|
|
||||||
runSwing(() -> panel.setColumnTableFilter(filter));
|
|
||||||
waitForTableModel(provider.getScalarModel());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private List<ColumnConstraint<Scalar>> atLeast(long value) {
|
|
||||||
|
|
||||||
ScalarToLongColumnTypeMapper mapper = new ScalarToLongColumnTypeMapper();
|
|
||||||
AtLeastColumnConstraint<Long> delegate =
|
|
||||||
new AtLeastColumnConstraint<>(value, new LongEditorProvider());
|
|
||||||
MappedColumnConstraint<Scalar, Long> constraint =
|
|
||||||
new MappedColumnConstraint<>(mapper, delegate);
|
|
||||||
return Arrays.asList(constraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ColumnConstraint<Scalar>> atMost(long value) {
|
|
||||||
|
|
||||||
ScalarToLongColumnTypeMapper mapper = new ScalarToLongColumnTypeMapper();
|
|
||||||
AtMostColumnConstraint<Long> delegate =
|
|
||||||
new AtMostColumnConstraint<>(value, new LongEditorProvider());
|
|
||||||
MappedColumnConstraint<Scalar, Long> constraint =
|
|
||||||
new MappedColumnConstraint<>(mapper, delegate);
|
|
||||||
return Arrays.asList(constraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function that will build a testing program given a test file
|
* Function that will build a testing program given a test file
|
||||||
* The function will initialize the program builder and then call
|
* The function will initialize the program builder and then call
|
||||||
|
@ -530,6 +557,10 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
"A_virt2@401120", 16);
|
"A_virt2@401120", 16);
|
||||||
createFunction(builder, "00401130", "55 8b ec 51 89 4d fc b8 08 00 00 00 8b e5 5d c3",
|
createFunction(builder, "00401130", "55 8b ec 51 89 4d fc b8 08 00 00 00 8b e5 5d c3",
|
||||||
"B_virt2@401130", 16);
|
"B_virt2@401130", 16);
|
||||||
|
createFunction(builder, "00401140", "48 83 ec cc",
|
||||||
|
"C_virt2@401140", 4);
|
||||||
|
createFunction(builder, "00401150", "55 8b ec 51 89 4d fc b8 cc 00 00 00 8b e5 5d c3",
|
||||||
|
"C_virt2@401150", 16);
|
||||||
|
|
||||||
createBytes(builder, COMPOSITE_DATA_ADDRESS,
|
createBytes(builder, COMPOSITE_DATA_ADDRESS,
|
||||||
"0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 " +
|
"0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 " +
|
||||||
|
@ -625,7 +656,7 @@ public class ScalarSearchTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private void searchProgramAndDisplayResults(Program customProgram, AddressSet selection,
|
private void searchProgramAndDisplayResults(Program customProgram, AddressSet selection,
|
||||||
int min, int max) throws Exception {
|
long min, long max) throws Exception {
|
||||||
|
|
||||||
ScalarSearchDialog dialog = launchScalarSearchDialog(customProgram, selection);
|
ScalarSearchDialog dialog = launchScalarSearchDialog(customProgram, selection);
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,10 @@ public class Scalar implements Comparable<Scalar> {
|
||||||
* Get the value as unsigned.
|
* Get the value as unsigned.
|
||||||
*/
|
*/
|
||||||
public long getUnsignedValue() {
|
public long getUnsignedValue() {
|
||||||
return value;
|
if (value == 0) { // just in case the bitLength is 0
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (value & BITMASKS[bitLength]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue