Wrong and missing structure field assignment
Version and Platform (required):
- Binary Ninja Version: 4.1.5474-dev, f6ba0af7
- OS: macos
- OS Version: 14.5
- CPU Architecture: arm64
Internal binary major dine favor.
This is IDA. Note the assignment to v13 and handler.field_0.
v13 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
HIDWORD(size) = 0x200;
callback = DjiLowSpeedDataChannel_SendDataToMobileWithoutFlowControl;
LOWORD(v16) = 128;
handler.field_0 = v13;
handler.buffer_size = size;
handler.callback = DjiLowSpeedDataChannel_SendDataToMobileWithoutFlowControl;
handler.field_3 = v16;
err = DjiFlowController_HandlerInit(&s_sendToMobileFlowController, &handler);
This is BN HLIL. The first two lines are gray and the field_0 assignment is completely different.
BN is not assigning var_44_1 and var_3c_1.
000823e0 int32_t var_44_1 = 0x3f99999a // gray
000823e8 int32_t var_3c_1 = 0x200 //gray
0008240c struct FlowCtrlHandler handler
0008240c handler.field_0 = 0x3f800000.q
0008240c handler.buffer_size = size.q
00082414 handler.callback = DjiLowSpeedDataChannel_SendDataToMobileWithoutFlowControl
00082414 handler.field_3 = 0x80.q
00082424 uint64_t err_4 = DjiFlowController_HandlerInit(ctrl: &MOBILE_FLOW_CTRL, &handler)
Also, below IDA has
if ( LS_CHAN_PARAM_CONFIG.series != DJI_AIRCRAFT_SERIES_M30 )
goto LABEL_17;
v10 = limit.cloud | 0x20000000000LL;
v9 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
v11 = DjiLowSpeedDataChannel_SendDataToCloudWithoutFlowControl;
LOWORD(v12) = 256;
handler.field_0 = v9;
handler.buffer_size = v10;
handler.callback = DjiLowSpeedDataChannel_SendDataToCloudWithoutFlowControl;
handler.field_3 = v12;
err = DjiFlowController_HandlerInit(&s_sendToCloudFlowController, &handler);
but BN is not assigning var_64_1 and var_5c_1.
And where is
v10 = limit.cloud | 0x20000000000LL;
v9 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
below?
00082484 if (LOW_SPEED_CHAN_PARAM_CONFIG.series == DJI_AIRCRAFT_SERIES_M30)
0008249c int32_t var_64_1 = 0x3f99999a // gray
000824a4 int32_t var_5c_1 = 0x200 // gray
000824c8 handler.field_0 = 0x3f800000.q
000824c8 handler.buffer_size = limit.cloud.q
000824d0 handler.callback = DjiLowSpeedDataChannel_SendDataToCloudWithoutFlowControl
000824d0 handler.field_3 = 0x100.q
000824e0 uint64_t err_5 = DjiFlowController_HandlerInit(ctrl: &CLOUD_FLOW_CTRL, &handler)
My BN types
struct BandwithLimit __packed
{
uint32_t payload_port;
uint32_t cloud;
uint32_t onboard_computer;
uint32_t extension_port;
uint32_t payload;
};
struct __data_var_refs FlowController __packed
{
int32_t field_0;
int32_t token;
int32_t field_8;
int32_t buffer_size;
__padding char _10[8];
void* buffer_data;
int64_t buffer;
uint32_t size_or_used_space;
__padding char _2c[0x14];
__padding char _40[8];
void* mutex_2;
uint64_t (* callback)(void* payload, int16_t payload_size, int16_t* sent_size);
int16_t field_58;
__padding char _5a[6];
__padding char _60[8];
void* mutex_1;
};
struct FlowCtrlHandler __packed
{
uint64_t field_0;
uint64_t buffer_size;
uint64_t (* callback)(void* payload, int16_t payload_size, int16_t* sent_size);
uint64_t field_3;
};
Full IDA code
__int64 DjiLowSpeedDataChannel_Init()
{
MessageBroker *broker; // x0
FlowCtrlHandler handler; // [xsp+10h] [xbp+10h] BYREF
BandwithLimit limit; // [xsp+30h] [xbp+30h] BYREF
FlowCtrlHandler handler_1; // [xsp+48h] [xbp+48h]
__int64 v5; // [xsp+68h] [xbp+68h]
__int64 v6; // [xsp+70h] [xbp+70h]
__int64 (__fastcall *v7)(); // [xsp+78h] [xbp+78h]
uint64_t v8; // [xsp+80h] [xbp+80h]
__int64 v9; // [xsp+88h] [xbp+88h]
__int64 v10; // [xsp+90h] [xbp+90h]
__int64 (__fastcall *v11)(); // [xsp+98h] [xbp+98h]
uint64_t v12; // [xsp+A0h] [xbp+A0h]
__int64 v13; // [xsp+A8h] [xbp+A8h]
uint64_t size; // [xsp+B0h] [xbp+B0h]
__int64 (__fastcall *callback)(); // [xsp+B8h] [xbp+B8h]
uint64_t v16; // [xsp+C0h] [xbp+C0h]
MessageHandlers handlers; // [xsp+C8h] [xbp+C8h] BYREF
int64_t err; // [xsp+D8h] [xbp+D8h]
T_DjiOsalHandler *osal; // [xsp+E0h] [xbp+E0h]
__int64 err_1; // [xsp+E8h] [xbp+E8h]
memset(&limit, 0, sizeof(limit));
osal = DjiPlatform_GetOsalHandler();
DjiDataBuriedPoint_ApiHitRecord();
DjiDataBuriedPoint_ModuleUsageRecord(17LL);
err_1 = DjiLowSpeedDataChannelParamConfig_Get(&LS_CHAN_PARAM_CONFIG);
if ( err_1 )
{
DjiLogger_Output("channel", 0, "[%s:%d) Can't get param config", "DjiLowSpeedDataChannel_Init", 205LL);
return 227LL;
}
err = osal->MutexCreate(&RX_CBK_MUTEX);
if ( err )
{
DjiLogger_Output("channel", 0, "[%s:%d) create mutex error: 0x%08llX.", "DjiLowSpeedDataChannel_Init", 211LL, err);
err_1 = err;
}
else
{
err = DjiLowSpeedDataChannel_GetStaticBandwidthLimit(&limit);
if ( err )
{
DjiLogger_Output(
"channel",
1,
"[%s:%d) get static bandwidth limit error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
218LL,
err);
err_1 = err;
}
else
{
if ( LS_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_PAYLOAD_PORT )
{
LODWORD(size) = limit.payload_port;
}
else if ( LS_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT
|| LS_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_LITE_PORT )
{
LODWORD(size) = limit.extension_port;
}
v13 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
HIDWORD(size) = 0x200;
callback = DjiLowSpeedDataChannel_SendDataToMobileWithoutFlowControl;
LOWORD(v16) = 128;
handler.field_0 = v13;
handler.buffer_size = size;
handler.callback = DjiLowSpeedDataChannel_SendDataToMobileWithoutFlowControl;
handler.field_3 = v16;
err = DjiFlowController_HandlerInit(&s_sendToMobileFlowController, &handler);
if ( err )
{
DjiLogger_Output(
"channel",
0,
"[%s:%d) send to mobile flow controller init error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
238LL,
err);
err_1 = err;
}
else
{
if ( LS_CHAN_PARAM_CONFIG.series != DJI_AIRCRAFT_SERIES_M30 )
goto LABEL_17;
v10 = limit.cloud | 0x20000000000LL;
v9 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
v11 = DjiLowSpeedDataChannel_SendDataToCloudWithoutFlowControl;
LOWORD(v12) = 256;
handler.field_0 = v9;
handler.buffer_size = v10;
handler.callback = DjiLowSpeedDataChannel_SendDataToCloudWithoutFlowControl;
handler.field_3 = v12;
err = DjiFlowController_HandlerInit(&s_sendToCloudFlowController, &handler);
if ( err )
{
DjiLogger_Output(
"channel",
0,
"[%s:%d) send to cloud flow controller init error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
252LL,
err);
err_1 = err;
}
else
{
LABEL_17:
v5 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
v6 = limit.onboard_computer | 0x20000000000LL;
v7 = DjiLowSpeedDataChannel_SendDataToOnboardComputerWithoutFlowControl;
LOWORD(v8) = 255;
handler.field_0 = v5;
handler.buffer_size = v6;
handler.callback = DjiLowSpeedDataChannel_SendDataToOnboardComputerWithoutFlowControl;
handler.field_3 = v8;
err = DjiFlowController_HandlerInit(&s_sendToOnboardComputerFlowController, &handler);
if ( err )
{
DjiLogger_Output(
"channel",
0,
"[%s:%d) send to onboard computer flow controller init error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
268LL,
err);
err_1 = err;
}
else
{
handler_1.field_0 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
handler_1.buffer_size = limit.payload | 0x20000000000LL;
if ( LS_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT
&& LS_CHAN_PARAM_CONFIG.series == DJI_AIRCRAFT_SERIES_M300 )
{
handler_1.callback = DjiLowSpeedDataChannel_SendDataToFirstPayloadbySdkWithoutFlowControl;
}
else
{
handler_1.callback = DjiLowSpeedDataChannel_SendDataToFirstPayloadWithoutFlowControl;
}
LOWORD(handler_1.field_3) = 255;
handler = handler_1;
err = DjiFlowController_HandlerInit(&s_sendToFirstPayloadFlowController, &handler);
if ( err )
{
DjiLogger_Output(
"channel",
0,
"[%s:%d) send to first payload flow controller init error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
288LL,
err);
err_1 = err;
}
else
{
handler_1.field_0 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
handler_1.buffer_size = limit.payload | 0x20000000000LL;
if ( LS_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT
&& LS_CHAN_PARAM_CONFIG.series == DJI_AIRCRAFT_SERIES_M300 )
{
handler_1.callback = DjiLowSpeedDataChannel_SendDataToSecondPayloadbySdkWithoutFlowControl;
}
else
{
handler_1.callback = DjiLowSpeedDataChannel_SendDataToSecondPayloadWithoutFlowControl;
}
LOWORD(handler_1.field_3) = 255;
handler = handler_1;
err = DjiFlowController_HandlerInit(&s_sendToSecondPayloadFlowController, &handler);
if ( err )
{
DjiLogger_Output(
"channel",
0,
"[%s:%d) send to second payload flow controller init error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
308LL,
err);
err_1 = err;
}
else
{
handler_1.field_0 = COERCE_UNSIGNED_INT(1.0) | 0x3F99999A00000000LL;
handler_1.buffer_size = limit.payload | 0x20000000000LL;
if ( LS_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT
&& LS_CHAN_PARAM_CONFIG.series == DJI_AIRCRAFT_SERIES_M300 )
{
handler_1.callback = DjiLowSpeedDataChannel_SendDataToThirdPayloadbySdkWithoutFlowControl;
}
else
{
handler_1.callback = DjiLowSpeedDataChannel_SendDataToThirdPayloadWithoutFlowControl;
}
LOWORD(handler_1.field_3) = 255;
handler = handler_1;
err = DjiFlowController_HandlerInit(&s_sendToThirdPayloadFlowController, &handler);
if ( err )
{
DjiLogger_Output(
"channel",
0,
"[%s:%d) send to third payload flow controller init error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
328LL,
err);
err_1 = err;
}
else
{
handlers.handlers = &s_dataTransmissionCmdList;
LOWORD(handlers.n_handlers) = 12;
broker = DjiAccessAdapter_GetCmdHandle();
err = DjiCommand_RegRecvCmdHandler(broker, &handlers);
if ( !err )
return 0LL;
DjiLogger_Output(
"channel",
0,
"[%s:%d) reg data transmission command handler error: 0x%08llX.",
"DjiLowSpeedDataChannel_Init",
340LL,
err);
err_1 = err;
}
}
}
}
}
}
}
}
DjiLowSpeedDataChannel_DeInit();
return err_1;
}
and full BN
00082250 uint64_t DjiLowSpeedDataChannel_Init()
00082258 struct BandwithLimit limit
00082258 __builtin_memset(s: &limit, c: 0, n: 0x14)
00082260 struct T_DjiOsalHandler* osal = DjiPlatform_GetOsalHandler()
0008227c DjiDataBuriedPoint_ModuleUsageRecord(0x11)
00082298 uint64_t err
00082250
00082298 if (DjiLowSpeedDataChannelParamConfig_Get(config: &LOW_SPEED_CHAN_PARAM_CONFIG) != 0)
000822c4 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) Can't get param config", "DjiLowSpeedDataChannel_Init", 0xcd)
000822c8 err = 0xe3
00082298 else
000822e0 uint64_t err_2 = osal->MutexCreate(mutex: &RX_CBK_MUTEX)
000822f0 uint64_t err_1
000822f0
000822f0 if (err_2 == 0)
00082334 uint64_t err_3 = DjiLowSpeedDataChannel_GetStaticBandwidthLimit(&limit)
00082334
00082344 if (err_3 != 0)
00082374 DjiLogger_Output(tag: "channel", level: 1, fmt: "[%s:%d) get static bandwidth lim…", "DjiLowSpeedDataChannel_Init", 0xda, err_3)
0008237c err_1 = err_3
00082380 goto label_828f8
00082334
00082394 uint32_t size
00082334
00082394 if (LOW_SPEED_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_PAYLOAD_PORT)
0008239c size = limit.payload_port
00082394 else if (LOW_SPEED_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT || LOW_SPEED_CHAN_PARAM_CONFIG.mount_pos_type == DJI_MOUNT_POSITION_TYPE_EXTENSION_LITE_PORT)
000823d0 size = limit.extension_port
00082334
000823e0 int32_t var_44_1 = 0x3f99999a
000823e8 int32_t var_3c_1 = 0x200
0008240c struct FlowCtrlHandler handler
0008240c handler.field_0 = 0x3f800000.q
0008240c handler.buffer_size = size.q
00082414 handler.callback = DjiLowSpeedDataChannel_SendDataToMobileWithoutFlowControl
00082414 handler.field_3 = 0x80.q
00082424 uint64_t err_4 = DjiFlowController_HandlerInit(ctrl: &MOBILE_FLOW_CTRL, &handler)
00082334
00082434 if (err_4 != 0)
00082464 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) send to mobile flow cont…", "DjiLowSpeedDataChannel_Init", 0xee, err_4)
0008246c err_1 = err_4
00082470 goto label_828f8
00082334
00082484 if (LOW_SPEED_CHAN_PARAM_CONFIG.series == DJI_AIRCRAFT_SERIES_M30)
0008249c int32_t var_64_1 = 0x3f99999a
000824a4 int32_t var_5c_1 = 0x200
000824c8 handler.field_0 = 0x3f800000.q
000824c8 handler.buffer_size = limit.cloud.q
000824d0 handler.callback = DjiLowSpeedDataChannel_SendDataToCloudWithoutFlowControl
000824d0 handler.field_3 = 0x100.q
000824e0 uint64_t err_5 = DjiFlowController_HandlerInit(ctrl: &CLOUD_FLOW_CTRL, &handler)
0008249c
000824f0 if (err_5 != 0)
00082520 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) send to cloud flow contr…", "DjiLowSpeedDataChannel_Init", 0xfc, err_5)
00082528 err_1 = err_5
0008252c goto label_828f8
00082334
00082544 int32_t var_84_1 = 0x3f99999a
0008254c int32_t var_7c_1 = 0x200
00082570 handler.field_0 = 0x3f800000.q
00082570 handler.buffer_size = limit.onboard_computer.q
00082578 handler.callback = DjiLowSpeedDataChannel_S...taToOnboardComputerWithoutFlowControl
00082578 handler.field_3 = 0xff.q
00082588 uint64_t err_6 = DjiFlowController_HandlerInit(ctrl: &ONBOARD_COMP_FLOW_CTRL, &handler)
00082334
00082598 if (err_6 != 0)
000825c8 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) send to onboard computer…", "DjiLowSpeedDataChannel_Init", 0x10c, err_6)
000825d0 err_1 = err_6
000825d4 goto label_828f8
00082334
000825ec int32_t var_a4_1 = 0x3f99999a
000825f4 int32_t var_9c_1 = 0x200
0008261c uint64_t (* callback)(char* payload, int16_t payload_size, int16_t* sent_size)
00082334
0008261c if (LOW_SPEED_CHAN_PARAM_CONFIG.mount_pos_type != DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT || LOW_SPEED_CHAN_PARAM_CONFIG.series != DJI_AIRCRAFT_SERIES_M300)
00082638 callback = DjiLowSpeedDataChannel_SendDataToFirstPayloadWithoutFlowControl
0008261c else
00082628 callback = DjiLowSpeedDataChannel_S...ToFirstPayloadbySdkWithoutFlowControl
00082334
00082650 handler.field_0 = 0x3f800000.q
00082650 handler.buffer_size = limit.payload.q
00082658 handler.callback = callback
00082658 handler.field_3 = 0xff.q
00082668 uint64_t err_7 = DjiFlowController_HandlerInit(ctrl: &SEND_TO_PAYLOAD_FLOW_CTRL, &handler)
00082334
00082678 if (err_7 != 0)
000826a8 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) send to first payload fl…", "DjiLowSpeedDataChannel_Init", 0x120, err_7)
000826b0 err_1 = err_7
000826b4 goto label_828f8
00082334
000826cc int32_t var_a4_2 = 0x3f99999a
000826d4 int32_t var_9c_2 = 0x200
000826fc uint64_t (* callback_1)(char* payload, int16_t payload_size, int16_t* sent_size)
00082334
000826fc if (LOW_SPEED_CHAN_PARAM_CONFIG.mount_pos_type != DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT || LOW_SPEED_CHAN_PARAM_CONFIG.series != DJI_AIRCRAFT_SERIES_M300)
00082718 callback_1 = DjiLowSpeedDataChannel_SendDataToSecondPayloadWithoutFlowControl
000826fc else
00082708 callback_1 = DjiLowSpeedDataChannel_S...oSecondPayloadbySdkWithoutFlowControl
00082334
00082730 handler.field_0 = 0x3f800000.q
00082730 handler.buffer_size = limit.payload.q
00082738 handler.callback = callback_1
00082738 handler.field_3 = 0xff.q
00082748 uint64_t err_8 = DjiFlowController_HandlerInit(ctrl: &SEND_TO_2ND_PAYLOAD_FLOW_CTRL, &handler)
00082334
00082758 if (err_8 != 0)
00082788 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) send to second payload f…", "DjiLowSpeedDataChannel_Init", 0x134, err_8)
00082790 err_1 = err_8
00082794 goto label_828f8
00082334
000827ac int32_t var_a4_3 = 0x3f99999a
000827b4 int32_t var_9c_3 = 0x200
000827dc uint64_t (* callback_2)(char* payload, int16_t payload_size, int16_t* sent_size)
00082334
000827dc if (LOW_SPEED_CHAN_PARAM_CONFIG.mount_pos_type != DJI_MOUNT_POSITION_TYPE_EXTENSION_PORT || LOW_SPEED_CHAN_PARAM_CONFIG.series != DJI_AIRCRAFT_SERIES_M300)
000827f8 callback_2 = DjiLowSpeedDataChannel_SendDataToThirdPayloadWithoutFlowControl
000827dc else
000827e8 callback_2 = DjiLowSpeedDataChannel_S...ToThirdPayloadbySdkWithoutFlowControl
00082334
00082810 handler.field_0 = 0x3f800000.q
00082810 handler.buffer_size = limit.payload.q
00082818 handler.callback = callback_2
00082818 handler.field_3 = 0xff.q
00082828 uint64_t err_9 = DjiFlowController_HandlerInit(ctrl: &SEND_TO_3D_PAYLOAD_FLOW_CTRL, &handler)
00082334
00082838 if (err_9 != 0)
00082868 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) send to third payload fl…", "DjiLowSpeedDataChannel_Init", 0x148, err_9)
00082870 err_1 = err_9
00082874 goto label_828f8
00082334
00082880 struct MessageHandlers handlers
00082880 handlers.handlers = &DATA_TX_HANDLER
00082888 handlers.n_handlers.w = 12
000828a0 uint64_t err_10 = DjiCommand_RegRecvCmdHandler(broker: DjiAccessAdapter_GetCmdHandle(), &handlers)
00082334
000828b0 if (err_10 != 0)
000828e0 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) reg data transmission co…", "DjiLowSpeedDataChannel_Init", 0x154, err_10)
000828e8 err_1 = err_10
000828ec goto label_828f8
00082334
000828f0 err = 0
000822f0 else
00082320 DjiLogger_Output(tag: "channel", level: 0, fmt: "[%s:%d) create mutex error: 0x%0…", "DjiLowSpeedDataChannel_Init", 0xd3, err_2)
00082328 err_1 = err_2
000828f8 label_828f8:
000828f8 DjiLowSpeedDataChannel_DeInit()
000828fc err = err_1
00082250
00082904 return err
00082908 int32_t data_82908 = 0x3f99999a
BN displays the code as grey because it thinks the assignment is useless, that the variable is not used afterwards, and subject to dead-code elimination. While such assertion is likely wrong, because I guess they could be part of a structure, and BN does not yet have a ability to see so. The behavior is expected given the current analysis result
Shouldn't this ticket be open until the issue is fixed, or do you not intend to fix the issue?
@psifertex ?
I feel like this should be kept closed because there is probably another issue that tracks the underlying analysis issue. We should link that to this, though.
Other than the stack structure analysis issue, things are working as expected, as far as I can tell
We'll re-open and re-name this issue if we can't find an appropriate issue to link to.
Actually, I'll just re-open it for now so we don't forget it. If we can find the other issue we'll close and link.
I believe this is a duplicate of https://github.com/Vector35/binaryninja-api/issues/5918. I am sorry that we have not had the proper issue to track the issue for quite a while