如何在IDA PRO中修复结构,以便它们在Hex-Rays插件(C反编译器)中正确显示。在IDA中可能会发生

几乎发生了什么事,我编译了一个非常好的程序,它可以正常工作,之后我对其进行了许多更改,现在它的工作情况比旧版本更糟,找出我做错了的事情(因为我现在丢失了源代码)以恢复到旧版本。 (我还在下面的原始代码中添加了用C ++编写的代码,这两个版本之间都没有更改。) >
*(_BYTE *)(shipsStruct + 279) = 1; //Ships[i].used = true;


应该真的是[10x4]=40+255= 295
*(_BYTE *)(shipsStruct + 295) = 1;  //Ships[i].used = true;


你可以在这里告诉结构尺寸(shipsStruct += 296;
我正在猜测以某种方式剥离未使用的结构成员(但是为什么结构尺寸有效?)。修复此问题的结构)?

当我尝试此技巧时,http://www.hexblog.com/?p = 63
选择mov edi, offset dword_10004C38行时,我的整个IDA PRO冻结了然后按T(IDA PRO 6.1)



我似乎错误地构造了结构?

这是反编译代码的样子(不使用结构)

  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 );
    }


这里是原始代码(未用C ++进行反编译)

q43 12078q

这是之前和之后(应用我的自定义结构)。
我通过做一堆数组(*键),然后设置适当的大小来完成了自定义结构。 (猜测这不是在IDA PRO中构建结构的正确方法吗?)
之前:之后: ASM:编辑功能双击局部变量

#1 楼

从上方...

反编译:

*(_DWORD *)(shipsStruct - 4) = playerPointer->ssXCoord;
*(_DWORD *)shipsStruct = playerPointer->ssYCoord;
...


原件:

Ships[i].XCoordinate = *(DWORD *) (playerPtr + 0x4);
Ships[i].YCoordinate = *(DWORD *) (playerPtr + 0x8);
...


>基于这些片段,堆栈变量中的结构看起来减少了8个字节。您可以与我们分享该函数的堆栈变量列表吗? (双击反编译中的局部变量之一以打开堆栈视图。)

评论


谈论这个? i.stack.imgur.com/2rANk.png此处:i.stack.imgur.com/9vKkW.png

– SSpoke
2013年12月31日在2:45



我应该冒险删除那些数据库吗? ;上面没有定义?以及IDA分析如何对此造成混乱。似乎关闭了12个字节(所有函数反编译都没有错误,顺便说一句)

– SSpoke
2013年12月31日在2:53



好的,我从0x68更改为0x5C,现在所有未定义都消失了,从var_5C开始仍然生成相同的C代码,并且一切看起来都一样,除了单击堆栈变量时,那里没有更多未定义变量。

– SSpoke
2013年12月31日下午3:06

shipsStruct是局部变量还是全局变量?

–詹森·格夫纳(Jason Geffner)
13年12月31日在3:44

好,shipsStruct是从(int)dword_10004C38本地声明的,这似乎是内存中的全局位置,我猜内存中的位置应该以某种方式表示偏移的结构。 ShipStruct是我给它命名的名称,实际上是假定将其转换为ShipStruct。当我将其转换为struct *时变成这样。

– SSpoke
2013年12月31日在3:51



#2 楼

从Hex-Rays 1.6开始支持此功能:

http://www.hexblog.com/?p=544

(请参见第3节CONTAINING_RECORD宏)