7

With Microsoft Visual C++ executables, I often run into decompilations like this:

void __cdecl Pbdf::ReadString(char *dst, Pbdf *pbdfOrLength)
{
    Pbdf *pbdf; // esi

    pbdf = pbdfOrLength;
    Pbdf::ReadBytes(&pbdfOrLength, 1, pbdfOrLength);
    Pbdf::ReadBytes(dst, (unsigned __int8)pbdfOrLength, pbdf);
    dst[(unsigned __int8)pbdfOrLength] = 0;
}

The function is actually more like this (as seen in a Watcom executable doing the same thing):

void __usercall Pbdf::ReadString(char *dst@<eax>, Pbdf *pbdf@<edx>)
{
    unsigned __int8 length; // [esp+0h] [ebp-14h]

    Pbdf::ReadBytes(pbdf, &length, 1u);
    Pbdf::ReadBytes(pbdf, dst, length);
    *((_BYTE *)dst + length) = 0;
}

So, from a Pbdf file-like struct, it's reading a single byte determining the number of following bytes to read into a buffer, and terminates that buffer with a 0.

However, in the MSVC decompilation, you can see it merged the length and Pbdf struct into one variable, causing me to name the variable "pbdfOrLength".

Is it somehow possible to tell the decompiler to "split" these variables up / handle them as two separate ones, to get an output similar to what is seen in Watcom?

5
  • Has this seriously not been fixed yet? It's probably the simplest yet most annoying issue I have with HexRays. Fixed in 7.2! hexrays: added “force new variable” command; it can be used to force the decompiler to create a new aliasable stack variable at the specified location – Orwellophile Jan 15 at 8:00
  • I had mixed experiences with "Force new variable" in case the variable was reused later on; it still mapped to the same old variable, and I had to split every occurence and map each back to the other split one which became tedious with long methods... but probably the best you can get at the moment. – Ray Jan 15 at 11:47
  • The option never seems to be there when I need it, so I have yet to be able to make any kind of report. Your description reminds me of the (still current @ 7.5) issue where mapping a variable to an enum will sometimes cause unrelated variables to self-convert to the same enum. This happened again yesterday, in applying an enum for socket(2, 0 ... aka socket(AF_UNIX, SOCK_STREAM... all my bool returns changed to return SOCK_STREAM;. TBF 7.5 is otherwise fairly impressive. e.g. I haven't had to map v1= a1; v2 = a2; v3 = a3 once! – Orwellophile Mar 1 at 8:50
  • @Orwellophile I know what you mean. I've so rarely gotten the option to split at a place where I need it, that I stopped looking for this function. I don't even use enum types anymore in my decompilations from the bogus they sometimes create. – Ray Mar 1 at 22:03
  • Good news everybody! I found the answer. You can only apply "ForceVar" to stack variables, not to registers -- which is naturally where one needs it, since register re-use is a lot more common than stack re-use. hex-rays.com/products/decompiler/manual/cmd_force_lvar.shtml – Orwellophile Mar 11 at 13:34
3

I don't think there's a way to add a new function variable, since the decompiler creates those based on registers and stack locations.

However, in situations where it's really annoying, creating a union type in the Structure viewer can be helpful.

Union Definition

Then, in your decompiler, set the type of the variable to the union type (Y is the keyboard shortcut). variable type declaration

In the disassembly, depending on the variable usage, you can use "Alt-Y" to select the appropriate union field. (it's also accessible in the right click menu) Union field select

2
  • Good idea. It would not be able to fix displaying of the variable in the second line, where the addressof operator is used on the merged variable (still displays only &pbdfOrLength without any member access), but I guess this is the best solution possible. – Ray May 8 '18 at 20:36
  • Bummer. I didn't realize it would act that way for the address operator. Appreciate the info. – mayahustle May 8 '18 at 21:48
0

I don't think there's any such feature in the IDA interface, nevertheless there's API in IDA SDK which allows you to create register variables: https://www.hex-rays.com/products/ida/support/sdkdoc/group__regvar.html#ga5f77d2c231f8faeb5939be2bc8e2a298

1
  • 1
    That doesn't create a new decompiler variable. That's for re-naming a variable in the disassembly (Put your cursor over a register and hit "N"). – mayahustle May 8 '18 at 19:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.