x86 装配问题 - 任何人都可以确定下面发生了啥吗?

Posted

技术标签:

【中文标题】x86 装配问题 - 任何人都可以确定下面发生了啥吗?【英文标题】:x86 Assembly Question - Can anyone determine what is happening below?x86 装配问题 - 任何人都可以确定下面发生了什么吗? 【发布时间】:2021-03-14 10:02:21 【问题描述】:

我为我玩的一个 20 多年前的游戏下载了一个修改,它是用汇编代码编写的。它添加了雾效果,然后基于此改变抓地力水平。但是,雾的级别似乎是随机选择的。

用受过训练的眼睛很容易看到下面发生的事情吗?我通过反汇编程序运行它,所以不确定它是否真的正确显示......

很容易发现递增的 0x33、0x34、0x35 等,所以我感觉很重要。

0x0000000000000000:  DD 35 00 00 00 00       fnsave dword ptr [0]
0x0000000000000006:  80 3D 00 00 00 00 B8    cmp    byte ptr [0], 0xb8
0x000000000000000d:  75 24                   jne    0x33
0x000000000000000f:  80 3D A8 11 55 00 02    cmp    byte ptr [0x5511a8], 2
0x0000000000000016:  0F 85 E6 00 00 00       jne    0x102
0x000000000000001c:  80 3D 00 00 00 00 00    cmp    byte ptr [0], 0
0x0000000000000023:  75 30                   jne    0x55
0x0000000000000025:  50                      push   eax
0x0000000000000026:  A1 04 B5 6C 00          mov    eax, dword ptr [0x6cb504]
0x000000000000002b:  A3 00 00 00 00          mov    dword ptr [0], eax
0x0000000000000030:  58                      pop    eax
0x0000000000000031:  EB 22                   jmp    0x55

0x0000000000000033:  80 3D B0 11 55 00 02    cmp    byte ptr [0x5511b0], 2
0x000000000000003a:  0F 85 C2 00 00 00       jne    0x102
0x0000000000000040:  80 3D 00 00 00 00 00    cmp    byte ptr [0], 0
0x0000000000000047:  75 0C                   jne    0x55
0x0000000000000049:  50                      push   eax
0x000000000000004a:  A1 0C B5 6C 00          mov    eax, dword ptr [0x6cb50c]
0x000000000000004f:  A3 00 00 00 00          mov    dword ptr [0], eax
0x0000000000000054:  58                      pop    eax
0x0000000000000055:  80 3D 00 00 00 00 33    cmp    byte ptr [0], 0x33
0x000000000000005c:  75 11                   jne    0x6f
0x000000000000005e:  D9 05 00 00 00 00       fld    dword ptr [0]
0x0000000000000064:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x000000000000006a:  E9 30 00 00 00          jmp    0x9f

0x000000000000006f:  80 3D 00 00 00 00 34    cmp    byte ptr [0], 0x34
0x0000000000000076:  75 11                   jne    0x89
0x0000000000000078:  D9 05 00 00 00 00       fld    dword ptr [0]
0x000000000000007e:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x0000000000000084:  E9 30 00 00 00          jmp    0xb9

0x0000000000000089:  80 3D 00 00 00 00 35    cmp    byte ptr [0], 0x35
0x0000000000000090:  75 11                   jne    0xa3
0x0000000000000092:  D9 05 00 00 00 00       fld    dword ptr [0]
0x0000000000000098:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x000000000000009e:  E9 30 00 00 00          jmp    0xd3

0x00000000000000a3:  80 3D 00 00 00 00 36    cmp    byte ptr [0], 0x36
0x00000000000000aa:  75 11                   jne    0xbd
0x00000000000000ac:  D9 05 00 00 00 00       fld    dword ptr [0]
0x00000000000000b2:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x00000000000000b8:  E9 30 00 00 00          jmp    0xed

0x00000000000000bd:  80 3D 00 00 00 00 37    cmp    byte ptr [0], 0x37
0x00000000000000c4:  75 11                   jne    0xd7
0x00000000000000c6:  D9 05 00 00 00 00       fld    dword ptr [0]
0x00000000000000cc:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x00000000000000d2:  E9 30 00 00 00          jmp    0x107

0x00000000000000d7:  80 3D 00 00 00 00 38    cmp    byte ptr [0], 0x38
0x00000000000000de:  75 11                   jne    0xf1
0x00000000000000e0:  D9 05 00 00 00 00       fld    dword ptr [0]
0x00000000000000e6:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x00000000000000ec:  E9 30 00 00 00          jmp    0x121

