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

Objective-C calls disappearing in MLIL and HLIL

Open ghost opened this issue 2 years ago • 5 comments

Version and Platform (required):

  • Binary Ninja Version: 3.4.4271, 3.5.4299-dev
  • OS: macOS
  • OS Version: 13.4
  • CPU Architecture: M1

Bug Description: Take the following assembly:

00082a5c  f44fbea9   stp     x20, x19, [sp, #-0x20]! {__saved_x20} {__saved_x19}
00082a60  fd7b01a9   stp     x29, x30, [sp, #0x10] {__saved_x29} {__saved_x30}
00082a64  fd430091   add     x29, sp, #0x10 {__saved_x29}
00082a68  1f2003d5   nop     
00082a6c  e16d1b58   ldr     x1, sr_bioResource  {sl_bioResource, "bioResource"}
00082a70  b30c0094   bl      _objc_msgSend
00082a74  fd031daa   mov     x29, x29 {__saved_x29}
00082a78  cf0c0094   bl      _objc_retainAutoreleasedReturnValue
00082a7c  f30300aa   mov     x19, x0
00082a80  1f2003d5   nop     
00082a84  616d1b58   ldr     x1, sr_hasPearlSupport  {sl_hasPearlSupport, "hasPearlSupport"}
00082a88  ad0c0094   bl      _objc_msgSend
00082a8c  f40300aa   mov     x20, x0
00082a90  e00313aa   mov     x0, x19
00082a94  bc0c0094   bl      _objc_release
00082a98  e00314aa   mov     x0, x20
00082a9c  fd7b41a9   ldp     x29, x30, [sp, #0x10] {__saved_x29} {__saved_x30}
00082aa0  f44fc2a8   ldp     x20, x19, [sp], #0x20 {__saved_x20} {__saved_x19}
00082aa4  c0035fd6   ret     

In LLIL, all looks good:

   0 @ 00082a5c  sp = sp - 0x20
   1 @ 00082a5c  [sp {__saved_x20}].q = x20
   2 @ 00082a5c  [sp + 8 {__saved_x19}].q = x19
   3 @ 00082a60  [sp + 0x10 {__saved_x29}].q = x29
   4 @ 00082a60  [sp + 0x18 {__saved_x30}].q = x30
   5 @ 00082a64  x29 = sp + 0x10 {__saved_x29}
   6 @ 00082a6c  x1 = [&sr_bioResource].q
   7 @ 00082a70  call(_objc_msgSend)
   8 @ 00082a74  x29 = x29 {__saved_x29}
   9 @ 00082a78  call(_objc_retainAutoreleasedReturnValue)
  10 @ 00082a7c  x19 = x0
  11 @ 00082a84  x1 = [&sr_hasPearlSupport].q
  12 @ 00082a88  call(_objc_msgSend)
  13 @ 00082a8c  x20 = x0
  14 @ 00082a90  x0 = x19
  15 @ 00082a94  call(_objc_release)
  16 @ 00082a98  x0 = x20
  17 @ 00082a9c  x29 = [sp + 0x10 {__saved_x29}].q
  18 @ 00082a9c  x30 = [sp + 0x18 {__saved_x30}].q
  19 @ 00082aa0  x20 = [sp {__saved_x20}].q
  20 @ 00082aa0  x19 = [sp + 8 {__saved_x19}].q
  21 @ 00082aa0  sp = sp + 0x20
  22 @ 00082aa4  <return> jump(x30)

However, in MLIL, hasPearlSupport has disappeared:

   0 @ 00082a70  _objc_msgSend(self, "bioResource")
   1 @ 00082a78  x0 = _objc_retainAutoreleasedReturnValue()
   2 @ 00082a7c  x19 = x0
   3 @ 00082a88  x0_1 = _objc_msgSend()
   4 @ 00082a8c  x20 = x0_1
   5 @ 00082a90  x0_2 = x19
   6 @ 00082a94  _objc_release(x0_2)
   7 @ 00082a98  x0_3 = x20
   8 @ 00082aa4  return x0_3

It's also gone in HLIL:

00082a70      _objc_msgSend(self, "bioResource")
00082a78      int64_t x0 = _objc_retainAutoreleasedReturnValue()
00082a88      char x0_1 = _objc_msgSend()
00082a94      _objc_release(x0)
00082aa4      return x0_1

Steps To Reproduce: Please provide all steps required to reproduce the behavior:

  1. Load the above assembly code
  2. Go to Plugins -> Objective-C -> Analyze Structures (optional, also happens without this but it makes the ILs cleaner)
  3. Compare the LLIL, MLIL and HLIL

If necessary, I can provide the binary privately.

Expected Behavior: The hasPearlSupport call should have been retained.

ghost avatar May 25 '23 22:05 ghost

Could you please provide the binary to @peter in Slack or here?

plafosse avatar Jun 09 '23 20:06 plafosse

Closing this issue because we haven't been able to reproduce the issue. If anyone has a binary that exhibits this problem and can provide it and point us in the right direction, please attach it (or email it to us) and reopen this issue.

fuzyll avatar Oct 17 '23 14:10 fuzyll

Binary Ninja Version: 4.1.5041-dev Personal (8ab0888f) OS: MacOS

Hi, i've got same behaviour due analysis of mach-o binaries. The binary obfuscated, but some of the cases is kinda clear but nevertheless BN still generating empty calls (objc_msgSend()) image

And as you may see, the signature for objc_msgSend is set: image

This can be fixed by manually overriding every call to exact amount of arguments (like https://github.com/nshp/binaryninja-printf). For example call at 0x039c7f4 from first screenshot can be fixed by overriding call site type to void* _objc_msgSend(id self, uint8_t* sel): image

Steps to reproduce:

  1. Open attached binary
  2. Navigate to 0x039c7f4 and switch to MLIL/HLIL

Here is binary: bin.zip

mostobriv avatar Apr 01 '24 14:04 mostobriv

Confirmed that I can reproduce this:

image

I was using 4.1.4997-dev. Wondering if maybe the workflow has an edge-case or something and is missing a fixup? Or, perhaps this could be a core bug where something isn't propagating? For both of the _objc_msgSend calls in the picture, we have int64_t _objc_msgSend() as the type applied.

fuzyll avatar Apr 02 '24 14:04 fuzyll

Here is kinda different example from clean binary, but mb it still can be helpful to investigate root cause: image

I overwrote call site types of both msgSend's (at 0x1000222ac and 0x1000222bc), but for some reason HLIL just ignores the second one (and use its own deducted signature): image image

Binary: bin.zip

mostobriv avatar Apr 03 '24 07:04 mostobriv

From glancing through this binary on latest dev, it appears the issues detailed here have been resolved.

TypeLibraries should be applying to _objc_msgSend which should resolve the initial issue with or without the Objective-C workflow running. This applies the `id(void*,char*) type to msgSend by default.

Additionally, the Objective-C workflow (enabled by default) should automatically be overriding calltypes in all _objc_msgSend calls based on the amount of arguments in the selector.


I threw in the provided binaries. It appears to have been resolved in both of these I additionally went through the list of xrefs to _objc_msgSend and validated every proper msgSend call seems correct. There were some msgSend calls with garbage arguments in the first one, but I have to assume that's some sort of obfuscation.

Here is the region of code screenshotted in the most recent comment, on current dev: Image

I'm marking this issue as closed again, please let us know if you're still experiencing issues.

0cyn avatar Mar 18 '25 09:03 0cyn