mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-07-30 07:18:37 -09:00
Merge remote-tracking branch 'origin/GP-6902_Dan_multiLineAssembly--SQUASHED'
This commit is contained in:
@@ -27,7 +27,14 @@
|
||||
Other languages may also be presented if the only thing that varies is the default disassembly
|
||||
context, e.g., configuring ARM will also allow THUMB disassembly.</P>
|
||||
|
||||
<H3><A name="patch_instruction"></A> Patch Instruction / Assemble</H3>
|
||||
<H3><A name="assemble_patch"></A>Assemble</H3>
|
||||
|
||||
<P>This action assembles a block of instructions starting at the cursor. One action is
|
||||
presented per language configured at the current location. Other languages may also be
|
||||
presented if the only thing that varies is the default disassembly context, e.g., configuring
|
||||
ARM will also allow THUMB assembly.</P>
|
||||
|
||||
<H3><A name="patch_instruction"></A> Patch Instruction</H3>
|
||||
|
||||
<P>This action assembles an instruction at the cursor. One action is presented per language
|
||||
configured at the current location. Other languages may also be presented if the only thing
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.plugin.core.assembler.AbstractAssemblePatchDialog;
|
||||
import ghidra.app.plugin.core.assembler.AssemblePatchAction;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
public abstract class AbstractTraceAssemblePatchAction extends AssemblePatchAction {
|
||||
|
||||
public AbstractTraceAssemblePatchAction(DebuggerDisassemblerPlugin plugin, String name) {
|
||||
super(plugin, name);
|
||||
}
|
||||
|
||||
protected abstract TracePlatform getPlatform(TraceProgramView view, Address entry);
|
||||
|
||||
@Override
|
||||
protected AbstractAssemblePatchDialog<?> newDialog(ListingActionContext ctx) {
|
||||
if (!(ctx.getProgram() instanceof TraceProgramView view)) {
|
||||
return null;
|
||||
}
|
||||
Address entry = ctx.getAddress();
|
||||
Instruction ins = view.getListing().getInstructionContaining(entry);
|
||||
RegisterValue initialContext = getInitialContext(ins, view, entry);
|
||||
return new TraceAssemblePatchDialog(plugin.getTool(), ctx.getNavigatable(),
|
||||
getPlatform(view, entry), view, entry, initialContext);
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,31 @@ import ghidra.util.Msg;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public abstract class AbstractTracePatchInstructionAction extends PatchInstructionAction {
|
||||
protected class TraceAssemblyDualTextField extends AssemblyDualTextField {
|
||||
protected class TraceAssemblyDualTextAutocompletionModel
|
||||
extends AssemblyDualTextAutocompletionModel {
|
||||
AssemblyPatternBlock ctx = null;
|
||||
|
||||
@Override
|
||||
protected AssemblyPatternBlock getContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddress(Address address) {
|
||||
super.setAddress(address);
|
||||
RegisterValue rv = getContextValue(getCodeUnit());
|
||||
ctx = rv == null ? AssemblyPatternBlock.nop()
|
||||
: AssemblyPatternBlock.fromRegisterValue(rv).fillMask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AssemblyDualTextAutocompletionModel newAutocompletionModel() {
|
||||
return new TraceAssemblyDualTextAutocompletionModel();
|
||||
}
|
||||
}
|
||||
|
||||
protected final DebuggerDisassemblerPlugin plugin;
|
||||
|
||||
public AbstractTracePatchInstructionAction(DebuggerDisassemblerPlugin plugin, String name) {
|
||||
@@ -57,22 +82,7 @@ public abstract class AbstractTracePatchInstructionAction extends PatchInstructi
|
||||
|
||||
@Override
|
||||
protected AssemblyDualTextField newAssemblyDualTextField() {
|
||||
return new AssemblyDualTextField() {
|
||||
AssemblyPatternBlock ctx = null;
|
||||
|
||||
@Override
|
||||
protected AssemblyPatternBlock getContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddress(Address address) {
|
||||
super.setAddress(address);
|
||||
RegisterValue rv = getContextValue(getCodeUnit());
|
||||
ctx = rv == null ? AssemblyPatternBlock.nop()
|
||||
: AssemblyPatternBlock.fromRegisterValue(rv).fillMask();
|
||||
}
|
||||
};
|
||||
return new TraceAssemblyDualTextField();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,7 +160,14 @@ public abstract class AbstractTracePatchInstructionAction extends PatchInstructi
|
||||
}
|
||||
|
||||
AddressSetView set = new AddressSet(address, address.add(data.length - 1));
|
||||
TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, address, set);
|
||||
TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, address, set) {
|
||||
@Override
|
||||
public boolean applyTo(TraceProgramView view, TaskMonitor monitor) {
|
||||
boolean result = super.applyTo(view, monitor);
|
||||
doGoToNext(data.length);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
if (contextValue != null) {
|
||||
dis.setInitialContext(contextValue);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import docking.ActionContext;
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.listing.TraceInstruction;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
public class CurrentPlatformTraceAssemblePatchAction extends AbstractTraceAssemblePatchAction {
|
||||
|
||||
public CurrentPlatformTraceAssemblePatchAction(DebuggerDisassemblerPlugin plugin) {
|
||||
super(plugin, "Assemble");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isApplicableToContext(ActionContext context) {
|
||||
return super.isApplicableToContext(context) &&
|
||||
context instanceof ListingActionContext lac && lac.getNavigatable().isDynamic();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TracePlatform getPlatform(TraceProgramView view, Address entry) {
|
||||
Instruction ins = view.getListing().getInstructionContaining(entry);
|
||||
if (!(ins instanceof TraceInstruction tins)) { // includes null
|
||||
return view.getTrace().getPlatformManager().getHostPlatform();
|
||||
}
|
||||
return tins.getPlatform();
|
||||
}
|
||||
}
|
||||
@@ -171,6 +171,7 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
|
||||
CurrentPlatformTraceDisassembleAction actionDisassemble;
|
||||
CurrentPlatformTracePatchInstructionAction actionPatchInstruction;
|
||||
TracePatchDataAction actionPatchData;
|
||||
CurrentPlatformTraceAssemblePatchAction actionAssemblePatch;
|
||||
|
||||
public DebuggerDisassemblerPlugin(PluginTool tool) {
|
||||
super(tool);
|
||||
@@ -187,10 +188,12 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
|
||||
actionDisassemble = new CurrentPlatformTraceDisassembleAction(this);
|
||||
actionPatchInstruction = new CurrentPlatformTracePatchInstructionAction(this);
|
||||
actionPatchData = new TracePatchDataAction(this);
|
||||
actionAssemblePatch = new CurrentPlatformTraceAssemblePatchAction(this);
|
||||
|
||||
tool.addAction(actionDisassemble);
|
||||
tool.addAction(actionPatchInstruction);
|
||||
tool.addAction(actionPatchData);
|
||||
tool.addAction(actionAssemblePatch);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,6 +225,7 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
|
||||
for (LanguageID langID : getAlternativeLanguageIDs(platform.getLanguage())) {
|
||||
result.add(new FixedPlatformTraceDisassembleAction(this, langID, platform));
|
||||
result.add(new FixedPlatformTracePatchInstructionAction(this, langID, platform));
|
||||
result.add(new FixedPlatformTraceAssemblePatchAction(this, langID, platform));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.plugin.core.assembler.AbstractPatchAction;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.listing.TraceInstruction;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
public class FixedPlatformTraceAssemblePatchAction extends AbstractTraceAssemblePatchAction {
|
||||
|
||||
private final LanguageID altLangID;
|
||||
private final TracePlatform platform;
|
||||
|
||||
public FixedPlatformTraceAssemblePatchAction(DebuggerDisassemblerPlugin plugin,
|
||||
LanguageID altLangID, TracePlatform platform) {
|
||||
this.altLangID = altLangID;
|
||||
this.platform = platform;
|
||||
super(plugin, "Assemble using " + altLangID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MenuData createMenuData(String name) {
|
||||
MenuData menuData =
|
||||
new MenuData(new String[] { "Assemble using...", altLangID.toString() });
|
||||
menuData.setParentMenuGroup(AbstractPatchAction.MENU_GROUP);
|
||||
return menuData;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TracePlatform getPlatform(TraceProgramView view, Address entry) {
|
||||
return platform;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegisterValue getInitialContext(Instruction ins, Program program, Address entry) {
|
||||
Language language = ins instanceof TraceInstruction tins
|
||||
? tins.getLanguage()
|
||||
: program.getLanguage();
|
||||
return DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext(language, altLangID,
|
||||
entry);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
package ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.plugin.core.assembler.AbstractPatchAction;
|
||||
import ghidra.program.model.lang.LanguageID;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
@@ -26,13 +27,13 @@ public class FixedPlatformTraceDisassembleAction extends AbstractTraceDisassembl
|
||||
|
||||
public FixedPlatformTraceDisassembleAction(DebuggerDisassemblerPlugin plugin,
|
||||
LanguageID altLangID, TracePlatform platform) {
|
||||
super(plugin, "Disassemble Trace as " + altLangID);
|
||||
this.altLangID = altLangID;
|
||||
this.platform = platform;
|
||||
super(plugin, "Disassemble Trace as " + altLangID);
|
||||
|
||||
// TODO: Human-readable description?
|
||||
setPopupMenuData(
|
||||
new MenuData(new String[] { "Disassemble as " + altLangID }, "Disassembly"));
|
||||
MenuData menuData = new MenuData(new String[] { "Disassemble as", altLangID.toString() });
|
||||
menuData.setParentMenuGroup(AbstractPatchAction.MENU_GROUP);
|
||||
setPopupMenuData(menuData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.plugin.core.assembler.AbstractPatchAction;
|
||||
import ghidra.program.model.lang.LanguageID;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
@@ -25,11 +27,18 @@ public class FixedPlatformTracePatchInstructionAction extends AbstractTracePatch
|
||||
|
||||
public FixedPlatformTracePatchInstructionAction(DebuggerDisassemblerPlugin plugin,
|
||||
LanguageID altLangID, TracePlatform platform) {
|
||||
super(plugin, "Patch Instruction using " + altLangID);
|
||||
setKeyBindingData(null);
|
||||
|
||||
this.altLangID = altLangID;
|
||||
this.platform = platform;
|
||||
super(plugin, "Patch Instruction using " + altLangID);
|
||||
setKeyBindingData(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MenuData createMenuData(String name) {
|
||||
MenuData menuData =
|
||||
new MenuData(new String[] { "Patch Instruction using", altLangID.toString() });
|
||||
menuData.setParentMenuGroup(AbstractPatchAction.MENU_GROUP);
|
||||
return menuData;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.plugin.assembler.Assembler;
|
||||
import ghidra.app.plugin.assembler.Assemblers;
|
||||
import ghidra.app.plugin.core.assembler.AbstractAssemblePatchDialog;
|
||||
import ghidra.app.plugin.core.assembler.AbstractPatchAssemblyCommand;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
public class TraceAssemblePatchDialog extends AbstractAssemblePatchDialog<TraceProgramView> {
|
||||
private final TracePlatform platform;
|
||||
|
||||
protected TraceAssemblePatchDialog(PluginTool tool, Navigatable navigatable,
|
||||
TracePlatform platform, TraceProgramView program, Address entry,
|
||||
RegisterValue initialContext) {
|
||||
this.platform = platform;
|
||||
super(tool, navigatable, program, entry, initialContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractPatchAssemblyCommand<TraceProgramView> newPatchCommand(List<String> lines) {
|
||||
return new TracePatchAssemblyCommand(platform, assembler, lines, entry, initialContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Language getLanguage() {
|
||||
return platform.getLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Assembler getAssembler() {
|
||||
return Assemblers.getAssembler(getLanguage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.plugin.core.debug.disassemble;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.plugin.assembler.Assembler;
|
||||
import ghidra.app.plugin.core.assembler.AbstractPatchAssemblyCommand;
|
||||
import ghidra.framework.cmd.Command;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
public class TracePatchAssemblyCommand extends AbstractPatchAssemblyCommand<TraceProgramView> {
|
||||
|
||||
private final TracePlatform platform;
|
||||
|
||||
public TracePatchAssemblyCommand(TracePlatform platform, Assembler asm, List<String> lines,
|
||||
Address entry, RegisterValue initialContext) {
|
||||
this.platform = platform;
|
||||
super(asm, lines, entry, initialContext);
|
||||
}
|
||||
|
||||
public TracePatchAssemblyCommand(TracePlatform platform, Assembler asm, String string,
|
||||
Address entry, RegisterValue initialContext) {
|
||||
this.platform = platform;
|
||||
super(asm, string, entry, initialContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command<TraceProgramView> newDisassembleCommand(AddressSetView set,
|
||||
TraceProgramView program) {
|
||||
TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, entry, set);
|
||||
dis.setInitialContext(initialContext);
|
||||
return dis;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ public class TracePatchDataAction extends PatchDataAction {
|
||||
|
||||
try {
|
||||
editor.setVariable(address, encoded).get(1, TimeUnit.SECONDS);
|
||||
doGoToNext(encoded.length);
|
||||
// Let the trace do everything regarding existing units
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -654,8 +654,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
Language language = asm.getLanguage();
|
||||
Register regCtx = language.getContextBaseRegister();
|
||||
Register regT = language.getRegister("T");
|
||||
RegisterValue rvDefault = new RegisterValue(regCtx,
|
||||
asm.getContextAt(entry).toBigInteger(regCtx.getNumBytes()));
|
||||
RegisterValue rvDefault = asm.getContextAt(entry).toRegisterValue(regCtx);
|
||||
RegisterValue rvThumb = rvDefault.assign(regT, BigInteger.ONE);
|
||||
AssemblyPatternBlock ctxThumb = AssemblyPatternBlock.fromRegisterValue(rvThumb);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user