How do I fix structures in IDA PRO so they show up properly in Hex-Rays plugin (C decompiler).
Similar question to: (But the solution doesn't work for me)
Struct with negative offset in IDA possible
Pretty much what happened is I compiled a very good program and it works right, after that I did many changes to it and now it works worse then the older version, I'm trying to figure out what I did wrong (since I lost the source code now) to revert back to the old version. (I also added below the original piece of the code written in C++, which didn't change between both versions).
Structure's addresses somehow optimized in IDA PRO Such as that
*(_BYTE *)(shipsStruct + 279) = 1; //Ships[i].used = true;
should really be [10x4]=40+255= 295
*(_BYTE *)(shipsStruct + 295) = 1; //Ships[i].used = true;
You can tell the structure size right here (shipsStruct += 296;
)
I'm guessing somehow the un-used structure members are stripped out (but why is the structure size valid?).
Seems the assembly somehow is offset wrongly (how do I add the proper offset deltas to the struct to fix this)?
When I try this tip http://www.hexblog.com/?p=63
My whole IDA PRO freezes up when I select the line mov edi, offset dword_10004C38
and press T (IDA PRO 6.1)
Seems I made my struct incorrectly?
Here is how the code decompiled code looks like (without applying structure)
if ( playerListBaseAddress && !IsBadReadPtr(playerListBaseAddress, 4u) )
{
shipsStruct = (int)dword_10004C38;
while ( 1 )
{
playerPointer = (struct_v3 *)*((_DWORD *)playerListBaseAddress + maxPlayers);
if ( !playerPointer )
break;
if ( IsBadReadPtr(playerPointer, 4u) )
break;
*(_DWORD *)(shipsStruct - 4) = playerPointer->ssXCoord;
*(_DWORD *)shipsStruct = playerPointer->ssYCoord;
*(_DWORD *)(shipsStruct + 4) = playerPointer->ssXSpeed;
*(_DWORD *)(shipsStruct + 8) = playerPointer->ssYSpeed;
*(_DWORD *)(shipsStruct - 8) = playerPointer->ssFreq;
*(_DWORD *)(shipsStruct + 20) = playerPointer->ssShipNum;
if ( playerPointer->ssPlayerName )
strcpy_s((char *)(shipsStruct + 24), 0xFFu, &playerPointer->ssPlayerName);
*(_BYTE *)(shipsStruct + 279) = 1;
if ( v37 == playerPointer )
break;
shipsStruct += 296;
++maxPlayers;
v37 = playerPointer;
if ( shipsStruct >= (signed int)&unk_10017310 )
goto finish;
}
v34 = maxPlayers;
if ( maxPlayers < 255 )
{
v4 = (int)((char *)&unk_10004D4F + 296 * maxPlayers);
do
{
*(_BYTE *)v4 = 0;
v4 += 296;
}
while ( v4 < (signed int)&unk_10017427 );
}
Here is the orginal code (not decompiled written in C++)
double currentTimer = GetTimer();
double timeElapsed = currentTimer - lastTimer;
int maxPlayers = 0;
DWORD lastPlayerPtr = 0;
if (playerListBaseAddress != NULL && !IsBadReadPtr((void *) playerListBaseAddress, sizeof(ULONG_PTR))) {
for (int i = 0; i < 255; i++) { //populate player ship list.
DWORD playerPtr = *(DWORD *) (playerListBaseAddress + (i * 4));
if (playerPtr != NULL && !IsBadReadPtr((void *) playerPtr, sizeof(ULONG_PTR))) {
Ships[i].XCoordinate = *(DWORD *) (playerPtr + 0x4);
Ships[i].YCoordinate = *(DWORD *) (playerPtr + 0x8);
Ships[i].XSpeed = *(signed long *) (playerPtr + 0x10);
Ships[i].YSpeed = *(signed long *) (playerPtr + 0x14);
Ships[i].Freq = *(DWORD *) (playerPtr + 0x58);
Ships[i].ShipNum = *(BYTE *) (playerPtr + 0x5C)
//memcpy(&(Ships[i].Name), (void*)((DWORD)playerPtr+0x6D), 19);
if (!*(BYTE *) (playerPtr + 0x6D) == NULL)
strcpy_s(Ships[i].Name, (char *) ((DWORD) playerPtr + 0x6D));
Ships[i].used = true;
if (lastPlayerPtr == playerPtr)
goto finishList;
lastPlayerPtr = playerPtr;
} else {
finishList:
maxPlayers = i;
for (int j = i; j < 255; j++)
Ships[j].used = false;
break;
}
}
Here is before and after (applying my custom struct)
I did the custom struct by doing a bunch of Arrays (* key), then setting proper sizes. (Guessing this isn't the proper way to make a structure in IDA PRO?)
Before:
After:
ASM:
Edit Function
Double clicked local variable