HLIL can't show arguments for a certain type of calls
Version and Platform (required):
- Binary Ninja Version: 4.1.558-dev
- OS: macOS 15
- CPU Architecture: m2
Bug Description: Some calls under Windows PE that are detected only in MLIL, when lifted to HLIL, do not show parameters/arguments while IDA does. The current issue seems to be related to the tracking of arguments in the stack that are not currently propagated into the call, but I'm currently not sure.
What I'm expecting is to have the arguments typed at the same level of the call.
Steps To Reproduce: Please provide all steps required to reproduce the behavior:
- Open binary
- Go to
0040181c - Change view to HLIL
- See the issue
Screenshots/Video Recording:
- MLIL of the calls:
- HLIL of the same portion of code:
Binary: Binary has been sent via private message into Slack.
Binary can be found internally with: mention resolve access.
There is another related issue in this binary as well. Check address 0x402948
21 @ 00402948 int32_t var_29c_1 = 0x44
All of these temp stack vars at 29c should be eliminated.
If you patch out the SEH prolog/epilog calls in sub_402932, then elimination occurs properly, and the stack strings are recovered as well.
I believe the core issue here is that the stack remains unresolved. You need to figure out the underlying reason that the stack isn't being adjusted properly and fix it. I think it would be good if we ultimately told the user that the stack is unresolved and we're operating in a degraded state.
A quick triage points out that the issue is we are not terminating the control flow after a call to ExitProcess
Weird enough, the type of ExitProcess is correctly marked as no-return:
What makes the thing even more confusing is that if I manually override the call type at 0x401044 to void (uint32_t ) __noreturn = , then it works just fine
That looks really interesting! Thanks for the fast triage, happy to report more issues :) let me know so I can retest
I think it would be good if we ultimately told the user that the stack is unresolved and we're operating in a degraded state.
This would be much appreciated ^
For what it's worth, you don't even have to specify the call-type at all since that is the defaults. Just right-click on the ExitProcess in that line and choose "override call type" and hit enter to select the default type and it resolves all the subsequent stack mis-alignment because it correctly understands execution will never continue.
That at least gives you a work-around for now, but it's still a but that this is occurring at all.
I tested and we are NOT always ignoring the no-return info from the external functions. I tested a few other paces and when there is a call to ExitProcess, we terminate the control flow properly. There is something peculiar with the control flow in this particular function -- those jumps back from the later part of the function is playing a role. If I remove them then it also works just fine
This is because we are NOT processing no-return properties if the call instruction becomes MLIL_CALL_UNTYPED at MLIL.