Previously, we discussed a situation where the decompiler wrongly used a combined stack slot for two separate variables. We could solve it because each variable had a distinct stack location, so editing the stack frame to split them worked.
However, modern optimizing compilers can actually reuse the same stack location for different variables active at different times (e.g. in different scopes). Consider this example:
int __fastcall getval(char a1) { int v2; // [esp+0h] [ebp-4h] BYREF if ( a1 ) { printf("Enter your age:"); scanf("%d", &v2); } else { printf("Enter your height:"); scanf("%d", &v2); } return v2; }
We can see that v2
is used for two different values: age and height. Because their uses do not overlap, the compiler decided to use the same stack slot. In this short example we can rename v2
to a generic value
and call it a day. But imagine that the code inside the two branches is more complicated and it’s actually useful to know with which one we’re dealing with.
In that case, you can use the “Split variable” action (shortcult Shift–S) to introduce a new variable for the same stack location.
If you do it for the first time, IDA will warn you that incorrect splitting may produce wrong decompilation.
After confirming, a new variable is created:
Note how it has the same stack location as v2
but has an annotation SPLIT. Now that you have a different variable, you can rename or retype it as necessary.
In case you want to go back to the original situation, you can use “Unsplit variable”, or reset split assignments for the current function.
Note: before IDA 8.4, the action was called “Force new variable”.
See also:
Hex-Rays interactive operation: Split variable
Igor’s Tip of the Week #155: Splitting stack variables in the decompiler