AnnotateVariable() method doesn't find the correct reference offset for global variables
sakiodre opened this issue · comments
I'm implementing my own ghidra decompiler and researching your source as a reference, while trying to make the xml parser I noticed that some global variable token has a varnode that is in the "register" or "unique" space.
I've checked on my end and it doesn't look like i parsed the xml incorrectly. Since your source doesn't handle this case, isn't this a bug?
void AnnotateGlobalVariable(Varnode *varnode, std::vector<RzCodeAnnotation> *out)
{
RzCodeAnnotation annotation = {};
annotation.type = RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE;
annotation.reference.offset = varnode->getOffset();
out->push_back(annotation);
}
void AnnotateVariable(ANNOTATOR_PARAMS){
....
if (high->isPersist() && high->isAddrTied())
AnnotateGlobalVariable(varnode, out);
}
@thestr4ng3r what do you think? is it intentional?
Might indeed be a bug that there are false positives in the "global variable" recognition. But it should be checked with a concrete test case.
I've tested this repeatedly over the past few days, and it looks like the check for high->isPersist() && high->isAddrTied()
is indeed false positive. This is how I fix this issue:
AddrSpace* space = varnode->getSpace();
AddrSpace* codeSpace = space->getTrans()->getDefaultCodeSpace();
annotation.reference.offset = (space != codeSpace) ? varnode->getTiedVarnode()->getOffset() : varnode->getOffset();
Note that I use the latest fork of ghidra, but that doesn't seem to be the issue.
I've come to a conclusion that this happens when a global variable get assign a value, something like this:
uRam_deadbeef = *(uint64_t*)(iVar8 + 0x123);
In this case, uRam_deadbeef
varnode's address is in the unique (IPTR_INTERNAL) space, with the def pcodeop is CPUI_LOAD and its input1 is CPUI_CAST -> CPUI_INT_ADD (iVar8, 123).
And the fix varnode->getTiedVarnode()
I mentioned above has been working fine for me till now. I'll make a PR in the next few days when I have free time and also bump ghidra to the latest version, it put everything in the ghidra namespace now so it's a bit complicated.
And the fix
varnode->getTiedVarnode()
I mentioned above has been working fine for me till now. I'll make a PR in the next few days when I have free time and also bump ghidra to the latest version, it put everything in the ghidra namespace now so it's a bit complicated.
Hi, have you had a chance to do that? Also, is there any test case? Minified example would work best.