binaryninja-api
binaryninja-api copied to clipboard
Weird stack issue
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.