ghidra
ghidra copied to clipboard
Use different names for a variable
Is there some way to separate out uses of a variable and give them separate names.
i.e. sometimes a particular stack location or register is reused for a different purpose. It would be valuable to give this information to the decompiler so that it can treat it as a separate variable.
It is surely something to be wanted.
@emteere is there a recommended workflow to deal with this problem?
I believe this should be labelled as a feature request.
For registers you can do it:
- Right click in the Decompiler → Commit Locals.
- Right click on the variable → Split out as New Variable.
4,883.64
For registers you can do it:
1. Right click in the Decompiler → _Commit Locals_. 2. Right click on the variable → _Split out as New Variable_.
I don't see this option in either the decompiler or the listing.
- OS: Windows 10
- Java Version: 11.0.6
- Ghidra Version: 9.1.2
The code is here, but I also have not been able to find this item in the right-click menu.
Looking over the code, it seems that this only applies to locals that are declared within the function in the assembly listing. Even then, the varnode associated with the variable must have a "HighVariable" whatever that is. There is no support for reusing parameters, renamed registers or other parameters that don't have whatever "HighVariable" is.
It is currently possible to split out a local variable as a new variable. Parameters of a functions do not have this functionality (yet).
@madebr how?
@jrmuizel
Search for Split Out As New Variable in the documentation (F1).
It's currently the last section in the Decompiler Window page.
I've encountered the described issue many many times, but I would like to add another case where this feature would be necessary, and doesn't conceptually fall under "different purpose": static casts.
E.g.
derived_class* foo = (derived_class*) pBaseClass;
...
if (foo->derivedClassIntMember == 42) {
...
}
ends up many times looking like
// foo's type has been changed to derived_class* via the UI.
// The register it is assigned to is never used for anything but foo of type derived_class* in the function.
derived_class* foo = (derived_class*) pBaseClass;
...
if ((base_class*)foo[16].pBaseClassPointerToSomething == (something_else*)42) {
...
}
The generated code is much harder to follow and the quality of the Find users of... results is diminished by the resulting false positives and negatives.