通过添加减法修改公式

逆向工程 x86
2021-06-24 21:30:12

我在 x86 程序中有以下汇编代码,我需要修改它,因为它有问题:

fld     ds:(flt_203B8 - 29C48h)[ebx]
fdivr   dword ptr [esi+44h]
fmul    ds:(flt_203BC - 29C48h)[ebx]
fisttp  [ebp+var_334]
mov     eax, [ebp+var_334]
cmp     eax, 0Fh
jg      short greater

test    eax, eax
mov     edx, 0
cmovs   eax, edx
jmp     short valueWithinLimits


greater:
mov     eax, 0Fh

valueWithinLimits:
....

在伪代码中,这是

v29 = (signed int)(*(float *)(v3 + 68) / 40.0 * 15.0);
if ( v29 > 15 )
{
  v29 = 15;
}
else if ( v29 < 0 )
{
  v29 = 0;
}

我需要插入以下行作为第二行:

v29 = 15 - v29;

有什么办法可以在不需要更多空间的情况下做到这一点吗?我假设没有,但也许有人在这里有一个聪明的想法,在这种情况下可以做什么。

4个回答

很难说,因为您没有发布与伪代码相关的整个程序集。然而,似乎“if”块是通过跳转实现的。在这种情况下,您可以改用条件移动例如,假设“if”块是这样实现的(使用 28 个字节):

  cmp eax, 0Fh
  jg greater
  cmp eax, 0
  jl less
  jmp continue
less:
  mov [ebp+var_334], 0
  jmp continue
greater:
  mov [ebp+var_334], 0Fh
continue:

你可以像下面这样实现它:

  mov ebx, 0Fh
  cmp eax, 0Fh
  cmovg eax, ebx
  xor ebx, ebx
  cmp eax, 0
  cmovl eax, ebx
  mov [ebp+var_334], eax

此实现使用 22 个字节,比前一个低 6 个字节 - 正是在将结果存储到 v29 之前插入 fsubr 指令以计算 15 - st(0) 所需的空间。

考虑这个实现:

  xor ebx, ebx    ; ebx = 0
  mov bl, 15      ; ebx = 15
  neg eax         ; eax = -eax
  add eax, ebx    ; eax = 15 - eax
  cmp eax, ebx    
  cmovg eax, ebx
  xor ebx, ebx
  test eax, eax
  cmovs eax, ebx

它甚至更短(占用 20 个字节),完成整个工作并且不需要对浮点数进行额外操作。

实际上你的汇编代码并不完整。它匹配下一个伪代码:

v29 = (signed int)(*(float *)(v3 + 68) / 40.0 * 15.0);
如果 ( v29 > 15 )

如果 40.0 和 15.0 是常数,则可以去掉除法,只与 0.375 进行乘法运算。不知道这会节省多少空间。

你有缩放和偏移的代码,你需要缩放和偏移。因此,您根本不需要更改代码,只需更改常量即可。

将您的新操作倒推到现有数学中。更改您乘以的常量之一的符号,并通过乘法和符号更改返回偏移量,并将其与原始偏移量组合。