0x00000000000000f1:  D9 05 00 00 00 00       fld    dword ptr [0]
0x00000000000000f7:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x00000000000000fd:  E9 1F 00 00 00          jmp    0x121

0x0000000000000102:  E8 00 00 00 00          call   0x107
0x0000000000000107:  D9 05 00 00 00 00       fld    dword ptr [0]
0x000000000000010d:  D8 25 00 00 00 00       fsub   dword ptr [0]
0x0000000000000113:  D8 C9                   fmul   st(1)
0x0000000000000115:  D8 05 00 00 00 00       fadd   dword ptr [0]
0x000000000000011b:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x0000000000000121:  50                      push   eax
0x0000000000000122:  B8 01 00 00 00          mov    eax, 1
0x0000000000000127:  A3 00 00 00 00          mov    dword ptr [0], eax
0x000000000000012c:  B8 BE 00 00 00          mov    eax, 0xbe
0x0000000000000131:  A3 00 00 00 00          mov    dword ptr [0], eax
0x0000000000000136:  A3 00 00 00 00          mov    dword ptr [0], eax
0x000000000000013b:  A3 00 00 00 00          mov    dword ptr [0], eax
0x0000000000000140:  58                      pop    eax
0x0000000000000141:  E8 00 00 00 00          call   0x146
0x0000000000000146:  83 3D 00 00 00 00 00    cmp    dword ptr [0], 0
0x000000000000014d:  75 20                   jne    0x16f
0x000000000000014f:  50                      push   eax
0x0000000000000150:  A1 00 00 00 00          mov    eax, dword ptr [0]
0x0000000000000155:  A3 00 00 00 00          mov    dword ptr [0], eax
0x000000000000015a:  A1 00 00 00 00          mov    eax, dword ptr [0]
0x000000000000015f:  A3 00 00 00 00          mov    dword ptr [0], eax
0x0000000000000164:  A1 00 00 00 00          mov    eax, dword ptr [0]
0x0000000000000169:  A3 00 00 00 00          mov    dword ptr [0], eax
0x000000000000016e:  58                      pop    eax
0x000000000000016f:  D9 05 00 00 00 00       fld    dword ptr [0]
0x0000000000000175:  D8 35 00 00 00 00       fdiv   dword ptr [0]
0x000000000000017b:  D8 0D 00 00 00 00       fmul   dword ptr [0]
0x0000000000000181:  D9 E0                   fchs   
0x0000000000000183:  D8 05 00 00 00 00       fadd   dword ptr [0]
0x0000000000000189:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x000000000000018f:  D9 05 00 00 00 00       fld    dword ptr [0]
0x0000000000000195:  D8 35 00 00 00 00       fdiv   dword ptr [0]
0x000000000000019b:  D8 0D 00 00 00 00       fmul   dword ptr [0]
0x00000000000001a1:  D9 E0                   fchs   
0x00000000000001a3:  D8 05 00 00 00 00       fadd   dword ptr [0]
0x00000000000001a9:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x00000000000001af:  D9 EE                   fldz   
0x00000000000001b1:  D8 1D 00 00 00 00       fcomp  dword ptr [0]
0x00000000000001b7:  9B                      wait   
0x00000000000001b8:  DF E0                   fnstsw ax
0x00000000000001ba:  9E                      sahf   
0x00000000000001bb:  74 1E                   je     0x1db
0x00000000000001bd:  D9 05 00 00 00 00       fld    dword ptr [0]
0x00000000000001c3:  D8 35 00 00 00 00       fdiv   dword ptr [0]
0x00000000000001c9:  D8 0D 00 00 00 00       fmul   dword ptr [0]
0x00000000000001cf:  D8 05 00 00 00 00       fadd   dword ptr [0]
0x00000000000001d5:  D9 1D 00 00 00 00       fstp   dword ptr [0]
0x00000000000001db:  DD 25 00 00 00 00       frstor dword ptr [0]
0x00000000000001e1:  E9 00 00 00 00          jmp    0x1e6
  <Relocation>
      <FromVirtualAddress>004A56B9</FromVirtualAddress>
      <ToVirtualAddress>988700</ToVirtualAddress>
      <Type>0x0014</Type>
   </Relocation>

  <BinaryPatch>
      <VirtualAddress>0x00A0D308</VirtualAddress>
      <Data>
     00000000
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D30C</VirtualAddress>
      <Data>
     0AD7233C
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D314</VirtualAddress>
      <Data>
     CDCC4C3E
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D31C</VirtualAddress>
      <Data>
     CDCC4C3E
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D324</VirtualAddress>
      <Data>
     CDCC4C3E
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D32C</VirtualAddress>
      <Data>
     0000803E
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D330</VirtualAddress>
      <Data>
     00004040
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D334</VirtualAddress>
      <Data>
     00008040
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D338</VirtualAddress>
      <Data>
     0000A040
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D33C</VirtualAddress>
      <Data>
     0000C040
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D340</VirtualAddress>
      <Data>
     0000E040
      </Data>
   </BinaryPatch>

  <BinaryPatch>
      <VirtualAddress>0x00A0D344</VirtualAddress>
      <Data>
     0AD7233C
      </Data>
   </BinaryPatch>

   <Relocation>
      <FromVirtualAddress>988702</FromVirtualAddress>
      <ToVirtualAddress>00A0D0A0</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

   <Relocation>
      <FromVirtualAddress>988708</FromVirtualAddress>
      <ToVirtualAddress>0040E9C0</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

   <Relocation>
      <FromVirtualAddress>98871E</FromVirtualAddress>
      <ToVirtualAddress>00A0D304</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

   <Relocation>
      <FromVirtualAddress>98872C</FromVirtualAddress>
      <ToVirtualAddress>00A0D304</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

   <Relocation>
      <FromVirtualAddress>988742</FromVirtualAddress>
      <ToVirtualAddress>00A0D304</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

   <Relocation>
      <FromVirtualAddress>988750</FromVirtualAddress>
      <ToVirtualAddress>00A0D304</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

   <Relocation>
      <FromVirtualAddress>988757</FromVirtualAddress>
      <ToVirtualAddress>00A0D304</ToVirtualAddress>
      <Type>0006</Type>
   </Relocation>

