binaryninja-api icon indicating copy to clipboard operation
binaryninja-api copied to clipboard

Phantom stack variables generated when creating a struct field

Open joelreymont opened this issue 1 year ago • 0 comments

Version and Platform (required):

  • Binary Ninja Version: 4.1.5260-dev, 7f6bb9ee
  • OS: macos
  • OS Version: 14.4
  • CPU Architecture: arm64

Internal binary major dine favor.

Possibly related to #5386.

struct Link __packed
{
    __offset(0x0), __offset(0x0).d
    uint32_t channel_id;
    uint32_t n_channels;
    int32_t baud_rate;
    int64_t field_10;
    int64_t field_18;
    int64_t field_20;
    int64_t field_28;
    uint32_t protocol_id;
};

or

struct Link __packed
{
    __padding char _0[4];
    uint32_t channel_id;
    uint32_t n_channels;
    int32_t baud_rate;
    int64_t field_10;
    int64_t field_18;
    int64_t field_20;
    int64_t field_28;
    uint32_t protocol_id;
};

The code is not recognizing that this is an array of structures (function arg struct Link* links), probably related to #5376

00062280                              DjiLogger_UserLogOutput(level: "linker", fmt: &(*nullptr->ident.signature)[3], "[%s:%d) config list channel id:%…", "DjiCommand_Init", 0x9e, zx.q(*(links->__offset(0x0).q + sx.q(ix) * 0x34 + 0x30)))
000622d8                              T_DjiReturnCode err_1 = DjiLinker_Init(link: links->__offset(0x0).q + sx.q(ix) * 0x34, linker: &(*mgr)->linkers[sx.q(ix)])
000622e8                              if (err_1 != 0)
00062318                                  DjiLogger_UserLogOutput(level: "linker", fmt: nullptr, "[%s:%d) init linker error:0x%08l…", "DjiCommand_Init", 0xa1, err_1)
0006231c                                  err = err_1
00062320                                  break

but I want to point something else. Replacing that 4-byte padding at the beginning of the struct with a 4-byte int

struct Link __packed
{
    uint32_t field_0;
    uint32_t channel_id;
    uint32_t n_channels;
    int32_t baud_rate;
    int64_t field_10;
    int64_t field_18;
    int64_t field_20;
    int64_t field_28;
    uint32_t protocol_id;
};

changes the code to

00062228                                  void* x2_1
00062228                                  x2_1.d = links->field_0
00062228                                  x2_1:4.d = links->channel_id
00062280                                  DjiLogger_UserLogOutput(level: "linker", fmt: &(*nullptr->ident.signature)[3], "[%s:%d) config list channel id:%…", "DjiCommand_Init", 0x9e, zx.q(*(x2_1 + sx.q(ix) * 0x34 + 0x30)))
00062288                                  void* x2_2
00062288                                  x2_2.d = links->field_0
00062288                                  x2_2:4.d = links->channel_id
000622d8                                  T_DjiReturnCode err_1 = DjiLinker_Init(link: x2_2 + sx.q(ix) * 0x34, linker: &(*mgr)->linkers[sx.q(ix)])

Why the extra phantom stack variables?

IDA Pro doesn't recognize array access but no extra variables are created

      DjiLogger_Output(
        "linker",
        3LL,
        "[%s:%d) config list channel id:%d",
        "DjiCommand_Init",
        158LL,
        *(unsigned __int8 *)(*(_QWORD *)&links->field_0 + 0x34LL * i + 0x30));// link->protocol_id
      v11 = DjiLinker_Init((struct Link *)(*(_QWORD *)&links->field_0 + 0x34LL * i), &(*mgr)->linkers[i]);

joelreymont avatar May 10 '24 08:05 joelreymont