Use call target parameter types to differentiate between `&struct` and `&struct.first_member`
Version and Platform (required):
- Binary Ninja Version: 3.4.4133-dev
- OS: Windows 11, x64
Bug Description:
0041536f char* var_38 = st_c_1->explorer_reg_path
00415376 enum WIN32_ERROR eax_10 = RegOpenKeyExW(0x80000001, var_38, 0, KEY_ALL_ACCESS, st_c_1)
0041537c int32_t eax_11 = neg.d(eax_10)
Disassembly of the call:
00415367 53 push ebx {var_2c_7}
00415368 683f000f00 push 0xf003f {var_30}
0041536d 6a00 push 0x0 {var_34}
0041536f ff36 push dword [esi] {var_38}
00415371 6801000080 push 0x80000001 {var_3c} {0x80000001}
00415376 ff1534904100 call dword [RegOpenKeyExW]
ebx is pointer to st_c_1 which is a structure like this:
struct struct_c __packed
{
HKEY key;
HKEY key2;
int32_t field_8;
int32_t field_c;
PWSTR explorer_reg_path;
int32_t current_ver_run_str;
int32_t inst_str;
int32_t init_windows_str;
char* field_20;
int32_t field_24;
int32_t field_28;
int32_t field_2c;
int32_t field_30;
};
As seen in the example, it does not reference first element of the structure when it should does.
When accessing first member of the structure (offset 0) IDA references first member if parameter /variable type is same as stucture member itself. Otherwise it directly references structure (not first member).
Expected Behavior:
I expect it to reference first member of structure there. So it will show st_c_1->key instead of st_c_1.
#include <stdio.h>
struct foo {
char name[0x10];
int count;
};
void bar(struct foo *ctx, char *name) {
puts(name);
++ctx->count;
}
int main(void) {
struct foo baz = { "asdf", 0 };
bar(&baz, baz.name);
return 0;
}
minimized testcase. the call bar inside main should display baz, baz.name as the arguments when bar is properly annotated. Right now it displays baz, baz