mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-28 14:55:33 +08:00
Merge remote-tracking branch 'origin/GP-6123_Dan_fixtTaintRegColumn'
This commit is contained in:
+28
-19
@@ -35,6 +35,7 @@ import docking.*;
|
|||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
import docking.action.builder.ActionBuilder;
|
import docking.action.builder.ActionBuilder;
|
||||||
import docking.actions.PopupActionProvider;
|
import docking.actions.PopupActionProvider;
|
||||||
|
import docking.widgets.AbstractGCellRenderer;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.ColumnSortState.SortDirection;
|
import docking.widgets.table.ColumnSortState.SortDirection;
|
||||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
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> {
|
static class RegisterValueCellRenderer extends HexDefaultGColumnRenderer<BigInteger> {
|
||||||
@Override
|
@Override
|
||||||
public final Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
public final Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||||
super.getTableCellRendererComponent(data);
|
super.getTableCellRendererComponent(data);
|
||||||
setFont(getFixedWidthFont());
|
applyStateColors(this, data, RegisterRow::isChanged);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1055,7 +1060,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||||||
if (previous.getThread() == null || current.getThread() == null) {
|
if (previous.getThread() == null || current.getThread() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (previous.getPlatform().getLanguage() != current.getPlatform().getLanguage()) {
|
if (previous.getLanguage() != current.getLanguage()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!isRegisterKnown(register)) {
|
if (!isRegisterKnown(register)) {
|
||||||
@@ -1328,6 +1333,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DebuggerCoordinates getPrevious() {
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
private void reportError(String title, String message, Throwable ex) {
|
private void reportError(String title, String message, Throwable ex) {
|
||||||
plugin.getTool().setStatusInfo(message + ": " + ex.getMessage());
|
plugin.getTool().setStatusInfo(message + ": " + ex.getMessage());
|
||||||
if (title != null) {
|
if (title != null) {
|
||||||
|
|||||||
+11
-2
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -211,4 +211,13 @@ public class RegisterRow {
|
|||||||
public DebuggerCoordinates getCurrent() {
|
public DebuggerCoordinates getCurrent() {
|
||||||
return provider.getCurrent();
|
return provider.getCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the table's previous coordinates (for change indication)
|
||||||
|
*
|
||||||
|
* @return the coordinates
|
||||||
|
*/
|
||||||
|
public DebuggerCoordinates getPrevious() {
|
||||||
|
return provider.getPrevious();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+120
-57
@@ -15,20 +15,22 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.taint.gui.field;
|
package ghidra.taint.gui.field;
|
||||||
|
|
||||||
import docking.widgets.table.AbstractDynamicTableColumn;
|
import java.awt.Component;
|
||||||
import docking.widgets.table.DynamicTableColumn;
|
import java.util.Objects;
|
||||||
import ghidra.app.plugin.core.debug.gui.register.DebuggerRegisterColumnFactory;
|
|
||||||
import ghidra.app.plugin.core.debug.gui.register.RegisterRow;
|
import docking.widgets.table.*;
|
||||||
|
import ghidra.app.plugin.core.debug.gui.register.*;
|
||||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.pcode.emu.taint.state.TaintPieceHandler;
|
import ghidra.pcode.emu.taint.state.TaintPieceHandler;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.Register;
|
||||||
import ghidra.trace.model.Trace;
|
|
||||||
import ghidra.trace.model.property.TracePropertyMap;
|
import ghidra.trace.model.property.TracePropertyMap;
|
||||||
import ghidra.trace.model.property.TracePropertyMapSpace;
|
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
|
* A factory for the "Taint" column in the "Registers" panel
|
||||||
@@ -38,60 +40,121 @@ import ghidra.trace.model.property.TracePropertyMapSpace;
|
|||||||
* screen.
|
* screen.
|
||||||
*/
|
*/
|
||||||
public class TaintDebuggerRegisterColumnFactory implements DebuggerRegisterColumnFactory {
|
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;
|
protected static final String PROP_NAME = TaintPieceHandler.NAME;
|
||||||
public static final String COL_NAME = "Taint";
|
public static final String COL_NAME = "Taint";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DynamicTableColumn<RegisterRow, ?, ?> create() {
|
public DynamicTableColumn<RegisterRow, ?, ?> create() {
|
||||||
return new AbstractDynamicTableColumn<RegisterRow, String, Void>() {
|
return new TaintDebuggerRegisterColumn();
|
||||||
@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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user