mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-16 23:50:14 +00:00
GP-1288: more visible clues
This commit is contained in:
parent
cd1b5f6592
commit
9c3084ccee
@ -114,6 +114,20 @@ public interface DebugControl extends DebugControlReentrant {
|
||||
;
|
||||
}
|
||||
|
||||
public static enum DebugFilterOrdinals {
|
||||
DEBUG_FILTER_CREATE_THREAD, //
|
||||
DEBUG_FILTER_EXIT_THREAD, //
|
||||
DEBUG_FILTER_CREATE_PROCESS, //
|
||||
DEBUG_FILTER_EXIT_PROCESS, //
|
||||
DEBUG_FILTER_LOAD_MODULE, //
|
||||
DEBUG_FILTER_UNLOAD_MODULE, //
|
||||
DEBUG_FILTER_SYSTEM_ERROR, //
|
||||
DEBUG_FILTER_INITIAL_BREAKPOINT, //
|
||||
DEBUG_FILTER_INITIAL_MODULE_LOAD, //
|
||||
DEBUG_FILTER_DEBUGGEE_OUTPUT, //
|
||||
;
|
||||
}
|
||||
|
||||
public static enum DebugFilterExecutionOption {
|
||||
DEBUG_FILTER_BREAK(0, "Break"), //
|
||||
DEBUG_FILTER_SECOND_CHANCE_BREAK(1, "Second-chance Break"), //
|
||||
|
@ -17,6 +17,8 @@ package agent.dbgeng.manager;
|
||||
|
||||
public interface DbgEventFilter {
|
||||
|
||||
int getIndex();
|
||||
|
||||
String getName();
|
||||
|
||||
String getCmd();
|
||||
|
@ -17,6 +17,7 @@ package agent.dbgeng.manager;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||
|
||||
public interface DbgEventsListener {
|
||||
|
||||
@ -123,6 +124,14 @@ public interface DbgEventsListener {
|
||||
*/
|
||||
void threadSelected(DbgThread thread, DbgStackFrame frame, DbgCause cause);
|
||||
|
||||
/**
|
||||
* A system event has occurred (gained focus)
|
||||
*
|
||||
* @param event a handle to the current event
|
||||
* @param cause the cause of this event
|
||||
*/
|
||||
void eventSelected(AbstractDbgEvent<?> event, DbgCause cause);
|
||||
|
||||
/**
|
||||
* A module has been loaded by an process
|
||||
*
|
||||
|
@ -17,6 +17,7 @@ package agent.dbgeng.manager;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||
|
||||
public interface DbgEventsListenerAdapter extends DbgEventsListener {
|
||||
|
||||
@ -82,6 +83,11 @@ public interface DbgEventsListenerAdapter extends DbgEventsListener {
|
||||
// Extension point
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
|
||||
// Extension point
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void moduleLoaded(DbgProcess process, DebugModuleInfo info, DbgCause cause) {
|
||||
// Extension point
|
||||
|
@ -48,8 +48,9 @@ public class DbgListEventFiltersCommand
|
||||
String text = control.getEventFilterText(i);
|
||||
String cmd = control.getEventFilterCommand(i);
|
||||
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(i);
|
||||
DbgEventFilterImpl f = new DbgEventFilterImpl(text, cmd, p.ExecutionOption.intValue(),
|
||||
p.ContinueOption.intValue());
|
||||
DbgEventFilterImpl f =
|
||||
new DbgEventFilterImpl(i, text, cmd, p.ExecutionOption.intValue(),
|
||||
p.ContinueOption.intValue());
|
||||
result.add(f);
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class DbgListExceptionFiltersCommand
|
||||
String text = control.getEventFilterText(nEvents + i);
|
||||
String cmd = control.getEventFilterCommand(nEvents + i);
|
||||
String cmd2 = control.getExceptionFilterSecondCommand(nEvents + i);
|
||||
DbgExceptionFilterImpl filter = new DbgExceptionFilterImpl(text, cmd, cmd2,
|
||||
DbgExceptionFilterImpl filter = new DbgExceptionFilterImpl(i, text, cmd, cmd2,
|
||||
p.ExecutionOption.intValue(), p.ContinueOption.intValue(),
|
||||
p.ExceptionCode.longValue());
|
||||
result.add(filter);
|
||||
|
@ -0,0 +1,60 @@
|
||||
/* ###
|
||||
* 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 agent.dbgeng.manager.cmd;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.ULONG;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_EXCEPTION_FILTER_PARAMETERS;
|
||||
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_SPECIFIC_FILTER_PARAMETERS;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
|
||||
public class DbgToggleContinuationCommand
|
||||
extends AbstractDbgCommand<Void> {
|
||||
|
||||
private int index;
|
||||
private DebugFilterContinuationOption optionCont;
|
||||
|
||||
public DbgToggleContinuationCommand(DbgManagerImpl manager, int index,
|
||||
DebugFilterContinuationOption optionCont) {
|
||||
super(manager);
|
||||
this.index = index;
|
||||
this.optionCont = optionCont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke() {
|
||||
DebugControl control = manager.getControl();
|
||||
DebugFilterInformation info = control.getNumberEventFilters();
|
||||
int nEvents = info.getNumberEvents();
|
||||
int nExcs = info.getNumberSpecificExceptions();
|
||||
if (index < nEvents) {
|
||||
DebugSpecificFilterInformation exc =
|
||||
control.getSpecificFilterParameters(0, nEvents);
|
||||
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||
p.ContinueOption = new ULONG(optionCont.ordinal());
|
||||
control.setSpecificFilterParameters(0, nEvents, exc);
|
||||
}
|
||||
else {
|
||||
DebugExceptionFilterInformation exc =
|
||||
control.getExceptionFilterParameters(nEvents, null, nExcs);
|
||||
DEBUG_EXCEPTION_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||
p.ContinueOption = new ULONG(optionCont.ordinal());
|
||||
control.setExceptionFilterParameters(nExcs, exc);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/* ###
|
||||
* 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 agent.dbgeng.manager.cmd;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.ULONG;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_EXCEPTION_FILTER_PARAMETERS;
|
||||
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_SPECIFIC_FILTER_PARAMETERS;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
|
||||
public class DbgToggleExecutionCommand
|
||||
extends AbstractDbgCommand<Void> {
|
||||
|
||||
private int index;
|
||||
private DebugFilterExecutionOption optionCont;
|
||||
|
||||
public DbgToggleExecutionCommand(DbgManagerImpl manager, int index,
|
||||
DebugFilterExecutionOption optionCont) {
|
||||
super(manager);
|
||||
this.index = index;
|
||||
this.optionCont = optionCont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke() {
|
||||
DebugControl control = manager.getControl();
|
||||
DebugFilterInformation info = control.getNumberEventFilters();
|
||||
int nEvents = info.getNumberEvents();
|
||||
int nExcs = info.getNumberSpecificExceptions();
|
||||
if (index < nEvents) {
|
||||
DebugSpecificFilterInformation exc =
|
||||
control.getSpecificFilterParameters(0, nEvents);
|
||||
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||
p.ExecutionOption = new ULONG(optionCont.ordinal());
|
||||
control.setSpecificFilterParameters(0, nEvents, exc);
|
||||
}
|
||||
else {
|
||||
DebugExceptionFilterInformation exc =
|
||||
control.getExceptionFilterParameters(nEvents, null, nExcs);
|
||||
DEBUG_EXCEPTION_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||
p.ExecutionOption = new ULONG(optionCont.ordinal());
|
||||
control.setExceptionFilterParameters(nExcs, exc);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,18 +18,27 @@ package agent.dbgeng.manager.impl;
|
||||
import agent.dbgeng.manager.DbgEventFilter;
|
||||
|
||||
public class DbgEventFilterImpl implements DbgEventFilter {
|
||||
|
||||
protected int index;
|
||||
protected final String text;
|
||||
protected final String cmd;
|
||||
protected int executionOption;
|
||||
protected int continueOption;
|
||||
|
||||
public DbgEventFilterImpl(String text, String cmd, int executionOption, int continueOption) {
|
||||
public DbgEventFilterImpl(int index, String text, String cmd, int executionOption,
|
||||
int continueOption) {
|
||||
this.index = index;
|
||||
this.text = text;
|
||||
this.cmd = cmd;
|
||||
this.setExecutionOption(executionOption);
|
||||
this.setContinueOption(continueOption);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return text;
|
||||
|
@ -22,9 +22,10 @@ public class DbgExceptionFilterImpl extends DbgEventFilterImpl implements DbgExc
|
||||
private final String cmd2;
|
||||
private long exceptionCode;
|
||||
|
||||
public DbgExceptionFilterImpl(String text, String cmd, String cmd2, int executionOption,
|
||||
public DbgExceptionFilterImpl(int index, String text, String cmd, String cmd2,
|
||||
int executionOption,
|
||||
int continueOption, long exceptionCode) {
|
||||
super(text, cmd, executionOption, continueOption);
|
||||
super(index, text, cmd, executionOption, continueOption);
|
||||
this.cmd2 = cmd2;
|
||||
this.exceptionCode = exceptionCode;
|
||||
}
|
||||
|
@ -685,6 +685,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
*/
|
||||
protected DebugStatus processException(DbgExceptionEvent evt, Void v) {
|
||||
DebugThreadId eventId = updateState();
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadSelected(eventThread, null, evt.getCause());
|
||||
|
||||
DebugExceptionRecord64 info = evt.getInfo();
|
||||
@ -710,6 +711,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
DbgProcessImpl process = getCurrentProcess();
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
||||
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||
|
||||
@ -735,6 +737,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
thread.remove();
|
||||
}
|
||||
process.threadExited(eventId);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
@ -783,6 +786,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
//so.setCurrentProcessId(id);
|
||||
int pid = so.getCurrentProcessSystemId();
|
||||
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.processAdded(proc, evt.getCause());
|
||||
getEventListeners().fire.processSelected(proc, evt.getCause());
|
||||
|
||||
@ -815,8 +819,9 @@ public class DbgManagerImpl implements DbgManager {
|
||||
DbgThreadImpl thread = getCurrentThread();
|
||||
DbgProcessImpl process = getCurrentProcess();
|
||||
process.setExitCode(Long.valueOf(evt.getInfo()));
|
||||
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
||||
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
||||
getEventListeners().fire.processExited(process, evt.getCause());
|
||||
|
||||
for (DebugBreakpoint bpt : getBreakpoints()) {
|
||||
@ -867,6 +872,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
DbgProcessImpl process = getCurrentProcess();
|
||||
DebugModuleInfo info = evt.getInfo();
|
||||
process.moduleLoaded(info);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.moduleLoaded(process, info, evt.getCause());
|
||||
|
||||
String key = info.getModuleName();
|
||||
@ -888,6 +894,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
DbgProcessImpl process = getCurrentProcess();
|
||||
DebugModuleInfo info = evt.getInfo();
|
||||
process.moduleUnloaded(info);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.moduleUnloaded(process, info, evt.getCause());
|
||||
|
||||
String key = info.getModuleName();
|
||||
|
@ -42,4 +42,6 @@ public abstract class AbstractDbgModel extends AbstractDebuggerObjectModel {
|
||||
|
||||
public abstract TargetObject getModelObject(Object object);
|
||||
|
||||
public abstract void deleteModelObject(Object object);
|
||||
|
||||
}
|
||||
|
@ -15,15 +15,18 @@
|
||||
*/
|
||||
package agent.dbgeng.model.iface2;
|
||||
|
||||
import agent.dbgeng.manager.DbgEventFilter;
|
||||
import agent.dbgeng.manager.*;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||
import agent.dbgeng.model.iface1.DbgModelSelectableObject;
|
||||
|
||||
public interface DbgModelTargetEvent extends DbgModelTargetObject {
|
||||
|
||||
@Override
|
||||
public default String getDisplay() {
|
||||
return getName();
|
||||
}
|
||||
public interface DbgModelTargetEvent extends DbgModelSelectableObject, DbgEventsListenerAdapter //
|
||||
{
|
||||
|
||||
public DbgEventFilter getFilter();
|
||||
|
||||
public int getEventIndex();
|
||||
|
||||
@Override
|
||||
void eventSelected(AbstractDbgEvent<?> event, DbgCause cause);
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,4 @@ import ghidra.dbg.target.TargetTogglable;
|
||||
|
||||
public interface DbgModelTargetEventOption extends DbgModelTargetObject, TargetTogglable {
|
||||
|
||||
@Override
|
||||
public default String getDisplay() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,12 +17,7 @@ package agent.dbgeng.model.iface2;
|
||||
|
||||
import agent.dbgeng.manager.DbgExceptionFilter;
|
||||
|
||||
public interface DbgModelTargetException extends DbgModelTargetObject {
|
||||
|
||||
@Override
|
||||
public default String getDisplay() {
|
||||
return getName();
|
||||
}
|
||||
public interface DbgModelTargetException extends DbgModelTargetEvent {
|
||||
|
||||
public DbgExceptionFilter getFilter();
|
||||
|
||||
|
@ -164,6 +164,7 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode
|
||||
return objectMap.get(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteModelObject(Object object) {
|
||||
objectMap.remove(object);
|
||||
}
|
||||
|
@ -20,75 +20,66 @@ import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||
import agent.dbgeng.manager.cmd.DbgToggleContinuationCommand;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
|
||||
@TargetObjectSchemaInfo(
|
||||
name = "Event",
|
||||
name = "ContinuationFilter",
|
||||
elements = {
|
||||
@TargetElementType(type = Void.class) },
|
||||
attributes = {
|
||||
@TargetAttributeType(type = Object.class) })
|
||||
public class DbgModelTargetEventOptionImpl extends DbgModelTargetObjectImpl
|
||||
public class DbgModelTargetContinuationOptionImpl extends DbgModelTargetObjectImpl
|
||||
implements DbgModelTargetEventOption {
|
||||
|
||||
protected static String keyFilter(DebugFilterExecutionOption option) {
|
||||
return PathUtils.makeKey(option.description);
|
||||
}
|
||||
|
||||
protected static String keyFilter(DebugFilterContinuationOption option) {
|
||||
return PathUtils.makeKey(option.description);
|
||||
}
|
||||
|
||||
private DebugFilterExecutionOption optionEx;
|
||||
private DbgModelTargetEvent event;
|
||||
private DebugFilterContinuationOption optionCont;
|
||||
|
||||
public DbgModelTargetEventOptionImpl(DbgModelTargetEvent event,
|
||||
DebugFilterExecutionOption option) {
|
||||
super(event.getModel(), event, keyFilter(option), "EventFilter");
|
||||
public DbgModelTargetContinuationOptionImpl(DbgModelTargetEvent event,
|
||||
DebugFilterContinuationOption option) {
|
||||
super(event.getModel(), event, "Continue", "ContinuationFilter");
|
||||
this.getModel().addModelObject(option, this);
|
||||
this.optionEx = option;
|
||||
this.event = event;
|
||||
this.optionCont = option;
|
||||
setAttributes();
|
||||
}
|
||||
|
||||
public DbgModelTargetEventOptionImpl(DbgModelTargetEvent event,
|
||||
public DbgModelTargetContinuationOptionImpl(DbgModelTargetException exc,
|
||||
DebugFilterContinuationOption option) {
|
||||
super(event.getModel(), event, keyFilter(option), "EventFilter");
|
||||
this.getModel().addModelObject(option, this);
|
||||
this.optionCont = option;
|
||||
}
|
||||
|
||||
public DbgModelTargetEventOptionImpl(DbgModelTargetException exc,
|
||||
DebugFilterExecutionOption option) {
|
||||
super(exc.getModel(), exc, keyFilter(option), "EventFilter");
|
||||
this.getModel().addModelObject(option, this);
|
||||
this.optionEx = option;
|
||||
}
|
||||
|
||||
public DbgModelTargetEventOptionImpl(DbgModelTargetException exc,
|
||||
DebugFilterContinuationOption option) {
|
||||
super(exc.getModel(), exc, keyFilter(option), "EventFilter");
|
||||
super(exc.getModel(), exc, "Continue", "ContinuationFilter");
|
||||
this.event = exc;
|
||||
this.getModel().addModelObject(option, this);
|
||||
this.optionCont = option;
|
||||
setAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> disable() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
DbgManagerImpl manager = getManager();
|
||||
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_NOT_HANDLED;
|
||||
setAttributes();
|
||||
return manager.execute(
|
||||
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> enable() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
DbgManagerImpl manager = getManager();
|
||||
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED;
|
||||
setAttributes();
|
||||
return manager.execute(
|
||||
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
|
||||
}
|
||||
|
||||
public void setAttributes() {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
DISPLAY_ATTRIBUTE_NAME, getName() //
|
||||
), "Initialized");
|
||||
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionCont.description, //
|
||||
VALUE_ATTRIBUTE_NAME, optionCont, //
|
||||
ENABLED_ATTRIBUTE_NAME,
|
||||
optionCont.equals(DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED)),
|
||||
"Refreshed");
|
||||
}
|
||||
|
||||
}
|
@ -18,9 +18,10 @@ package agent.dbgeng.model.impl;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||
import agent.dbgeng.dbgeng.DebugControl.*;
|
||||
import agent.dbgeng.manager.DbgCause;
|
||||
import agent.dbgeng.manager.DbgEventFilter;
|
||||
import agent.dbgeng.manager.evt.*;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
@ -55,8 +56,8 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
|
||||
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
|
||||
DebugFilterContinuationOption cont =
|
||||
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
|
||||
execOption = new DbgModelTargetEventOptionImpl(this, exec);
|
||||
contOption = new DbgModelTargetEventOptionImpl(this, cont);
|
||||
execOption = new DbgModelTargetExecutionOptionImpl(this, exec);
|
||||
contOption = new DbgModelTargetContinuationOptionImpl(this, cont);
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
|
||||
@ -64,6 +65,8 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
|
||||
"Execute", execOption, //
|
||||
"Continue", contOption //
|
||||
), "Initialized");
|
||||
|
||||
getManager().addEventsListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,4 +74,44 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEventIndex() {
|
||||
return filter.getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, false), "Refreshed");
|
||||
if (event instanceof DbgThreadCreatedEvent &&
|
||||
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_CREATE_THREAD.ordinal()) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
if (event instanceof DbgThreadExitedEvent &&
|
||||
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_EXIT_THREAD.ordinal()) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
if (event instanceof DbgProcessCreatedEvent &&
|
||||
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_CREATE_PROCESS.ordinal()) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
if (event instanceof DbgProcessExitedEvent &&
|
||||
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_EXIT_PROCESS.ordinal()) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
if (event instanceof DbgModuleLoadedEvent &&
|
||||
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_LOAD_MODULE.ordinal()) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
if (event instanceof DbgModuleUnloadedEvent &&
|
||||
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_UNLOAD_MODULE.ordinal()) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,14 @@ import java.util.Map;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||
import agent.dbgeng.dbgeng.DebugExceptionRecord64;
|
||||
import agent.dbgeng.manager.DbgCause;
|
||||
import agent.dbgeng.manager.DbgExceptionFilter;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||
import agent.dbgeng.manager.evt.DbgExceptionEvent;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetFocusScope;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.dbg.target.TargetFocusScope;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
|
||||
@ -56,8 +62,8 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
|
||||
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
|
||||
DebugFilterContinuationOption cont =
|
||||
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
|
||||
execOption = new DbgModelTargetEventOptionImpl(this, exec);
|
||||
contOption = new DbgModelTargetEventOptionImpl(this, cont);
|
||||
execOption = new DbgModelTargetExecutionOptionImpl(this, exec);
|
||||
contOption = new DbgModelTargetContinuationOptionImpl(this, cont);
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
|
||||
@ -67,6 +73,8 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
|
||||
"Continue", contOption, //
|
||||
"Exception", filter.getExceptionCode() //
|
||||
), "Initialized");
|
||||
|
||||
getManager().addEventsListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,4 +82,23 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEventIndex() {
|
||||
return filter.getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, false), "Refreshed");
|
||||
if (event instanceof DbgExceptionEvent) {
|
||||
DebugExceptionRecord64 info = (DebugExceptionRecord64) event.getInfo();
|
||||
if (info.code == Long.parseLong(filter.getExceptionCode(), 16)) {
|
||||
((DbgModelTargetFocusScope) searchForSuitable(TargetFocusScope.class))
|
||||
.setFocus(this);
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
/* ###
|
||||
* 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 agent.dbgeng.model.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||
import agent.dbgeng.manager.cmd.DbgToggleExecutionCommand;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
|
||||
@TargetObjectSchemaInfo(
|
||||
name = "ExecutionFilter",
|
||||
elements = {
|
||||
@TargetElementType(type = Void.class) },
|
||||
attributes = {
|
||||
@TargetAttributeType(type = Object.class) })
|
||||
public class DbgModelTargetExecutionOptionImpl extends DbgModelTargetObjectImpl
|
||||
implements DbgModelTargetEventOption {
|
||||
|
||||
private DbgModelTargetEvent event;
|
||||
private DebugFilterExecutionOption optionExc;
|
||||
|
||||
public DbgModelTargetExecutionOptionImpl(DbgModelTargetEvent event,
|
||||
DebugFilterExecutionOption option) {
|
||||
super(event.getModel(), event, "Execute", "ExecutionFilter");
|
||||
this.event = event;
|
||||
this.getModel().addModelObject(option, this);
|
||||
this.optionExc = option;
|
||||
setAttributes();
|
||||
}
|
||||
|
||||
public DbgModelTargetExecutionOptionImpl(DbgModelTargetException exc,
|
||||
DebugFilterExecutionOption option) {
|
||||
super(exc.getModel(), exc, "Execute", "ExecutionFilter");
|
||||
this.event = exc;
|
||||
this.getModel().addModelObject(option, this);
|
||||
this.optionExc = option;
|
||||
setAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> disable() {
|
||||
return enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> enable() {
|
||||
DbgManagerImpl manager = getManager();
|
||||
int ordinal = (optionExc.ordinal() + 1) % (DebugFilterExecutionOption.values().length - 1);
|
||||
optionExc = DebugFilterExecutionOption.getByNumber(ordinal);
|
||||
setAttributes();
|
||||
return manager.execute(
|
||||
new DbgToggleExecutionCommand(manager, event.getEventIndex(), optionExc));
|
||||
}
|
||||
|
||||
public void setAttributes() {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionExc.description, //
|
||||
VALUE_ATTRIBUTE_NAME, optionExc, //
|
||||
ENABLED_ATTRIBUTE_NAME,
|
||||
optionExc.equals(DebugFilterExecutionOption.DEBUG_FILTER_BREAK)), "Refreshed");
|
||||
}
|
||||
|
||||
}
|
@ -182,6 +182,11 @@ public class DbgModel2Impl extends AbstractDbgModel
|
||||
return objectMap.get(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteModelObject(Object object) {
|
||||
objectMap.remove(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> CompletableFuture<T> gateFuture(CompletableFuture<T> future) {
|
||||
return super.gateFuture(future).exceptionally(ex -> {
|
||||
|
@ -1210,6 +1210,22 @@ public interface DebuggerResources {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractToggleAction extends DockingAction {
|
||||
public static final String NAME = "Toggle";
|
||||
public static final Icon ICON = ICON_BREAKPOINT_MIXED_ED_MARKER;
|
||||
public static final String HELP_ANCHOR = "toggle_option";
|
||||
|
||||
public static HelpLocation help(Plugin owner) {
|
||||
return new HelpLocation(owner.getName(), HELP_ANCHOR);
|
||||
}
|
||||
|
||||
public AbstractToggleAction(Plugin owner) {
|
||||
super(NAME, owner.getName());
|
||||
setDescription("Enable or disable an option");
|
||||
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface MapIdenticallyAction {
|
||||
String NAME = "Map Identically";
|
||||
String DESCRIPTION =
|
||||
|
@ -1148,43 +1148,43 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||
groupTargetIndex++;
|
||||
|
||||
new ActionBuilder("Finish", plugin.getName())
|
||||
.keyBinding("F12")
|
||||
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.toolBarIcon(AbstractStepFinishAction.ICON)
|
||||
.popupMenuPath("&Finish")
|
||||
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.popupMenuIcon(AbstractStepFinishAction.ICON)
|
||||
.helpLocation(AbstractStepFinishAction.help(plugin))
|
||||
//.withContext(ObjectActionContext.class)
|
||||
.enabledWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.popupWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.onAction(ctx -> performStepFinish(ctx))
|
||||
.enabled(false)
|
||||
.buildAndInstallLocal(this);
|
||||
.keyBinding("F12")
|
||||
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.toolBarIcon(AbstractStepFinishAction.ICON)
|
||||
.popupMenuPath("&Finish")
|
||||
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.popupMenuIcon(AbstractStepFinishAction.ICON)
|
||||
.helpLocation(AbstractStepFinishAction.help(plugin))
|
||||
//.withContext(ObjectActionContext.class)
|
||||
.enabledWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.popupWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.onAction(ctx -> performStepFinish(ctx))
|
||||
.enabled(false)
|
||||
.buildAndInstallLocal(this);
|
||||
|
||||
groupTargetIndex++;
|
||||
|
||||
new ActionBuilder("Step Last", plugin.getName())
|
||||
.keyBinding("ALT F8")
|
||||
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.toolBarIcon(AbstractStepLastAction.ICON)
|
||||
.popupMenuPath("&Step Last")
|
||||
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.popupMenuIcon(AbstractStepLastAction.ICON)
|
||||
.helpLocation(AbstractStepLastAction.help(plugin))
|
||||
//.withContext(ObjectActionContext.class)
|
||||
.enabledWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.popupWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.onAction(ctx -> performStepLast(ctx))
|
||||
.enabled(false)
|
||||
.buildAndInstallLocal(this);
|
||||
|
||||
groupTargetIndex++;
|
||||
|
||||
groupTargetIndex++;
|
||||
|
||||
new ActionBuilder("Step Last", plugin.getName())
|
||||
.keyBinding("ALT F8")
|
||||
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.toolBarIcon(AbstractStepLastAction.ICON)
|
||||
.popupMenuPath("&Step Last")
|
||||
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
.popupMenuIcon(AbstractStepLastAction.ICON)
|
||||
.helpLocation(AbstractStepLastAction.help(plugin))
|
||||
//.withContext(ObjectActionContext.class)
|
||||
.enabledWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.popupWhen(ctx ->
|
||||
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
|
||||
.onAction(ctx -> performStepLast(ctx))
|
||||
.enabled(false)
|
||||
.buildAndInstallLocal(this);
|
||||
|
||||
groupTargetIndex++;
|
||||
|
||||
actionAddBreakpoint = new ActionBuilder("Add Breakpoint", plugin.getName())
|
||||
.keyBinding("F3")
|
||||
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
|
||||
@ -1221,6 +1221,20 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||
|
||||
groupTargetIndex++;
|
||||
|
||||
new ActionBuilder("Toggle", plugin.getName())
|
||||
.keyBinding("T")
|
||||
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
|
||||
.popupMenuPath("&Toggle")
|
||||
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
|
||||
.helpLocation(AbstractToggleAction.help(plugin))
|
||||
.enabledWhen(ctx -> isInstance(ctx, TargetTogglable.class))
|
||||
.popupWhen(ctx -> isInstance(ctx, TargetResumable.class))
|
||||
.onAction(ctx -> performToggle(ctx))
|
||||
.enabled(false)
|
||||
.buildAndInstallLocal(this);
|
||||
|
||||
groupTargetIndex++;
|
||||
|
||||
displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this);
|
||||
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
|
||||
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
|
||||
@ -1486,6 +1500,12 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||
}, "Couldn't set breakpoint");
|
||||
}
|
||||
|
||||
public void performToggle(ActionContext context) {
|
||||
performAction(context, false, TargetTogglable.class, t -> {
|
||||
return t.toggle(!t.isEnabled());
|
||||
}, "Couldn't toggle");
|
||||
}
|
||||
|
||||
public void initiateConsole(ActionContext context) {
|
||||
performAction(context, false, TargetInterpreter.class, interpreter -> {
|
||||
getPlugin().showConsole(interpreter);
|
||||
|
Loading…
Reference in New Issue
Block a user