mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Isolate variable action
This commit is contained in:
parent
c0dfa509ee
commit
b0fb7b287d
4 changed files with 121 additions and 3 deletions
|
@ -70,6 +70,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
|
|||
private DockingAction lockLocalAction;
|
||||
private DockingAction renameVarAction;
|
||||
private DockingAction retypeVarAction;
|
||||
private DockingAction isolateVarAction;
|
||||
private DockingAction specifyCProtoAction;
|
||||
private DockingAction overrideSigAction;
|
||||
private DockingAction deleteSigAction;
|
||||
|
@ -778,6 +779,9 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
|
|||
retypeVarAction = new RetypeVariableAction(tool, controller);
|
||||
setGroupInfo(retypeVarAction, variableGroup, subGroupPosition++);
|
||||
|
||||
isolateVarAction = new IsolateVariableAction(tool, controller);
|
||||
setGroupInfo(isolateVarAction, variableGroup, subGroupPosition++);
|
||||
|
||||
decompilerCreateStructureAction =
|
||||
new DecompilerStructureVariableAction(owner, tool, controller);
|
||||
setGroupInfo(decompilerCreateStructureAction, variableGroup, subGroupPosition++);
|
||||
|
@ -907,6 +911,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
|
|||
addLocalAction(removeSecondaryHighlightAction);
|
||||
addLocalAction(removeAllSecondadryHighlightsAction);
|
||||
addLocalAction(retypeVarAction);
|
||||
addLocalAction(isolateVarAction);
|
||||
addLocalAction(decompilerCreateStructureAction);
|
||||
tool.addAction(listingCreateStructureAction);
|
||||
addLocalAction(editDataTypeAction);
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/* ###
|
||||
* 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.decompile.actions;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.decompiler.ClangToken;
|
||||
import ghidra.app.decompiler.component.DecompilerController;
|
||||
import ghidra.app.decompiler.component.DecompilerPanel;
|
||||
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.pcode.*;
|
||||
import ghidra.util.UndefinedFunction;
|
||||
|
||||
public class IsolateVariableAction extends RetypeVariableAction {
|
||||
|
||||
public IsolateVariableAction(PluginTool tool, DecompilerController controller) {
|
||||
super("New Isolated Variable", tool, controller);
|
||||
setPopupMenuData(new MenuData(new String[] { "New Isolated Variable" }, "Decompile"));
|
||||
// setKeyBindingData(new KeyBindingData(KeyEvent.VK_L, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
|
||||
Function function = controller.getFunction();
|
||||
if (function instanceof UndefinedFunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DecompilerPanel decompilerPanel = controller.getDecompilerPanel();
|
||||
ClangToken tokenAtCursor = decompilerPanel.getTokenAtCursor();
|
||||
if (tokenAtCursor == null) {
|
||||
return false;
|
||||
}
|
||||
HighVariable variable = tokenAtCursor.getHighVariable();
|
||||
if (!(variable instanceof HighLocal)) {
|
||||
return false;
|
||||
}
|
||||
HighSymbol highSymbol = variable.getSymbol();
|
||||
if (highSymbol == null) {
|
||||
return false;
|
||||
}
|
||||
if (highSymbol.isIsolated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Varnode vn = tokenAtCursor.getVarnode();
|
||||
if (vn == null) {
|
||||
return false;
|
||||
}
|
||||
short mergeGroup = vn.getMergeGroup();
|
||||
boolean mergeSplit = false;
|
||||
for (Varnode var : variable.getInstances()) {
|
||||
if (var.getMergeGroup() != mergeGroup) {
|
||||
mergeSplit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mergeSplit) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decompilerActionPerformed(DecompilerActionContext context) {
|
||||
DecompilerPanel decompilerPanel = controller.getDecompilerPanel();
|
||||
final ClangToken tokenAtCursor = decompilerPanel.getTokenAtCursor();
|
||||
HighVariable variable = tokenAtCursor.getHighVariable();
|
||||
HighSymbol highSymbol = variable.getSymbol();
|
||||
highSymbol.setTypeLock(true);
|
||||
retypeSymbol(highSymbol, tokenAtCursor.getVarnode(), highSymbol.getDataType());
|
||||
}
|
||||
|
||||
}
|
|
@ -38,9 +38,15 @@ import ghidra.util.data.DataTypeParser.AllowedDataTypes;
|
|||
import ghidra.util.exception.*;
|
||||
|
||||
public class RetypeVariableAction extends AbstractDecompilerAction {
|
||||
private final DecompilerController controller;
|
||||
protected final DecompilerController controller;
|
||||
private final PluginTool tool;
|
||||
|
||||
protected RetypeVariableAction(String name, PluginTool tool, DecompilerController controller) {
|
||||
super(name);
|
||||
this.tool = tool;
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
public RetypeVariableAction(PluginTool tool, DecompilerController controller) {
|
||||
super("Retype Variable");
|
||||
this.tool = tool;
|
||||
|
@ -124,7 +130,7 @@ public class RetypeVariableAction extends AbstractDecompilerAction {
|
|||
return chooserDialog.getUserChosenDataType();
|
||||
}
|
||||
|
||||
private void retypeSymbol(HighSymbol highSymbol, Varnode exactSpot, DataType dt) {
|
||||
protected void retypeSymbol(HighSymbol highSymbol, Varnode exactSpot, DataType dt) {
|
||||
HighFunction hfunction = highSymbol.getHighFunction();
|
||||
|
||||
boolean commitRequired = checkFullCommit(highSymbol, hfunction);
|
||||
|
|
|
@ -262,6 +262,16 @@ public class HighSymbol {
|
|||
return namelock;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this returns true, the decompiler will not speculatively merge this with
|
||||
* other variables.
|
||||
* Currently, being isolated is equivalent to being typelocked.
|
||||
* @return true if this will not be merged with other variables
|
||||
*/
|
||||
public boolean isIsolated() {
|
||||
return typelock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the symbol's value is considered read-only (by the decompiler)
|
||||
*/
|
||||
|
@ -323,6 +333,9 @@ public class HighSymbol {
|
|||
if (isVolatile) {
|
||||
SpecXmlUtils.encodeBooleanAttribute(buf, "volatile", true);
|
||||
}
|
||||
if (isIsolated()) {
|
||||
SpecXmlUtils.encodeBooleanAttribute(buf, "merge", false);
|
||||
}
|
||||
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "cat", category);
|
||||
if (categoryIndex >= 0) {
|
||||
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", categoryIndex);
|
||||
|
@ -356,6 +369,12 @@ public class HighSymbol {
|
|||
if ((namelockstr != null) && (SpecXmlUtils.decodeBoolean(namelockstr))) {
|
||||
namelock = true;
|
||||
}
|
||||
// isolate = false;
|
||||
// String isolatestr = symel.getAttribute("merge");
|
||||
// if ((isolatestr != null) && !SpecXmlUtils.decodeBoolean(isolatestr)) {
|
||||
// isolate = true;
|
||||
// }
|
||||
|
||||
name = symel.getAttribute("name");
|
||||
categoryIndex = -1;
|
||||
category = -1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue