Vector35 / binaryninja-api

Public API, examples, documentation and issues for Binary Ninja
https://binary.ninja/
MIT License
921 stars 208 forks source link

Arm64: Incorrect return address handling when the link register (x30)'s value is known #3896

Open xusheng6 opened 1 year ago

xusheng6 commented 1 year ago

A user reported a bug that BN does not handle the return address properly when the x30 value is known. The sample is obfuscated, and it is using the ret instruction to do a jump. At the end of the function, it first calculates the jump target in x30, and then returns. BN is unaware of the trick and during LLIL->MLIL translation, the information is lost and the code is treated as a regular return.

The user does not wish to share the binary in public, so I recreated the issue on a different binary. helloworld_bug.zip For comparison, the original binary is attached as well: helloworld.zip

100003f54  mov     x30, #0x1234
100003f58  add     sp, sp, #0x40
100003f5c  ret     

Given the above function epilog, it loads 0x1234 into x30. After the ret instruction, the pc will become 0x1234. The code effectively does a b 0x1234. The LLIL is fine:

  25 @ 100003f54  x30 = 0x1234
  26 @ 100003f58  sp = sp + 0x40
  27 @ 100003f5c  <return> jump(x30)

However, things are screwed up in MLIL:

  18 @ 100003f5c  return 0xa

To deal with this, we need to do the following things:

  1. When the x30 value is a known constant, translate the ret instruction into a jump
  2. When the x30 value is undetermined, check its value is actually the value of x30 at the function start. For example, if we look at the original binary, we can see that the x30 value is the __saved_x30.

image

  1. (what should we do if it is not the entry value of x30?)
xusheng6 commented 1 year ago

We are dealing with the same issue in x64 slightly better:

Screenshot 2023-02-14 at 4 19 15 PM

That we at least indicated the write to the __return_addr. Although we do not redirect the control flow in the IL

plafosse commented 1 year ago

This may be a duplicate of this issue: #1052