tl;dr

  • Simple typer bug, range of BitAnd opcode is assumed to be [1, operand] when in reality it is [0, operand].
  • Use range assumptions to create unchecked integer underflow.
  • Bypass array bounds checks and obtain OOB write, overwrite size of array to get overlap.
  • Use double & object array overlap to create addrOf & fakeObj primitives.
  • Create overlapping fake array using StructureID leak to obtain arbitrary R/W.