ARM function calls ignore target function type
Version and Platform (required):
- Binary Ninja Version: All for a long time
- OS: Ubuntu (and others)
- OS Version: 22.04
- CPU Architecture: x64
Bug Description:
It seems in most if not all cases function calls in ARMv7 do not respect the type you set for them. This includes when you "override call type" at the call site as well as changing the target function type. For example, I'll set a function type to int sprintf(char *buf, const char *fmt, ...), and some call sites will stubbornly refuse to show anything other than sprintf() with no parameters. This can be hard to see at first because binja's call-site parameter detection usually does a decent job on its own, but for anything else, especially variadic functions, it seems to be unfixable.
I've seen this both in Thumb and ARM mode, in regular Linux ELFs and baremetal firmware, and for a long time. Thought there was a report for this already, but I can't find it now.
Hey, I compiled a little binary (hello.zip) with an sprintf() call and another rando function and am able to override both.
Before:
After:
Could you share your example binary?
Can't share and of course I'm also having trouble reproducing this with other binaries. I'll see if I can figure out what the difference is.
of course I'm also having trouble reproducing this with other binaries
Heh it's always that way. I'll watch for a followup.
Found a small example in here.
Open, let analysis finish, then go to 0x000a43dc.
Set the type of this function to void* xcalloc(uint32_t arg1, uint32_t arg2). Binja automatically adds __convention("cdecl") when changing the type.
Let reanalysis finish.
The very first xref at 0x00045924 does not (always?) change to reflect the new type, it's still int32_t r0 = xcalloc(). In this case if you go there and "override call type" it does take.
I noticed more weird behavior here - the first time I did these steps it did update that call type, but then I scrolled around a bit and came back and it changed itself back to int32_t r0 = xcalloc(). This was on an M2 MBP in 3.6.4593-dev FWIW.
Yep, I can reproduce this on 3.6.4617-dev - Many of the callsites for xcalloc (after following the steps above) do not change type to void*. Thanks for the test case, super helpful!
I suspect this is related to this: https://github.com/Vector35/binaryninja-api/issues/3927
The root cause of this has been identified, the fix is pending, and it was in fact a duplicate of #4529. Explanation of the bug here.