You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Ignore invalid instruction after jump/call for triggering guided analysis #7999
What is the feature you'd like to have?
See title.
Is your feature request related to a problem?
When we encounter invalid instructions in a function, we enter Guided Analysis Mode (https://docs.binary.ninja/guide/guided_analysis.html). This helps both us and users in cases where there are things like obfuscated functions that will send analysis going off in directions it shouldn't.
Unfortunately, there's a common pattern used by some compilers for noreturn functions that also currently triggers it. It looks something like this, for RISC-V:
The 0000 "instruction" here is intended to trap in the event that something goes wrong and execution comes back from sub_b5550 (which it should not).
We should not enter guided analysis mode in these situations as it prevents analysis in a situation where it should continue.
Are any alternative solutions acceptable?
For the RISC-V case above, I've opened a PR (#7998) to address this by lifting 0000 as a trap instead. But, we should solve this more generally so that other architectures (and, particularly ones that might not be our official ones, but user plugins) are not also running into this.
Partially? This is also a pretty large regression because now any compiler emitting such guards after noreturn function calls always trips guided analysis mode, meaning the rest of the basic blocks in the function won't be automatically discovered.
The guided analysis mode should be self-correcting in the presence of incremental analysis in conjunction with no-returns being identified. There could be an new edge case that popped up, or a regression that happened. Is the binary available for this?
Correct. We are not identifying a no return in this case, causing guided analysis mode to start because we hit an invalid instruction. There is no binary and the issue is trivially reproduced with the information above.
PR #7998 addresses this specific issue, but by modifying the way we lift the byte sequence 0000 in RISC-V. Alternatives that would fix this case more generally are welcome and preferred, but this issue is bad enough for affected users that I had hoped we could band-aid it for the 5.3 release. The only current solution is that those users need to turn off guided analysis mode entirely to deal with the regression.
I was looking at a binary a while back with this pattern and found that these functions that dropped into guided analysis mode were useful because I was able to identify these patterns more easily and make the callees no-return manually before then disabling guided analysis. Isn't this the kind of scenario that guided analysis was meant for?
Yeah this is exactly the purpose. Identify and stop analysis before it goes off in the weeds. That pause gives a user the ability to inspect and handle it appropriately.
If it were difficult to understand that these functions can't return for some reason, yes, guided analysis would probably be beneficial. It'd prevent a bunch of runaway analysis creating incorrect functions and wasting a whole bunch of time.
But, in this case (the RISC-V example above), it's a straightforward output from the compiler. There is zero reason we shouldn't be handling this automatically, and the degree to which this comes up on certain firmwares for very little benefit turns reversing into a whole lot of manual work.
We can't handle this in basic block analysis if Binja fails to recognize that a callee is no-return. I like your change to go ahead and lift 0000 as a trap for now. But maybe we need a module-level workflow that looks for jal instructions followed by a 0000 and assign no-return to the callee.
The RISC-V case should be worked around in builds >= 5.4.9470-dev. Leaving the issue open because we still need a more general solution. Whether that's improving the noreturn analysis, changing something about how we lift more generally, modifying guided analysis mode, or something else entirely, I don't know.
Activity
plafosse commentedon Mar 9, 2026
So are you asking for "heuristic no-return analysis" This is something I've wanted for awhile and something Ghidra already supports.
rssor commentedon Apr 9, 2026
Partially? This is also a pretty large regression because now any compiler emitting such guards after noreturn function calls always trips guided analysis mode, meaning the rest of the basic blocks in the function won't be automatically discovered.
bpotchik commentedon Apr 10, 2026
The guided analysis mode should be self-correcting in the presence of incremental analysis in conjunction with no-returns being identified. There could be an new edge case that popped up, or a regression that happened. Is the binary available for this?
plafosse commentedon Apr 10, 2026
I think this is the case when no-returns are not automatically identified
fuzyll commentedon Apr 10, 2026
Correct. We are not identifying a no return in this case, causing guided analysis mode to start because we hit an invalid instruction. There is no binary and the issue is trivially reproduced with the information above.
PR #7998 addresses this specific issue, but by modifying the way we lift the byte sequence 0000 in RISC-V. Alternatives that would fix this case more generally are welcome and preferred, but this issue is bad enough for affected users that I had hoped we could band-aid it for the 5.3 release. The only current solution is that those users need to turn off guided analysis mode entirely to deal with the regression.
zznop commentedon Apr 10, 2026
I was looking at a binary a while back with this pattern and found that these functions that dropped into guided analysis mode were useful because I was able to identify these patterns more easily and make the callees no-return manually before then disabling guided analysis. Isn't this the kind of scenario that guided analysis was meant for?
bpotchik commentedon Apr 10, 2026
Yeah this is exactly the purpose. Identify and stop analysis before it goes off in the weeds. That pause gives a user the ability to inspect and handle it appropriately.
fuzyll commentedon Apr 10, 2026
If it were difficult to understand that these functions can't return for some reason, yes, guided analysis would probably be beneficial. It'd prevent a bunch of runaway analysis creating incorrect functions and wasting a whole bunch of time.
But, in this case (the RISC-V example above), it's a straightforward output from the compiler. There is zero reason we shouldn't be handling this automatically, and the degree to which this comes up on certain firmwares for very little benefit turns reversing into a whole lot of manual work.
bpotchik commentedon Apr 10, 2026
I think one observation here is that we could potentially improve the no-return analysis.
zznop commentedon Apr 10, 2026
We can't handle this in basic block analysis if Binja fails to recognize that a callee is no-return. I like your change to go ahead and lift
0000as a trap for now. But maybe we need a module-level workflow that looks forjalinstructions followed by a0000and assign no-return to the callee.zznop commentedon Apr 10, 2026
Or yeah, what Brian said about improving no-return analysis for this case.
fuzyll commentedon May 25, 2026
The RISC-V case should be worked around in builds >=
5.4.9470-dev. Leaving the issue open because we still need a more general solution. Whether that's improving thenoreturnanalysis, changing something about how we lift more generally, modifying guided analysis mode, or something else entirely, I don't know.