我目前正在研究游戏(《灵魂掠夺者:凯恩的遗产》),经常在反编译器中遇到类似这样的怪异部分。



  *(_DWORD *)(a2 + 16) = a2 + 624;
  *(_DWORD *)(a2 + 38200) = a2 + 8;
  *(_DWORD *)(a2 + 20) = 0;
  *(_DWORD *)(a2 + 37592) = 0;
  *(_DWORD *)(a2 + 37596) = a2 + 36968;
  *(_DWORD *)(a1 + 8) = a2;
  *(_DWORD *)a1 = 0;
  *(_DWORD *)(a1 + 4) = 0;


在我看来,这些似乎是结构中的偏移量,但是其中一些偏移量没有什么意义,例如36968。我知道很难确定,但是一些正确方向的指针将不胜感激:)

为那些想要的人组装:)



.text:004B0126                   xor     esi, esi
.text:004B0128                   mov     [ecx+10h], eax
.text:004B012B                   lea     eax, [ecx+8]
.text:004B012E                   mov     [ecx+9538h], eax
.text:004B0134                   mov     eax, [esp+4+arg_0]
.text:004B0138                   lea     edx, [ecx+9068h]
.text:004B013E                   mov     [ecx+14h], esi
.text:004B0141                   mov     [ecx+92D8h], esi
.text:004B0147                   mov     [ecx+92DCh], edx
.text:004B014D                   mov     [eax+8], ecx
.text:004B0150                   mov     [eax], esi
.text:004B0152                   mov     [eax+4], esi


#1 楼

在内部具有大型数组或其他结构的结构或对象中没有什么奇怪的。此外,我看到大多数较大的偏移量都是从ecx寄存器计数的,这符合__thiscall调用约定的Visual Studio变体的定义。因此,我认为这只是大型结构或物体。另外-IDA中的结构不是要还原原始结构,而是要在已创建的代码中构造结构,因此,如果它可以更好地组织生成的代码,为什么仍然不使用它呢?

无论如何,您可以检查分配此参数的内存的来源。如果看到它是用单个mallocnew运算符分配的,则它应该是单个对象/结构或对象/结构的数组。

(来自x86调用约定Wiki文章的引号)


在Microsoft Visual C ++编译器上,此指针在
ECX中传递,并且被调用方清理堆栈,并镜像C在此编译器中使用的stdcall约定。 Windows API函数。
当函数使用可变数量的参数时,调用方
会清理堆栈(请参阅cdecl)。只能在Microsoft Visual C ++ 2005和更高版本上显式指定thiscall调用约定。
在任何其他编译器上,thiscall都不是关键字。 (但是,
反汇编程序(例如IDA)必须指定它。因此IDA为此使用关键字
__thiscall。)


评论


非常感谢您的回答。我还应该提到它是使用Visual C ++ 6.0编译的。到目前为止,我几乎没有遇到任何新的或malloc发生的情况(由于它是从PS1移植而来的,它似乎使用了自己的内存分配系统,而PS1是malloc的包装器)。我了解IDA如何主要使用结构来组织程序集并使其更易于阅读。它让我失望的主要原因是偏移量之间的巨大差异,而且所写的值似乎无法填补这些空白。再次感谢您的回答,这是非常有用的:)

– MicroTransactionsMatterToo
17 Mar 10 '17在14:00