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 -C
:
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_C
so 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.
See also:
Igor’s tip of the week #65: stack frame view
Igor’s tip of the week #42: Renaming and retyping in the decompiler