Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AnnotateVariable() method doesn't find the correct reference offset for global variables #323

Open
sakiodre opened this issue Jun 19, 2023 · 5 comments

Comments

@sakiodre
Copy link

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);
}
@ITAYC0HEN
Copy link
Member

@thestr4ng3r what do you think? is it intentional?

@thestr4ng3r
Copy link
Member

thestr4ng3r commented Jun 23, 2023

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.

@sakiodre
Copy link
Author

sakiodre commented Jun 24, 2023

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.

@sakiodre
Copy link
Author

sakiodre commented Jun 30, 2023

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.

@XVilka
Copy link
Member

XVilka commented Aug 10, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants