Vector35 / Vector35/binaryninja-api
Array offsets constructed in multiple steps not handled as indices
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 298
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 19
Description
When an array offset is constructed by shifting an index multiple times (e.g. due to architectures without hardware multipliers), HLIL doesn't seem to catch that as an array index.
Here's an example from ARMv7 Thumb:
/* uint8_t r4 is an index variable (this is in a loop) */
/* struct *r6 is an array-base pointer */
04ebc400 add r0, r4, r4, lsl #3
00eb4005 add r5, r0, r0, lsl #1
06eb8500 add r0, r6, r5, lsl #2 /* r0 points to the base of the r4'th structure */
00f83c7f strb r7, [r0, #0x3c]!
4770 strb r7, [r0, #1]
8770 strb r7, [r0, #2]
MLIL - all good so far:
4 r0_1 = r4 + (r4 << 3)
5 r5_1 = r0_1 + (r0_1 << 1)
6 r0_2 = gArrayBase + (r5_1 << 2)
7 r0_3 = r0_2 + 0x3c
8 [r0_3].b = 0xff
9 [r0_3 + 1].b = 0xff
10 [r0_3 + 2].b = 0xff
HLIL:
4 uint32_t r5_1 = r4 * 0x1b
5 *((r5_1 << 2) + &gArrayBase[0].__offset(0x3c)) = 0xff
6 *((r5_1 << 2) + &gArrayBase[0].__offset(0x3d)) = 0xff
7 *((r5_1 << 2) + &gArrayBase[0].__offset(0x3e)) = 0xff
Oops.
Not sure if this is a separate issue, but it also gets weirder when I define members at those offsets:
5 (&gArrayBase[0].field_3c)[r5_1 << 2] = 0xff
6 (&gArrayBase[0].field_3d)[r5_1 << 2] = 0xff
7 (&gArrayBase[0].field_3e)[r5_1 << 2] = 0xff
This just seems wrong? I could see (&gArrayBase[r5_1 << 2]).field_3c = 0xff, but the indexing there is just in the wrong place.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the ARMv7 Thumb example and comparing the MLIL and HLIL output shown in the issue. Investigate the HLIL array-index and structure-member recovery path, including the variant with defined members. Done means the computed offset is represented as the correct array index and member access rather than placing the index inside the member address.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers, reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100