1

Hex-Rays generated C code is adding a lot of redundancy code, and I cannot figure out why and it really frustrates me to remove them manually on my reverse engineering process.

if ( v1 )
{
    v15.ObjectID = *(_DWORD *)Obj.ObjectID;
    v6 = AccessObject((Object)&v15);
    ObjectType::setTypeID(&v16, v6->Type.TypeID);
    v7 = ObjectType::getFlag(&v16, BANK);
    v4 = 0;
    if ( !v7 )
    {
      v16.TypeID = *(_DWORD *)Obj.ObjectID;
      v8 = AccessObject((Object)&v16);
      ObjectType::setTypeID((ObjectType *const )&v15, v8->Type.TypeID);
      v9 = ObjectType::getFlag((ObjectType *const )&v15, CLIP);
      v4 = 1;
      if ( !v9 )
      {
        v16.TypeID = *(_DWORD *)Obj.ObjectID;
        v10 = AccessObject((Object)&v16);
        ObjectType::setTypeID((ObjectType *const )&v15, v10->Type.TypeID);
        v11 = ObjectType::getFlag((ObjectType *const )&v15, BOTTOM);
        v4 = 2;
        if ( !v11 )
        {
          v16.TypeID = *(_DWORD *)Obj.ObjectID;
          v12 = AccessObject((Object)&v16);
          ObjectType::setTypeID((ObjectType *const )&v15, v12->Type.TypeID);
          v13 = ObjectType::getFlag((ObjectType *const )&v15, TOP);
          v4 = 3;
          if ( !v13 )
          {
            v16.TypeID = *(_DWORD *)Obj.ObjectID;
            v14 = AccessObject((Object)&v16);
            ObjectType::setTypeID((ObjectType *const )&v15, v14->Type.TypeID);
            v4 = (v15.ObjectID != 99) + 4;
          }
        }
      }
    }
  }
  else
  {
    error("GetObjectPriority: _bergebenes Objekt existiert nicht.\n");
    v4 = 0x7FFFFFFF;
  }

There's continous assigns to the v15 stack variable, which are making absolutely non-sense, I doubt the actual programmers of this binary had this intent.

I could have easily done it this way:

int32_t Priority = 0;
if (Object)
{
    if (!Object->getFlag(BANK))
    {
        Priority = 1;
        if (!Object->getFlag(CLIP))
        {
            Priority = 2;
            if (!Object->getFlag(BOTTOM))
            {
                Priority = 3;
                if (!Object->getFlag(TOP))
                {
                    Priority = (Object->TypeID != 99) + 4;
                }
            }
        }
    }
}
else
{
    std::cout << "GetObjectPriority: Object is NULL." << std::endl;
    Priority = -1;
}

return Priority;

How can I mess with IDA to stop this madness?

  • 2
    Welcome to C++, where one line of code may be expanded to hundreds of instructions if you're not careful :) – Igor Skochinsky Aug 19 '16 at 9:30
  • 1
    You should compare the C(++) code to the assembly, to check if the code is really there. To me, this reeks of a loop that got unrolled by the compiler (with the if parts originating from a break in the loop) so the assembly instructions are actually duplicated, which makes the decompiler generate code for all of them. Loop unrolling in a compiler isn't always easy, but i guess loop rolling in a decompiler would be way harder. – Guntram Blohm Aug 19 '16 at 19:33
1

Writing a good decompiler is hard. There are multiple challenges in the process. Writing a decompiler that has no redundant code in its output is even harder. Most decompilers still ouput high level code that resembles the assembly code it originated from, and that's what you see as redudant assignments.

There isn't really something you can do about it easily. You could try contacting IDA's support to get them to improve the decompiler. You could write an IDAPython script the implements the extra code simplifications. Or you could continue doing that manually.

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.