Vector35 / Vector35/binaryninja-api

Array offsets constructed in multiple steps not handled as indices

Open
#2,488 4 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Component: Core Core: HLIL IL Optimization Impact: Medium
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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.