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

Weird stack issue

Open joelreymont opened this issue 1 year ago • 0 comments

Version and Platform (required):

  • Binary Ninja Version: 4.0.4958, ddff9339
  • OS: macos
  • OS Version: 14.4
  • CPU Architecture: arm64

Internal binary major dine favor.

IDA Pro code

              recv_cmds = (struct RecvCmd *)djiOs->Malloc(24 * (unsigned int)LOWORD(cmd_list->n_cmds));
              if ( recv_cmds )
              {
                for ( j = 0; LOWORD(cmd_list->n_cmds) > j; ++j )
                {
                  recv_cmd = &recv_cmds[j];
                  recv_cmd_1 = &cmd_list->cmds[j];
                  v8 = recv_cmd_1->field_8;
                  *(_QWORD *)&recv_cmd->field_0 = *(_QWORD *)&recv_cmd_1->field_0;
                  recv_cmd->field_8 = v8;
                  recv_cmd->callback = recv_cmd_1->callback;
                }
                cmd->recv_cmds[ixa].cmds = recv_cmds;
                LOWORD(cmd->recv_cmds[ixa].n_cmds) = cmd_list->n_cmds;
...

BN

00064540                                  struct RecvCmd* recv_cmds = CMD_OSAL->Malloc(size: zx.d(cmd_list->n_cmds.w) * 0x18)
00064550                                  if (recv_cmds == 0)
0006457c                                      DjiLogger_UserLogOutput(level: "linker", fmt: nullptr, "[%s:%d) recv cmd list malloc err…", "DjiCommand_RegRecvCmdHandler", 0x297)
00064550                                  else
00064604                                      for (int32_t j = 0; zx.d(cmd_list->n_cmds.w) s> j; j = j + 1)
000645a8                                          void* x3_16 = &recv_cmds[sx.q(j)]
000645c8                                          void* x0_345 = &cmd_list->cmds[sx.q(j)]
000645d4                                          int64_t x1_56 = *(x0_345 + 8)
000645d8                                          *x3_16 = *x0_345
000645d8                                          *(x3_16 + 8) = x1_56
000645e0                                          *(x3_16 + 0x10) = *(x0_345 + 0x10)
00064614                                      cmd->recv_cmds[sx.q(ix_2)].cmds = recv_cmds
0006463c                                      (&cmd->recv_cmds[0]:8.q)[sx.q(ix_2) * 2].w = cmd_list->n_cmds.w

It's clear that both x3_16 and x0_345 are of type RecvCmd* and we are just copying info between structures.

Assigning the right type to both variables should clear up the code, right? Right?

After typing x3_16 and renaming it to cmd1...

00064604                                      for (int32_t j = 0; zx.d(cmd_list->n_cmds.w) s> j; j = j + 1)
000645a8                                          struct RecvCmd* cmd1 = &recv_cmds[sx.q(j)]
000645c8                                          void* x0_345 = &cmd_list->cmds[sx.q(j)]
000645d4                                          int64_t x0_346 = *x0_345
000645d4                                          int64_t x1_56 = *(x0_345 + 8)
000645d8                                          cmd1->field_0 = x0_346.d
000645d8                                          cmd1->sender = x0_346:4.b
000645d8                                          cmd1->receiver = x0_346:5.b
000645d8                                          cmd1->field_1 = x0_346:6.b
000645d8                                          cmd1->field_2 = x0_346:7.b
000645d8                                          cmd1->field_8 = x1_56
000645e0                                          cmd1->callback = *(x0_345 + 0x10)
00064614                                      cmd->recv_cmds[sx.q(ix_2)].cmds = recv_cmds
0006463c                                      (&cmd->recv_cmds[0]:8.q)[sx.q(ix_2) * 2].w = cmd_list->n_cmds.w

After typing x0_345 and renaming it to cmd2 ...

00064604                                      for (int32_t j = 0; zx.d(cmd_list->n_cmds.w) s> j; j = j + 1)
000645a8                                          struct RecvCmd* cmd1 = &recv_cmds[sx.q(j)]
000645c8                                          struct RecvCmd* cmd2 = &cmd_list->cmds[sx.q(j)]
000645d4                                          int64_t x0_345
000645d4                                          x0_345.d = cmd2->field_0
000645d4                                          x0_345:4.b = cmd2->sender
000645d4                                          x0_345:5.b = cmd2->receiver
000645d4                                          x0_345:6.b = cmd2->field_1
000645d4                                          x0_345:7.b = cmd2->field_2
000645d4                                          int64_t field_8 = cmd2->field_8
000645d8                                          cmd1->field_0 = x0_345.d
000645d8                                          cmd1->sender = x0_345:4.b
000645d8                                          cmd1->receiver = x0_345:5.b
000645d8                                          cmd1->field_1 = x0_345:6.b
000645d8                                          cmd1->field_2 = x0_345:7.b
000645d8                                          cmd1->field_8 = field_8
000645e0                                          cmd1->callback = cmd2->callback
00064614                                      cmd->recv_cmds[sx.q(ix_2)].cmds = recv_cmds
0006463c                                      (&cmd->recv_cmds[0]:8.q)[sx.q(ix_2) * 2].w = cmd_list->n_cmds.w

What's going on here?

Let me know if you want my database!

P.S. IDA is much better with stack management. It will tell me if I type something to a size that the stack layout of the function won't handle, i.e. if my type is larger than what would fit or smaller. BN seems to do none of that.

joelreymont avatar May 09 '24 16:05 joelreymont