binaryninja-api icon indicating copy to clipboard operation
binaryninja-api copied to clipboard

Changing the type of a stack-based array does not take effect the first time

Open joelreymont opened this issue 1 year ago • 7 comments

Version and Platform (required):

  • Binary Ninja Version: 4.1.5272-dev, 3a057a87
  • OS: macos
  • OS Version: 14.4
  • CPU Architecture: arm64

Internal binary major dine favor.

0006815c  struct ErrObj* DjiError_GetErrorMsgElements(int64_t err_code, struct ErrDesc* err_desc @ x8)

00068178      char* description
00068178      __builtin_memset(s: &description, c: 0, n: 0x20)

I pointed at description and set the type with 'y' to char description[0x20] this is what I got as a result

0006815c  struct ErrObj* DjiError_GetErrorMsgElements(int64_t err_code, struct ErrDesc* err_desc @ x8)
00068178      int64_t s
00068178      __builtin_memset(s: &s, c: 0, n: 0x20)

Typing s and changing it to char description[0x20] does the right thing

0006815c  struct ErrObj* DjiError_GetErrorMsgElements(int64_t err_code, struct ErrDesc* err_desc @ x8)
00068178      char description[0x20]
00068178      __builtin_memset(s: &description, c: 0, n: 0x20)

but why not the first time around?

I was able to reproduce this several times by undoing my changes.

joelreymont avatar May 14 '24 14:05 joelreymont

Here's a binary that repros the issue: a.txt

  1. Go to main
  2. Change var_38 to char str[0x20]
  3. Change str to char* str2
  4. Notice that the user-defined name gets undefined ~and it's marked low-confidence~

Edit: Ok it's not marked low confidence, it's grayed out because it's dead code

negasora avatar May 14 '24 15:05 negasora

Here's the main I see

00001139  int32_t main(int32_t argc, char** argv, char** envp)

00001141      int32_t argc_1 = argc
00001144      char** argv_1 = argv
00001148      char** envp_1 = envp
0000114c      void* fsbase
0000114c      int64_t rax = *(fsbase + 0x28)
0000115b      int64_t s
0000115b      __builtin_memset(s: &s, c: 0, n: 0x20)
00001184      *(fsbase + 0x28)
0000118d      if (rax == *(fsbase + 0x28))
00001195          return 0
0000118f      __stack_chk_fail()
0000118f      noreturn

Looked at the stack view to figure out that var_38 must be s.

Changed the type of s to char str[0x20] and got

00001139  int32_t main(int32_t argc, char** argv, char** envp)

00001141      int32_t argc_1 = argc
00001144      char** argv_1 = argv
00001148      char** envp_1 = envp
0000114c      void* fsbase
0000114c      int64_t rax = *(fsbase + 0x28)
0000115b      char str[0x20]
0000115b      __builtin_memset(s: &str, c: 0, n: 0x20)
00001184      *(fsbase + 0x28)
0000118d      if (rax == *(fsbase + 0x28))
00001195          return 0
0000118f      __stack_chk_fail()
0000118f      noreturn

Everything worked as expected.

joelreymont avatar May 14 '24 15:05 joelreymont

Change it to char* str after

negasora avatar May 14 '24 15:05 negasora

Yes, it went back to s and the type was greyed-out so must be low confidence.

My original complaint was that the process was going the other way around, though, and I had to ask BN to make my type twice. Did it decide it was a low-confidence type the first time around?

joelreymont avatar May 14 '24 15:05 joelreymont

That's my current guess

negasora avatar May 14 '24 15:05 negasora

I don't know if BN is working as intended here so feel free to close the issue.

I object to BN claiming that I'm wrong, though, given that I'm right in the end 🤷🏼‍♂️.

joelreymont avatar May 14 '24 15:05 joelreymont

Definitely not working as intended :P

negasora avatar May 14 '24 15:05 negasora