Open joelreymont opened 5 months ago
The disassembly
0007bef0 uint64_t DjiIdentityVerify_GetSerialNumber(struct CommandManager* mgr, struct CommandHeader* header)
0007bef0 ffc317d1 sub sp, sp, #0x5f0
0007bef4 fd7bbfa9 stp x29, x30, [sp, #-0x10]! {__saved_x29} {__saved_x30}
0007bef8 fd030091 mov x29, sp {__saved_x29}
0007befc a07f01f9 str x0, [x29, #0x2f8 {var_308}]
0007bf00 a17b01f9 str x1, [x29, #0x2f0 {var_310}]
0007bf04 a27701f9 str x2, [x29, #0x2e8 {var_318}]
0007bf08 a07741f9 ldr x0, [x29, #0x2e8 {var_318}]
0007bf0c a0ff02f9 str x0, [x29, #0x5f8 {var_8}]
0007bf10 a0231791 add x0, x29, #0x5c8 {payload}
0007bf14 1f7c00a9 stp xzr, xzr, [x0] {payload} {0x0} {0x0}
0007bf18 a0631791 add x0, x29, #0x5d8
0007bf1c 1f7c00a9 stp xzr, xzr, [x0] {0x0} {0x0}
0007bf20 bfd30b79 strh wzr, [x29, #0x5e8 {var_18}] {0x0}
0007bf24 bfab1739 strb wzr, [x29, #0x5ea {var_16}] {0x0}
0007bf28 bf231739 strb wzr, [x29, #0x5c8 {payload}] {0x0}
0007bf2c 00048052 mov w0, #0x20
0007bf30 a1271791 add x1, x29, #0x5c9 {payload+0x1}
0007bf34 20000079 strh w0, [x1 {payload+0x1}] {0x20}
0007bf38 a0430091 add x0, x29, #0x10 {info}
0007bf3c e80300aa mov x8, x0 {info}
0007bf40 e58a0094 bl DjiProductInfo_GetInfo
0007bf44 a0030c91 add x0, x29, #0x300 {info_1}
0007bf48 a1430091 add x1, x29, #0x10 {info}
0007bf4c 825880d2 mov x2, #0x2c4
0007bf50 7c59fe97 bl memcpy
0007bf54 a22f1791 add x2, x29, #0x5cb {payload+0x3}
0007bf58 a3c30c91 add x3, x29, #0x330 {info_1.user_info.appKey}
0007bf5c 600440a9 ldp x0, x1, [x3] {info_1.user_info.appKey[0]} {info_1.user_info.appKey[1]} {info_1.user_info.appKey[2]} {info_1.user_info.appKey[3]} {info_1.user_info.appKey[4]} {info_1.user_info.appKey[5]} {info_1.user_info.appKey[6]} {info_1.user_info.appKey[7]} {info_1.user_info.appKey[8]} {info_1.user_info.appKey[9]} {info_1.user_info.appKey[0xa]} {info_1.user_info.appKey[0xb]} {info_1.user_info.appKey[0xc]} {info_1.user_info.appKey[0xd]} {info_1.user_info.appKey[0xe]} {info_1.user_info.appKey[0xf]}
0007bf60 400400a9 stp x0, x1, [x2] {payload+0x3} {s+0x3}
0007bf64 600441a9 ldp x0, x1, [x3, #0x10] {info_1.user_info.appKey[0x10]} {info_1.user_info.appKey[0x11]} {info_1.user_info.appKey[0x12]} {info_1.user_info.appKey[0x13]} {info_1.user_info.appKey[0x14]} {info_1.user_info.appKey[0x15]} {info_1.user_info.appKey[0x16]} {info_1.user_info.appKey[0x17]} {info_1.user_info.appKey[0x18]} {info_1.user_info.appKey[0x19]} {info_1.user_info.appKey[0x1a]} {info_1.user_info.appKey[0x1b]} {info_1.user_info.appKey[0x1c]} {info_1.user_info.appKey[0x1d]} {info_1.user_info.appKey[0x1e]} {info_1.user_info.appKey[0x1f]}
0007bf68 400401a9 stp x0, x1, [x2, #0x10] {var_28+0x3} {var_20+0x3}
0007bf6c a0231791 add x0, x29, #0x5c8 {payload}
0007bf70 63048052 mov w3, #0x23
0007bf74 e20300aa mov x2, x0 {payload}
0007bf78 a17b41f9 ldr x1, [x29, #0x2f0 {var_310}]
0007bf7c a07f41f9 ldr x0, [x29, #0x2f8 {var_308}]
0007bf80 129cff97 bl DjiCommand_SendAckData
0007bf84 a0fb02f9 str x0, [x29, #0x5f0 {var_10}]
0007bf88 a0fb42f9 ldr x0, [x29, #0x5f0 {var_10}]
0007bf8c 1f0000f1 cmp x0, #0
0007bf90 a0010054 b.eq 0x7bfc4
0007bf94 000600b0 adrp x0, 0x13c000
0007bf98 02c03691 add x2, x0, #0xdb0
0007bf9c 000600b0 adrp x0, 0x13c000
0007bfa0 01202591 add x1, x0, #0x948
0007bfa4 000600b0 adrp x0, 0x13c000
0007bfa8 00c01b91 add x0, x0, #0x6f0 {data_13c6f0, "auth"}
0007bfac a5fb42f9 ldr x5, [x29, #0x5f0 {var_10}]
0007bfb0 24238052 mov w4, #0x119
0007bfb4 e30302aa mov x3, x2 {__FUNCTION__.7456, "DjiIdentityVerify_GetSerialNumbe…"}
0007bfb8 e20301aa mov x2, x1 {data_13c948, "[%s:%d) get serial number ack er…"}
0007bfbc 01008052 mov w1, #0
0007bfc0 cf150094 bl DjiLogger_Output
0007bfc4 a0fb42f9 ldr x0, [x29, #0x5f0 {var_10}]
0007bfc8 fd7bc1a8 ldp x29, x30, [sp], #0x10 {__saved_x29} {__saved_x30}
0007bfcc ffc31791 add sp, sp, #0x5f0
0007bfd0 c0035fd6 ret
This is too much information please try to simplify down exactly what you're asking for.
How do I get the compact output of the kind that IDA Pro gives me?
memcpy(&info_1, &info, sizeof(info_1));
*(_QWORD *)&payload_1[3] = *(_QWORD *)info_1.user_info.appKey;
*(_QWORD *)&payload_1[11] = *(_QWORD *)&info_1.user_info.appKey[8];
*(_QWORD *)&payload_1[19] = *(_QWORD *)&info_1.user_info.appKey[16];
*(_QWORD *)&payload_1[27] = *(_QWORD *)&info_1.user_info.appKey[24];
err = DjiCommand_SendAckData(mgr_1, header_1, payload_1, 0x23);
Typing things correctly results in better output:
0007bef0 uint64_t DjiIdentityVerify_GetSerialNumber(struct CommandManager* arg1, struct CommandHeader* arg2)
0007bf0c int64_t x2
0007bf0c int64_t var_8 = x2
0007bf14 char payload[0x23]
0007bf14 payload[0].q = 0
0007bf14 payload[8].q = 0
0007bf1c payload[0x10].q = 0
0007bf1c payload[0x18].q = 0
0007bf20 payload[0x20].w = 0
0007bf24 payload[0x22] = 0
0007bf28 payload[0] = 0
0007bf34 payload[1].w = 0x20
0007bf40 char info_output[0x2c4]
0007bf40 DjiProductInfo_GetInfo(&info_output)
0007bf50 char copy_target[0x2c4]
0007bf50 memcpy(©_target, &info_output, 0x2c4)
0007bf60 payload[3].q = copy_target[0x30].q
0007bf60 payload[0xb].q = copy_target[0x38].q
0007bf68 payload[0x13].q = copy_target[0x40].q
0007bf68 payload[0x1b].q = copy_target[0x48].q
0007bf80 uint64_t result = DjiCommand_SendAckData(mgr: arg1, header: arg2, &payload, payload_size: 0x23)
0007bf90 if (result != 0)
0007bf90 {
0007bfc0 DjiLogger_Output(tag: "auth", level: 0, fmt: "[%s:%d) get serial number ack error:0x%08llX", "DjiIdentityVerify_GetSerialNumber", 0x119, result)
0007bf90 }
0007bfd0 return result
I wonder why we're not picking up on the memset operation though. ... oh probably because of the payload[1].w = 0x20
yeah looks like IDA handles this as such
*(_QWORD *)payload_1 = 0x2000LL;
memset(&payload_1[8], 0, 0x1B);
@negasora The code is trying to stuff parts of product info into a buffer so the type of product_info
is not char[0x2c4]
but ProductInfo
, a structure of the same size.
Why all the code with phantom variables, e.g. char payload_1[0x28]
, int64_t x1_1
, int64_t x0_2
and int64_t x1_2
?
Compare IDA output
DjiProductInfo_GetInfo(&info);
memcpy(&info_1, &info, sizeof(info_1));
*(_QWORD *)&payload_1[3] = *(_QWORD *)info_1.user_info.appKey;
*(_QWORD *)&payload_1[11] = *(_QWORD *)&info_1.user_info.appKey[8];
*(_QWORD *)&payload_1[19] = *(_QWORD *)&info_1.user_info.appKey[16];
*(_QWORD *)&payload_1[27] = *(_QWORD *)&info_1.user_info.appKey[24];
err = DjiCommand_SendAckData(mgr_1, header_1, payload_1, 0x23);
to BN
0007bf5c char payload_1[0x28]
0007bf5c payload_1[0] = info_1.user_info.appKey[0]
0007bf5c payload_1[1] = info_1.user_info.appKey[1]
0007bf5c payload_1[2] = info_1.user_info.appKey[2]
0007bf5c payload_1[3] = info_1.user_info.appKey[3]
0007bf5c payload_1[4] = info_1.user_info.appKey[4]
0007bf5c payload_1[5] = info_1.user_info.appKey[5]
0007bf5c payload_1[6] = info_1.user_info.appKey[6]
0007bf5c payload_1[7] = info_1.user_info.appKey[7]
0007bf5c int64_t x1_1
0007bf5c x1_1.b = info_1.user_info.appKey[8]
0007bf5c x1_1:1.b = info_1.user_info.appKey[9]
0007bf5c x1_1:2.b = info_1.user_info.appKey[0xa]
0007bf5c x1_1:3.b = info_1.user_info.appKey[0xb]
0007bf5c x1_1:4.b = info_1.user_info.appKey[0xc]
0007bf5c x1_1:5.b = info_1.user_info.appKey[0xd]
0007bf5c x1_1:6.b = info_1.user_info.appKey[0xe]
0007bf5c x1_1:7.b = info_1.user_info.appKey[0xf]
0007bf60 payload[3].q = payload_1
0007bf60 payload[0xb].q = x1_1
0007bf64 int64_t x0_2
0007bf64 x0_2.b = info_1.user_info.appKey[0x10]
0007bf64 x0_2:1.b = info_1.user_info.appKey[0x11]
0007bf64 x0_2:2.b = info_1.user_info.appKey[0x12]
0007bf64 x0_2:3.b = info_1.user_info.appKey[0x13]
0007bf64 x0_2:4.b = info_1.user_info.appKey[0x14]
0007bf64 x0_2:5.b = info_1.user_info.appKey[0x15]
0007bf64 x0_2:6.b = info_1.user_info.appKey[0x16]
0007bf64 x0_2:7.b = info_1.user_info.appKey[0x17]
0007bf64 int64_t x1_2
0007bf64 x1_2.b = info_1.user_info.appKey[0x18]
0007bf64 x1_2:1.b = info_1.user_info.appKey[0x19]
0007bf64 x1_2:2.b = info_1.user_info.appKey[0x1a]
0007bf64 x1_2:3.b = info_1.user_info.appKey[0x1b]
0007bf64 x1_2:4.b = info_1.user_info.appKey[0x1c]
0007bf64 x1_2:5.b = info_1.user_info.appKey[0x1d]
0007bf64 x1_2:6.b = info_1.user_info.appKey[0x1e]
0007bf64 x1_2:7.b = info_1.user_info.appKey[0x1f]
0007bf68 payload[0x13].q = x0_2
0007bf68 payload[0x1b].q = x1_2
0007bf80 uint64_t result = DjiCommand_SendAckData(mgr, header, &payload, payload_size: 0x23)
I maintain that BN is doing it wrong or can do much better here!
The cause for this seems to be the load/store splitting, we allow the operation to occur on array-struct pairs, even when the access on both sides is an array, causing the undersizing. If this can disallowed with no/little regressions then it is trivial to fix.
Should this still be tagged as a question given @emesare 's comment above?
It seems like an issue with load/store splitting.
Should this still be tagged as a question given @emesare 's comment above?
It seems like an issue with load/store splitting.
Yes, right now it is still being looked into, this issue will be updated when we can figure out a plan forward.
Version and Platform (required):
Internal binary
major dine favor
.Here's IDA Pro
Here's the original BN. I tried to undefine the function but the result was the same.
My
ProductInfo
typeTyping the two product infos give me the following
I'm trying to set the size of
payload
used hereI was able to adjust
payload
in IDA by looking at the space available betweenerr
at stack offset0x5F0
andpayload_1
at stack offset0x5C8
. This is how I got the 40.I thought I'd try the same using the BN Stack View. Hovering over
&payload
below tells me that the variable is at stack offset-0x38
. This is indeed the case per the Stack View. I don't seeresult
anywhere near, though, and there's not enough space between adjacent variables to fit a 40-character buffer.Very strange but maybe all is not lost. Maybe I should look at
0x5F0
and0xFC8
? The former offset holdsinfo
and there's nothing at the latter offset.Maybe BN will just do the right thing if I set the size of
payload
? I do know it's 40 characters after all!What about this assignment, though? Should I take the offset of
payload_1
instead? Can't because BN says it's in registerX0
.I'm just gonna go ahead and set the type of
payload_1
tochar[40]
and cross my fingers. And...How do I get out of this mess I got myself into?
And how do I use the Stack View in this case?
How do I get rid of
and make sure just
payload
is used?