rizinorg / rz-ghidra

Deep ghidra decompiler and sleigh disassembler integration for rizin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.