Vector35 / Vector35/binaryninja-api

Extra arguments added to function in THUMB

Open
#6,615 5 comments 0 reactions 1 assignee View on GitHub

@rssor is already working on this.

Since May 7, 2025.

Arch: ARM/Thumb Component: Architecture Component: Core Effort: Medium Impact: Medium
Dominant language
C++
Stars
1.3k
Forks
298
Avg merge
5d 5h
Merged PRs (30d)
19

Description

Version and Platform (required):

  • Binary Ninja Version: 4.3.6844
  • OS: Windows
  • OS Version: 10
  • CPU Architecture: x64

Bug Description:

I often see this pattern come up when looking at THUMB code:

push {r0, r1, r2, r3, r4, lr}
movs r4, #0
str r4, [sp, #4]
str r4, [sp, #8]
...
add sp, #0x10
pop {r4, pc}

There are 6 registers that are saved to the stack in the function prologue, but only 2 are actually restored in the epilogue. The r0/r1/r2/r3 stack slots are used as variables instead of actually being used to save/restore the registers. I guess the compiler may do this as an optimization to remove a sub sp, X instruction.

Binja does not handle this pattern well, and it leads to code that looks like this in HLIL:

int32_t func(int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4)
    int32_t var_c = arg4
    int32_t var_10 = arg3
    int32_t var_14 = arg2
    var_14 = 0
    var_10 = 0
    ...

The function is thought to have 4 arguments when it really only has 1.

Steps To Reproduce:

Can't share the binary that I encountered this in, but I did my best to create a minimal example for this (which may be a little contrived).

Please provide all steps required to reproduce the behavior:

  1. Create new window
  2. Paste in following bytes: 1fb505460024019401a800f005f8019c04eb050004b010bd052101607047
  3. Make thumb2 function
  4. See that sub_0 is shown to have 2 arguments

Expected Behavior:

The function should not have any arguments appended if the stack variable the argument is written to is being reused as a regular variable.

A possible heuristic for this could be comparing the push/pop instructions of the function and considering any non-restored registers to not be arguments.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.