【问题讨论】:

代码看起来像是一个可重定位对象,但尚未修补重定位信息(因此所有 [0] 操作数)。像这样不太容易理解。 【参考方案1】:

使用绝对地址0 很奇怪,大概有某种重定位来修复这些地址。但是你的反汇编并没有显示出来。如果它是标准的对象文件格式,您可以使用objdump -dr -Mintel foo.o 来包含重定位元数据。

但无论如何,它使用fnsave 转储 x87 FPU 状态。

可能后面的地址具有不同的重定位修复元数据,即使它们在您转储的代码中都是[0]。 fsave 区域的开头得到FPUControlWord,从该位置到fld / fstp 4 个字节是没有意义的。

几乎可以肯定fld dword ptr [0]/fstp dword ptr [0] 正在两个其他位置之间复制float 值,而不是加载/存储 FPU 控制和状态字,作为 4 字节单精度 float。 (如果数据表示 NaN,可能会修改数据。)因此我们必须得出结论,每个[0] 寻址模式实际上可以是任何地址,无论是否在 fsave 区域内。 (fsave 区域中的浮点数将是 80 位 x87 格式,而不是 32 位(dword)单精度,因此fld dword 不太可能对它们进行操作。)

带有 0x33 .. 0x38 的 cmp 可能正在查看 x87 状态字的一个字节,也许是为了找出保存区域中的哪个插槽是当前的栈顶?不,状态字位不在字节的底部。但是比较结果(C2、C1、C0)在状态字(http://www.ray.masmcode.com/tutorial/fpuchap1.htm)的高字节的底部,而异常状态位在低字节的底部。

因此,这条比较/分支链可能正在 fsave 区域中寻找某些东西。 或者更有可能它只是检查游戏数据的某个字节的几个可能值之一。注意它如何在不等于时跳转到下一个 cmp/jne。 所以这是 if/else 链,或者是实现 switch/case 0x33: / case 0x34: / ... 语句的一种方式。

围绕整个事情的fnsave / frstor 可能是一个红鲱鱼,它可能根本不会在这些数据中四处寻找。相反,它可能只是保存/恢复 FPU 状态,因此它可以使用 x87 指令本身而不会弄乱主程序。我最初认为它正在读取保存区域,因为[0] 地址,但似乎很明显,重定位可能会将该地址指向程序数据的其他部分,而不仅仅是这个补丁自己的私有存储。

【讨论】:

是的,正在进行一些搬迁。我刚刚用一些值更新了原始帖子,但我不知道这些值的含义。

以上是关于x86 装配问题 - 任何人都可以确定下面发生了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章

我们可以确定 iCloud 文件包中发生了啥变化吗?

Azure 启动运行手册停止工作,不确定发生了啥?

有人可以解释一下这里发生了啥吗?存在普遍量化

我的 Internet 浏览器每次都会自动打开和关闭 HTML 侧边栏。我怎样才能阻止它,发生了啥?

iOS 7.1.2:iBeacon 真正发生了啥变化?

在 iOS 中删除内存映射文件 - 幕后发生了啥?