IDA PRO Structures 定义负偏移 -4 -8 偏移修复 asm Hex-Rays

逆向工程 艾达 结构
2021-06-29 21:22:28

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

类似的问题:(但该解决方案对我不起作用)
可能在 IDA 中使用负偏移量进行结构化

几乎发生的事情是我编译了一个非常好的程序并且它运行正常,之后我对它做了很多更改,现在它比旧版本运行得更糟,我试图找出我做错了什么(因为我丢失了源代码)恢复到旧版本。(我还在用 C++ 编写的原始代码段下面添加了,这两个版本之间没有变化)。

在 IDA PRO 中以某种方式优化了结构的地址,例如

*(_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并按下 T (IDA PRO 6.1)时,我的整个 IDA PRO 都冻结了

结构偏移

似乎我错误地制作了结构?

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

  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++ 编写的反编译)

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

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

2个回答

自 Hex-Rays 1.6 起支持此功能:

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

(参见第 3 节 CONTAINING_RECORD 宏)

从上面...

反编译:

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

原来的:

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

根据这些片段,您的堆栈变量中的结构看起来像是 8 个字节。您能否与我们分享该函数的堆栈变量列表?(在反编译中双击局部变量之一打开堆栈视图。)