mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-02-06 05:52:45 +08:00
Merge remote-tracking branch 'origin/GP-6123_Dan_fixtTaintRegColumn'
This commit is contained in:
@@ -35,6 +35,7 @@ import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.actions.PopupActionProvider;
|
||||
import docking.widgets.AbstractGCellRenderer;
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.ColumnSortState.SortDirection;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||
@@ -411,28 +412,32 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
|
||||
public static void applyStateColors(AbstractGCellRenderer renderer,
|
||||
GTableCellRenderingData data, Predicate<RegisterRow> isChanged) {
|
||||
RegisterRow row = (RegisterRow) data.getRowObject();
|
||||
if (!row.isKnown()) {
|
||||
if (data.isSelected()) {
|
||||
renderer.setForeground(COLOR_FOREGROUND_STALE_SEL);
|
||||
}
|
||||
else {
|
||||
renderer.setForeground(COLOR_FOREGROUND_STALE);
|
||||
}
|
||||
}
|
||||
else if (isChanged.test(row)) {
|
||||
if (data.isSelected()) {
|
||||
renderer.setForeground(COLOR_FOREGROUND_CHANGED_SEL);
|
||||
}
|
||||
else {
|
||||
renderer.setForeground(COLOR_FOREGROUND_CHANGED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class RegisterValueCellRenderer extends HexDefaultGColumnRenderer<BigInteger> {
|
||||
@Override
|
||||
public final Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
super.getTableCellRendererComponent(data);
|
||||
setFont(getFixedWidthFont());
|
||||
RegisterRow row = (RegisterRow) data.getRowObject();
|
||||
if (!row.isKnown()) {
|
||||
if (data.isSelected()) {
|
||||
setForeground(COLOR_FOREGROUND_STALE_SEL);
|
||||
}
|
||||
else {
|
||||
setForeground(COLOR_FOREGROUND_STALE);
|
||||
}
|
||||
}
|
||||
else if (row.isChanged()) {
|
||||
if (data.isSelected()) {
|
||||
setForeground(COLOR_FOREGROUND_CHANGED_SEL);
|
||||
}
|
||||
else {
|
||||
setForeground(COLOR_FOREGROUND_CHANGED);
|
||||
}
|
||||
}
|
||||
applyStateColors(this, data, RegisterRow::isChanged);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1055,7 +1060,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
if (previous.getThread() == null || current.getThread() == null) {
|
||||
return false;
|
||||
}
|
||||
if (previous.getPlatform().getLanguage() != current.getPlatform().getLanguage()) {
|
||||
if (previous.getLanguage() != current.getLanguage()) {
|
||||
return false;
|
||||
}
|
||||
if (!isRegisterKnown(register)) {
|
||||
@@ -1328,6 +1333,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
return current;
|
||||
}
|
||||
|
||||
public DebuggerCoordinates getPrevious() {
|
||||
return previous;
|
||||
}
|
||||
|
||||
private void reportError(String title, String message, Throwable ex) {
|
||||
plugin.getTool().setStatusInfo(message + ": " + ex.getMessage());
|
||||
if (title != null) {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -211,4 +211,13 @@ public class RegisterRow {
|
||||
public DebuggerCoordinates getCurrent() {
|
||||
return provider.getCurrent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table's previous coordinates (for change indication)
|
||||
*
|
||||
* @return the coordinates
|
||||
*/
|
||||
public DebuggerCoordinates getPrevious() {
|
||||
return provider.getPrevious();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,20 +15,22 @@
|
||||
*/
|
||||
package ghidra.taint.gui.field;
|
||||
|
||||
import docking.widgets.table.AbstractDynamicTableColumn;
|
||||
import docking.widgets.table.DynamicTableColumn;
|
||||
import ghidra.app.plugin.core.debug.gui.register.DebuggerRegisterColumnFactory;
|
||||
import ghidra.app.plugin.core.debug.gui.register.RegisterRow;
|
||||
import java.awt.Component;
|
||||
import java.util.Objects;
|
||||
|
||||
import docking.widgets.table.*;
|
||||
import ghidra.app.plugin.core.debug.gui.register.*;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.pcode.emu.taint.state.TaintPieceHandler;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.property.TracePropertyMap;
|
||||
import ghidra.trace.model.property.TracePropertyMapSpace;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.util.table.column.AbstractGColumnRenderer;
|
||||
import ghidra.util.table.column.GColumnRenderer;
|
||||
|
||||
/**
|
||||
* A factory for the "Taint" column in the "Registers" panel
|
||||
@@ -38,60 +40,121 @@ import ghidra.trace.model.property.TracePropertyMapSpace;
|
||||
* screen.
|
||||
*/
|
||||
public class TaintDebuggerRegisterColumnFactory implements DebuggerRegisterColumnFactory {
|
||||
private static TracePropertyMapSpace<String> getTaintSpace(DebuggerCoordinates coords,
|
||||
Register register) {
|
||||
TracePropertyMap<String> taintMap =
|
||||
coords.getTrace().getAddressPropertyManager().getPropertyMap(PROP_NAME, String.class);
|
||||
|
||||
if (taintMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AddressSpace addressSpace = register.getAddressSpace();
|
||||
if (addressSpace.isRegisterSpace()) {
|
||||
return taintMap.getPropertyMapRegisterSpace(coords.getThread(),
|
||||
coords.getFrame(), false);
|
||||
}
|
||||
return taintMap.getPropertyMapSpace(addressSpace, false);
|
||||
}
|
||||
|
||||
private static String getTaintValue(DebuggerCoordinates coords,
|
||||
TracePropertyMapSpace<String> taintSpace, Register register) {
|
||||
// Cheat the deserialization/reserialization here
|
||||
AddressRange range = coords.getPlatform()
|
||||
.getConventionalRegisterRange(taintSpace.getAddressSpace(), register);
|
||||
StringBuffer vec = new StringBuffer();
|
||||
for (Address addr : range) {
|
||||
vec.append('[');
|
||||
String taint = taintSpace.get(coords.getViewSnap(), addr);
|
||||
vec.append(taint == null ? "" : taint);
|
||||
vec.append(']');
|
||||
}
|
||||
return vec.toString();
|
||||
}
|
||||
|
||||
private static String getTaintValue(DebuggerCoordinates coords, RegisterRow row) {
|
||||
TraceThread thread = coords.getThread();
|
||||
if (thread == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Register register = row.getRegister();
|
||||
TracePropertyMapSpace<String> taintSpace = getTaintSpace(coords, register);
|
||||
if (taintSpace == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getTaintValue(coords, taintSpace, register);
|
||||
}
|
||||
|
||||
private static class TaintDebuggerRegisterCellRenderer extends AbstractGColumnRenderer<String> {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
super.getTableCellRendererComponent(data);
|
||||
DebuggerRegistersProvider.applyStateColors(this, data, this::isChanged);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilterString(String t, Settings settings) {
|
||||
return t;
|
||||
}
|
||||
|
||||
private boolean isChanged(RegisterRow row) {
|
||||
if (row.getPrevious().getThread() == null || row.getCurrent().getThread() == null) {
|
||||
return false;
|
||||
}
|
||||
if (row.getPrevious().getLanguage() != row.getCurrent().getLanguage()) {
|
||||
return false;
|
||||
}
|
||||
if (!row.isKnown()) {
|
||||
return false;
|
||||
}
|
||||
Register register = row.getRegister();
|
||||
TracePropertyMapSpace<String> curTaintSpace =
|
||||
getTaintSpace(row.getCurrent(), register);
|
||||
if (curTaintSpace == null) {
|
||||
return false; // unlikely
|
||||
}
|
||||
TracePropertyMapSpace<String> prevTaintSpace =
|
||||
getTaintSpace(row.getPrevious(), register);
|
||||
if (prevTaintSpace == null) {
|
||||
return false;
|
||||
}
|
||||
String curTaintValue = getTaintValue(row.getCurrent(), curTaintSpace, register);
|
||||
String prevTaintValue = getTaintValue(row.getPrevious(), prevTaintSpace, register);
|
||||
return !Objects.equals(curTaintValue, prevTaintValue);
|
||||
}
|
||||
}
|
||||
|
||||
private static final TaintDebuggerRegisterCellRenderer RENDERER =
|
||||
new TaintDebuggerRegisterCellRenderer();
|
||||
|
||||
private static class TaintDebuggerRegisterColumn
|
||||
extends AbstractDynamicTableColumn<RegisterRow, String, Void> {
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
return COL_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GColumnRenderer<String> getColumnRenderer() {
|
||||
return RENDERER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(RegisterRow rowObject, Settings settings, Void dataSource,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
String value = getTaintValue(rowObject.getCurrent(), rowObject);
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
}
|
||||
|
||||
protected static final String PROP_NAME = TaintPieceHandler.NAME;
|
||||
public static final String COL_NAME = "Taint";
|
||||
|
||||
@Override
|
||||
public DynamicTableColumn<RegisterRow, ?, ?> create() {
|
||||
return new AbstractDynamicTableColumn<RegisterRow, String, Void>() {
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
return COL_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(RegisterRow rowObject, Settings settings, Void dataSource,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
DebuggerCoordinates current = rowObject.getCurrent();
|
||||
Trace trace = current.getTrace();
|
||||
if (trace == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
TracePropertyMap<String> taintMap = current.getTrace()
|
||||
.getAddressPropertyManager()
|
||||
.getPropertyMap(PROP_NAME, String.class);
|
||||
|
||||
if (taintMap == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Register register = rowObject.getRegister();
|
||||
TracePropertyMapSpace<String> taintSpace;
|
||||
AddressSpace addressSpace = register.getAddressSpace();
|
||||
if (addressSpace.isRegisterSpace()) {
|
||||
taintSpace = taintMap.getPropertyMapRegisterSpace(current.getThread(),
|
||||
current.getFrame(), false);
|
||||
}
|
||||
else {
|
||||
taintSpace = taintMap.getPropertyMapSpace(addressSpace, false);
|
||||
}
|
||||
if (taintSpace == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Cheat the deserialization/reserialization here
|
||||
StringBuffer vec = new StringBuffer();
|
||||
int count = register.getNumBytes();
|
||||
Address start = register.getAddress();
|
||||
for (int i = 0; i < count; i++) {
|
||||
vec.append('[');
|
||||
String taint = taintSpace.get(current.getViewSnap(), start.addWrap(i));
|
||||
vec.append(taint == null ? "" : taint);
|
||||
vec.append(']');
|
||||
}
|
||||
return vec.toString();
|
||||
}
|
||||
};
|
||||
return new TaintDebuggerRegisterColumn();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user