We’ve covered splitting expressions before, but there may be situations where it can’t be used.
For example, consider following situation:
The decompiler decided that the function returns a 64-bit integer and allocated a 64-bit stack varible for it. For example, the code may be manipulating a register pair commonly used for 64-bit variables (
eax:edx) which triggers the heirustics for recovering 64-bit calculations. However, here it seems to be a false positive: we can see separate accesses to the low and high dword of the variable, and the third argument for the IndexFromId call also uses a pointer into the middle of the variable.
One option is to hint to the decompiler that the function returns a 32-bit integer by editing the function’s prototype (use “Set item type” or the Y shotrcut on the first line).
Often this fixes the decompilation, but not here:
We still have a 64-bt variable on the stack at
ebp-10h, so it’s worth inspecting the stack frame. It can be opened by pressing Ctrl-K in disassembly view or double-cliking stack variable in disassembly or pseudocode:
We see that there is a quadword (64-bit) variable at offset
-10. it can be converted to 32-bit(dword) by pressing D three times. Another dword can be added in the same manner at offset
After refreshing pseudocode, we can see improved output:
There’s only one small issue:
v5 became an array. This happened bcause passing an array or an address of a single integer produces the same code but there was a gap in the stack frame after
var_C, so the decompiler decided that it’s actually an array. If you’re certain that it’s a single integer, you have the following options:
- Edit the stack frame again and define some variables after
var_Cso that there is no space for an array.
- retype v5 directly from the pseudocode (use Y and enter ‘int’).
Now the pseudocode looks correct and there is only one variable of correct size:
Note that in some cases a variable passed by address may be really an array, or a structure – in case of doubt inspect the called function to confirm how the argument is being used.