decompiler: fix indexing into arrays #6722
Open
+12
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Ghidra decompiler is sometimes struggling to show submember array access.
For example, given the following structs:
and the following source code:
that compiled into the following 32-bit x86 code:
the decompiled output produced would be this:
With this fix it should produce:
This is caused by RulePtrArith traveling through a CPUI_INT_MULT and latching onto a CPUI_INT_ADD operation happening on the line above the array access, which makes it distribute the members of the addition through the *4 multiplication, producing a local_18 * 4 and a -0x30 * 4 + 4, which doesn't lead to any member of the struct, and then it just gives up. This is fixed by letting it undo the 'distribute' that it did and try again in case if it didn't find the appropriate struct member.
EDIT: Another example
It becomes a tree:
When Ghidra sees the -1, it checks if 0xfffffffc is greater than the structure's size, which it is, and then short-circuits the whole expression tree as invalid and RulePtrArith just doesn't get applied.
By setting preventDistribution to true, this behavior can be stopped.