Ghidra: Detect typical for loops

Created on 31 May 2019  路  6Comments  路  Source: NationalSecurityAgency/ghidra

The decompiler takes a rather pessimistic approach and considers all loops to be while loops. For patterns known to be traditionally written using for loops, it should output the loop as a for loop instead.

Decompiler Enhancement

Most helpful comment

for instance,

void __thiscall SymbolTable(SymbolTable *this,int param_1)

{
  SymbolHashNode **ppSVar1;
  int iVar2;

  this->size = param_1;
  ppSVar1 = (SymbolHashNode **)
            operator_new__(-(uint)((int)((ulonglong)(uint)param_1 * 4 >> 0x20) != 0) |
                           (uint)((ulonglong)(uint)param_1 * 4));
  this->bucket = ppSVar1;
  iVar2 = 0;
  if (0 < this->size) {
    do {
      this->bucket[iVar2] = (SymbolHashNode *)0x0;
      iVar2 = iVar2 + 1;
    } while (iVar2 < this->size);
  }
  return;
}

may be converted to

void __thiscall SymbolTable::SymbolTable(SymbolTable *this, int param_1)
{
  SymbolTable *v2; 
  int i; 
  this->size = param_1;
  this->bucket = (SymbolHashNode **)operator new[](4 * param_1); // maybe too c++ish
  for ( i = 0; i < this->size; ++i )
    this->bucket[i] = 0;
}

it could also go further by noting that i's scope is the loop and write "int i = 0". Also note the rewrite of operator new's argument

All 6 comments

for instance,

void __thiscall SymbolTable(SymbolTable *this,int param_1)

{
  SymbolHashNode **ppSVar1;
  int iVar2;

  this->size = param_1;
  ppSVar1 = (SymbolHashNode **)
            operator_new__(-(uint)((int)((ulonglong)(uint)param_1 * 4 >> 0x20) != 0) |
                           (uint)((ulonglong)(uint)param_1 * 4));
  this->bucket = ppSVar1;
  iVar2 = 0;
  if (0 < this->size) {
    do {
      this->bucket[iVar2] = (SymbolHashNode *)0x0;
      iVar2 = iVar2 + 1;
    } while (iVar2 < this->size);
  }
  return;
}

may be converted to

void __thiscall SymbolTable::SymbolTable(SymbolTable *this, int param_1)
{
  SymbolTable *v2; 
  int i; 
  this->size = param_1;
  this->bucket = (SymbolHashNode **)operator new[](4 * param_1); // maybe too c++ish
  for ( i = 0; i < this->size; ++i )
    this->bucket[i] = 0;
}

it could also go further by noting that i's scope is the loop and write "int i = 0". Also note the rewrite of operator new's argument

@ryanmkurtz Any news for this issue? Are you devs working / planning to work on this?

No news that I am aware of, but I'll check with the right people and get back to you.

No one is working on it yet, but it's on the list of things to do. Unfortunately at this time I can't give you a prediction of when it will be started.

Thanks, good to know :+1:

I would also really like to see different types of loops be represented better by the decompiler. As you can see in the example provided by @Piruzzolo it would help clean up the code a lot, especially in larger, already complex functions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rrivera1849 picture rrivera1849  路  3Comments

loudinthecloud picture loudinthecloud  路  3Comments

chibicitiberiu picture chibicitiberiu  路  3Comments

toor-de-force picture toor-de-force  路  3Comments

astrelsky picture astrelsky  路  3Comments