In order to show the user only the most relevant code and hide the unnecessary clutter, the decompiler performs various optimizations before displaying the pseudocode. Some of these optimizations rely on various assumptions which are usually correct in well-behaved programs. However, in some situations they may be incorrect which may lead to wrong output, so you may need to know how to fix them.
Constant data and dead code removal
Consider this example from a recent iOS kernelcache:
The function looks non-trivial (I’ve had to zoom out the graph) but the pseudocode is very short. Most of the conditional branches visible in the graph have disappeared. What’s happening?
You may get some hints from the warnings shown by the decompiler when you first decompile the function:
If you have checked “Don’t display message again” previously, the message will be shown in the Output window:
The last message is also a useful hint: if you double-click the address you’ll land on the instruction which was “optimized away”.
If we double-click the variables involved in the condition, we can see that they both are situated in the segment mentioned in the warning message (
So, apparently, because the segment is considered read-only and both variables are set to zero, the decompiler deduced that the branch is always taken and removed the check itself as dead code. Similarly it removed many of the previous comparisons. But is this assumption correct?
Not very constant
If we check cross-references to the variables, we can see that they’re actually written to:
And if we try to decompile the function doing it, we’ll see some “interesting” messages:
And again, the addresses mentioned are all in the same supposedly-constant segment.
So we can make this conclusion: despite the name, the segment is not actually constant. How do we tell the decompiler that?
The easiest solution is to add the Write flag to the segment’s permission. This can be done via the Edit > Segments > Edit segment… command (shortcut Alt-S).
After refreshing the pseudocode (F5), we no longer see the red warning or mentions of “write access to const memory”. And if we go back to the previously “too short” function, it now has all the checks which were missing: