Vector35 / Vector35/binaryninja-api
Pointer-Array duality not handled for structure members
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 298
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 19
Description
Version and Platform (required):
- Binary Ninja Version: 3.4.4248-dev, c26685e2
- OS: macos
- OS Version: 13.3
- CPU Architecture: arm64
Data structures
struct __data_var_refs drv_cfg_item_t __packed
{
char* name;
int32_t field_4;
int32_t field_8;
};
struct __data_var_refs drv_cfg_t __packed
{
char* name;
struct drv_cfg_item_t* items;
char field_8;
char field_9;
char field_a;
char field_b;
char field_c;
uint8_t field_d;
char field_e;
char field_f;
};
What IDA generates
v10 = v18 - 1;
v11 = (unsigned __int8)p->field_E;
v12 = v10 / v11;
v13 = &p->data[v10 % v11];
name = v13->name;
v15 = LOBYTE(v13->field_8);
v16 = BYTE1(v13->field_8);
v17 = (&off_E0544)[2 * v15];
and the BN HLIL (see full listing at the bottom)...
000030f74 uint32_t r3_1 = ((uint32_t)p->field_e);
000030f76 struct drv_cfg_item_t* items = p->items;
000030f7a uint32_t r12_1 = ((r4_5 - 1) / r3_1);
000030f84 int32_t r4_3 = (((r4_5 - 1) - (r3_1 * r12_1)) * 0xc);
000030f8c int32_t r4_4 = *(int32_t*)((char*)items + r4_3);
000030f94 uint32_t r5_1 = ((uint32_t)*(int8_t*)(((char*)items + r4_3) + 9));
So BN recognizes items to be a structure but fails to recognize items->name
Assembler below
000030f40 void* fetch_config_30f40(int32_t arg1, int32_t arg2)
000030f40 2de9ff41 push {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr} {var_1c} {var_20_2} {var_24_4} {var_28_4} {var_4} {__saved_r8} {__saved_r7} {__saved_r6} {__saved_r5} {__saved_r4}
000030f44 8c46 mov r12, r1
000030f46 1046 mov r0, r2
000030f48 1946 mov r1, r3
000030f4a 334d ldr r5, [pc, #0xcc] {data_31018} {FETCH_CONFIG_START}
000030f4c dff8e080 ldr r8, [pc, #0xe0] {data_31030}
000030f50 6c68 ldr r4, [r5, #4] {drv_cfg_t::items}
000030f52 002c cmp r4, #0
000030f54 5bd1 bne #0x3100e
000030f56 4545 cmp r5, r8
000030f58 01d3 bcc #0x30f5e
000030f5a 0020 movs r0, #0
000030f5c 06e0 b #0x30f6c
000030f5e 1035 adds r5, #0x10
000030f60 f6e7 b #0x30f50
000030f62 0092 str r2, [sp] {var_28}
000030f64 2d4a ldr r2, [pc, #0xb4] {data_3101c} {data_108240, "Op.[config]\nname\t%s\ntype\t%d"}
000030f66 d4f768f9 bl #flight_log_523a
000030f6a 0130 adds r0, #1
000030f6c 04b0 add sp, #0x10
000030f6e bde8f081 pop {r4, r5, r6, r7, r8, pc} {__saved_r4} {__saved_r5} {__saved_r6} {__saved_r7} {__saved_r8} {var_4}
000030f72 013c subs r4, #1
000030f74 ab7b ldrb r3, [r5, #0xe] {drv_cfg_t::field_e}
000030f76 d5f804e0 ldr lr, [r5, #4] {drv_cfg_t::items}
000030f7a b4fbf3fc udiv r12, r4, r3
000030f7e 03fb1c43 mls r3, r3, r12, r4
000030f82 0c24 movs r4, #0xc
000030f84 5c43 muls r4, r3, r4
000030f86 264b ldr r3, [pc, #0x98] {data_31020}
000030f88 0eeb0405 add r5, lr, r4
000030f8c 5ef80440 ldr r4, [lr, r4]
000030f90 95f80880 ldrb r8, [r5, #8]
000030f94 6d7a ldrb r5, [r5, #9]
000030f96 53f83830 ldr r3, [r3, r8, lsl #3]
000030f9a 32b1 cbz r2, #0x30faa
000030f9c cde901c5 strd r12, r5, [sp, #4] {var_24} {var_20}
000030fa0 204a ldr r2, [pc, #0x80] {data_31024} {data_10825c, "Op.%s\t%s%d %d"}
000030fa2 0094 str r4, [sp] {var_28_1}
000030fa4 d4f749f9 bl #flight_log_523a
000030fa8 dfe7 b #0x30f6a
000030faa 17b1 cbz r7, #0x30fb2
000030fac cde90165 strd r6, r5, [sp, #4] {var_24_1} {var_20_1}
000030fb0 f6e7 b #0x30fa0
000030fb2 1d4a ldr r2, [pc, #0x74] {data_31028} {data_10826a, "Op.%s\t%s %d"}
000030fb4 cde90045 strd r4, r5, [sp] {var_28_2} {var_24_2}
000030fb8 26e0 b #0x31008
000030fba 0134 adds r4, #1
000030fbc 95f80ee0 ldrb lr, [r5, #0xe] {drv_cfg_t::field_e}
000030fc0 0ab1 cbz r2, #0x30fc6
000030fc2 02fb0efe mul lr, r2, lr
000030fc6 a645 cmp lr, r4
000030fc8 06da bge #0x30fd8
000030fca 0136 adds r6, #1
000030fcc b742 cmp r7, r6
000030fce dbbf ittet le
000030fd0 0024 movs r4, #0
000030fd2 1035 adds r5, #0x10
000030fd4 0024 movs r4, #0
000030fd6 2646 mov r6, r4
000030fd8 0133 adds r3, #1
000030fda 4545 cmp r5, r8
000030fdc bdd2 bcs #0x30f5a
000030fde 95f90d70 ldrsb r7, [r5, #0xd] {drv_cfg_t::field_d}
000030fe2 6a7b ldrb r2, [r5, #0xd] {drv_cfg_t::field_d}
000030fe4 002f cmp r7, #0
000030fe6 b6bf itet lt
000030fe8 02f07f07 and r7, r2, #0x7f
000030fec 0027 movs r7, #0
000030fee 0022 movs r2, #0
000030ff0 9c45 cmp r12, r3
000030ff2 e2d1 bne #0x30fba
000030ff4 002c cmp r4, #0
000030ff6 bcd1 bne #0x30f72
000030ff8 2b68 ldr r3, [r5]
000030ffa 2a89 ldrh r2, [r5, #8] {drv_cfg_t::field_8.w}
000030ffc 002f cmp r7, #0
000030ffe b0d0 beq #0x30f62
000031000 3244 add r2, r6
000031002 cde90062 strd r6, r2, [sp] {var_28_3} {var_24_3}
000031006 094a ldr r2, [pc, #0x24] {data_3102c} {data_108222, "Op.[config]\nname\t%s%d\ntype\t%…"}
000031008 d4f717f9 bl #flight_log_523a
00003100c ade7 b #0x30f6a
00003100e 0024 movs r4, #0
000031010 2346 mov r3, r4 {0x0}
000031012 2646 mov r6, r4 {0x0}
000031014 e1e7 b #0x30fda
and full HLIL
000030f40 void* fetch_config_30f40(int32_t arg1, int32_t arg2)
000030f40 {
000030f40 int32_t r3;
000030f40 int32_t var_1c = r3;
000030f40 int32_t r2;
000030f40 int32_t var_20_2 = r2;
000030f40 int32_t var_24_4 = arg2;
000030f40 int32_t var_28_4 = arg1;
000030f4a struct drv_cfg_t* p = &FETCH_CONFIG_START;
000030f54 void* r0;
000030f54 while (true)
000030f54 {
000030f54 if (p->items != 0)
000030f52 {
00003100e int32_t r4_5 = 0;
000031010 int32_t r3_3 = 0;
000031012 int32_t r6_1 = 0;
000030fdc uint32_t v23;
000030fdc int32_t v25;
000030fdc while (p < 0x13d3d0)
000030fda {
000030fde v25 = ((int32_t)p->field_d);
000030fe2 v23 = ((uint32_t)p->field_d);
000030fe4 bool cond:0_1 = v25 >= 0;
000030fe4 bool cond:1_1 = v25 < 0;
000030fe8 if (v25 < 0)
000030fe4 {
000030fe8 v25 = (v23 & 0x7f);
000030fe8 }
000030fec if (cond:0_1)
000030fec {
000030fec v25 = 0;
000030fec }
000030fee if (cond:1_1)
000030fee {
000030fee v23 = 0;
000030fee }
000030ff2 if (arg2 == r3_3)
000030ff0 {
000030ff2 break;
000030ff2 }
000030fba r4_5 = (r4_5 + 1);
000030fbc uint32_t v11 = ((uint32_t)p->field_e);
000030fc0 if (v23 != 0)
000030fc0 {
000030fc2 v11 = (v23 * v11);
000030fc2 }
000030fc8 if (v11 < r4_5)
000030fc6 {
000030fca r6_1 = (r6_1 + 1);
000030fd0 if (v25 <= r6_1)
000030fcc {
000030fd0 r4_5 = 0;
000030fd0 }
000030fd2 if (v25 <= r6_1)
000030fcc {
000030fd2 p = &p[1];
000030fd2 }
000030fd4 if (v25 > r6_1)
000030fcc {
000030fd4 r4_5 = 0;
000030fd4 }
000030fd6 if (v25 <= r6_1)
000030fcc {
000030fd6 r6_1 = r4_5;
000030fd6 }
000030fcc }
000030fd8 r3_3 = (r3_3 + 1);
000030fd8 }
000030fdc if (p < 0x13d3d0)
000030fda {
000030ff6 void* r0_1;
000030ff6 if (r4_5 != 0)
000030ff4 {
000030f74 uint32_t r3_1 = ((uint32_t)p->field_e);
000030f76 struct drv_cfg_item_t* items = p->items;
000030f7a uint32_t r12_1 = ((r4_5 - 1) / r3_1);
000030f84 int32_t r4_3 = (((r4_5 - 1) - (r3_1 * r12_1)) * 0xc);
000030f8c int32_t r4_4 = *(int32_t*)((char*)items + r4_3);
000030f94 uint32_t r5_1 = ((uint32_t)*(int8_t*)(((char*)items + r4_3) + 9));
000030f9a if (v23 != 0)
000030f9a {
000030f9c uint32_t var_24 = r12_1;
000030f9c uint32_t var_20 = r5_1;
000030f9c }
000030faa else if (v25 == 0)
000030faa {
000030fb4 int32_t var_28_2 = r4_4;
000030fb4 uint32_t var_24_2 = r5_1;
000030fb4 }
000030fac else
000030fac {
000030fac int32_t var_24_1 = r6_1;
000030fac uint32_t var_20_1 = r5_1;
000030fac }
000030faa if ((v23 != 0 || (v23 == 0 && v25 != 0)))
000030faa {
000030fa2 int32_t var_28_1 = r4_4;
000030fa4 r0_1 = flight_log_523a();
000030fa4 }
000030ff4 }
000030ffa else
000030ffa {
000030ffa uint32_t r2_1 = ((uint32_t)p->field_8*(int32_t*)((char*)p + 8));
000030ffe if (v25 == 0)
000030ffc {
000030f62 uint32_t var_28 = r2_1;
000030f66 r0_1 = flight_log_523a();
000030f66 }
000031002 else
000031002 {
000031002 int32_t var_28_3 = r6_1;
000031002 int32_t var_24_3 = (r2_1 + r6_1);
000031000 }
000031000 }
000030faa if (((r4_5 == 0 && v25 != 0) || ((r4_5 != 0 && v23 == 0) && v25 == 0)))
000030faa {
000031008 r0_1 = flight_log_523a();
000031008 }
000030f6a r0 = ((char*)r0_1 + 1);
000030f6a break;
000030f6a }
000030ff6 }
000030f58 else if (p < 0x13d3d0)
000030f56 {
000030f5e p = &p[1];
000030f60 continue;
000030f60 }
000030f5a r0 = nullptr;
000030f5c break;
000030f5c }
000030f6e return r0;
000030f6e }
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the fetch_config_30f40 entry point and compare the supplied ARM assembler with its HLIL listing, focusing on p->items and the later access to the structure member name. Reproduce the case using the drv_cfg_t and drv_cfg_item_t definitions; done means HLIL preserves the structure-member access instead of reducing it to raw pointer arithmetic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100