Vector35 / binaryninja-api

Public API, examples, documentation and issues for Binary Ninja
https://binary.ninja/
MIT License
900 stars 203 forks source link

Array access not recognized #4316

Closed joelreymont closed 1 year ago

joelreymont commented 1 year ago

Version and Platform (required):

BN disassembly

00049368  int32_t add_sys_task(struct sys_task_t* task, uint32_t ix)

00049368  0929       cmp     r1, #9
0004936a  0246       mov     r2, r0
0004936c  10b5       push    {r4, lr} {var_4} {__saved_r4}
0004936e  15d8       bhi     #0x4939c

00049370  8368       ldr     r3, [r0, #8] {sys_task_t::ctx}
00049372  b3b1       cbz     r3, #0x493a2

00049374  4368       ldr     r3, [r0, #4] {sys_task_t::proc}
00049376  a3b1       cbz     r3, #0x493a2

00049378  0d4b       ldr     r3, [pc, #0x34]  {__ptr_SYS_TASKS}
0004937a  0c20       movs    r0, #0xc
0004937c  00fb0130   mla     r0, r0, r1, r3
00049380  4468       ldr     r4, [r0, #4]
00049382  0cb1       cbz     r4, #0x49388

00049384  8068       ldr     r0, [r0, #8]
00049386  78b9       cbnz    r0, #0x493a8

00049388  0c20       movs    r0, #0xc
0004938a  00fb0133   mla     r3, r0, r1, r3
0004938e  1068       ldr     r0, [r2] {sys_task_t::name}
00049390  5168       ldr     r1, [r2, #4] {sys_task_t::proc}
00049392  03c3       stm     r3!, {r0, r1}
00049394  9068       ldr     r0, [r2, #8] {sys_task_t::ctx}
00049396  1860       str     r0, [r3]
00049398  0020       movs    r0, #0

0004939a  10bd       pop     {r4, pc} {__saved_r4} {var_4}

0004939c  6ff01500   mvn     r0, #0x15  {0xffffffea}
000493a0  fbe7       b       #0x4939a

000493a2  6ff00d00   mvn     r0, #0xd  {0xfffffff2}
000493a6  f8e7       b       #0x4939a

000493a8  6ff00f00   mvn     r0, #0xf  {0xfffffff0}
000493ac  f5e7       b       #0x4939a

000493ae                                            00 bf                                                                ..

000493b0  struct sys_task_t (* __ptr_SYS_TASKS)[0xa] = SYS_TASKS

SYS_TASKS is an array of structures

20056a40  struct sys_task_t SYS_TASKS[0xa] = 
20056a40  {
20056a40      [0x0] = 
20056a40      {
20056a40          char* name = nullptr
20056a44          void* proc = nullptr
20056a48          void* ctx = nullptr
20056a4c      }

where sys_task_t is defined thusly

struct __data_var_refs sys_task_t __packed
{
    char* name;
    void* proc;
    void* ctx;
};

IDA recognized array access

int __fastcall add_sys_task(sys_task_t *task, unsigned int ix)
{
  sys_task_t *sys_task; // r0
  sys_task_t *sys_task_1; // r3
  int proc; // r1

  if ( ix > 9 )
    return 0xFFFFFFEA;
  if ( !task->ctx || !task->proc )
    return 0xFFFFFFF2;
  sys_task = &SYS_TASKS[ix];
  if ( sys_task->proc && sys_task->ctx )
    return 0xFFFFFFF0;
  sys_task_1 = &SYS_TASKS[ix];
  proc = task->proc;
  sys_task_1->name = task->name;
  sys_task_1->proc = proc;
  sys_task_1->ctx = task->ctx;
  return 0;
}

but BN does not and avoids referring to SYS_TASKS at all costs!

00049368  int32_t add_sys_task(struct sys_task_t* task, uint32_t ix)

0004936e      int32_t err
0004936e      if (ix u> 9)
0004939c          err = 0xffffffea
00049376      else
00049376          if (task->ctx == 0 || (task->ctx != 0 && task->proc == 0))
000493a2              err = 0xfffffff2
00049376          if (task->ctx != 0 && task->proc != 0)
00049386              if (*(0xc * ix + 0x20056a44) == 0 || (*(0xc * ix + 0x20056a44) != 0 && *(0xc * ix + 0x20056a48) == 0))
00049390                  void* proc = task->proc
00049392                  *(0x20056a40 + 0xc * ix) = task->name
00049392                  *(0xc * ix + 0x20056a44) = proc
00049396                  *(0xc * ix + 0x20056a48) = task->ctx
00049398                  err = 0
00049386              if (*(0xc * ix + 0x20056a44) != 0 && *(0xc * ix + 0x20056a48) != 0)
000493a8                  err = 0xfffffff0
0004939a      return err

000493ae                                            00 bf                                                                ..

000493b0  struct sys_task_t (* __ptr_SYS_TASKS)[0xa] = SYS_TASKS

Anyone from V35 should search for "Encourage Salesman Prompt Delay" to find the database.

joelreymont commented 1 year ago

Related to #4256.

fuzyll commented 1 year ago

I think this is actually a duplicate of #4310? The things we get wrong are the same in both issues. The code above will refer to SYS_TASKS if types are applied properly and we are told values are pointers, but it will only do this for places where 0x20056a40 is used directly. We get members (e.g. 0x20056a44) wrong and none of the multiplications will work either.

Leaving this open for now in case I've missed something else that makes this functionally different, but I believe this can be closed as a duplicate and #4310 should survive as the issue that needs addressed.

xusheng6 commented 1 year ago

Very likely a duplicate of https://github.com/Vector35/binaryninja-api/issues/4251.

fuzyll commented 1 year ago

Ah, good catch! Closing this as a duplicate of #4251.