这可能是一个用 C 反编译的 Math.Min 函数吗?

逆向工程 部件 反编译
2021-06-24 13:26:36

我喜欢用类似内存调整大小功能多数民众赞成在工作realloc/ redimVB中。

反编译的前 3 行看起来像

char *__cdecl ExpandMemory(void *lpAddress, signed int StartPos, signed int MaxSize)
{
    int NewSize; // edi@3

    if ( StartPos > 0x80000 )
        MaxSize = 16 * MaxSize;
    NewSize = MaxSize * (MaxSize + StartPos - 1) / MaxSize;
    //Lots of stuff goes here
}

有人能告诉我这条线应该做什么吗

NewSize = MaxSize * (MaxSize + StartPos - 1) / MaxSize;

我有一种非常强烈的感觉它是一个Math.MIN()没有功能?:

由于 MIN 函数是这样声明的

#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))

我不明白这个数学如何与它相似,有人可以解释它应该做什么。

据我所知,它甚至无法正常工作,不断创建一个远大于 MaxSize 的 NewSize,如果它可以工作,有人可以解释它实际上是如何工作的吗?在大多数情况下,MaxSize 参数通常1表示没有限制并且仅使用 StartPos,在使用 MaxSize 的情况下,它通常是 65536 或 2048 一些二进制值。但这与二进制无关。

在 ASM 中,代码如下所示

.text:004083BC                 lea     eax, [ecx+eax-1]
.text:004083C0                 cdq
.text:004083C1                 idiv    ecx
.text:004083C3                 mov     edi, eax
.text:004083C5                 imul    edi, ecx
.text:004083C8                 mov     ecx, [esp+114h+arg_0]

完整的反编译源码:

char *__cdecl ExpandMemory(void *a1, signed int NewSize, signed int MaxSize)
{
  signed int HowMuchBiggerr; // ecx@1
  int NewSizee; // edi@3
  char *v5; // eax@5
  char *v6; // esi@8
  char *result; // eax@13
  void *v8; // eax@15
  signed int v9; // esi@18
  int v10; // edi@18
  char *v11; // eax@22
  char *v12; // eax@27
  char *v13; // ebp@30
  unsigned int v14; // ecx@35
  void *Memory; // [sp+10h] [bp-104h]@18
  char Text[256]; // [sp+14h] [bp-100h]@11

  HowMuchBiggerr = MaxSize;
  if ( NewSize > (signed int)0x80000u )
    HowMuchBiggerr = 16 * MaxSize;
  NewSizee = HowMuchBiggerr * (HowMuchBiggerr + NewSize - 1) / HowMuchBiggerr;
  if ( a1 )
  {
    if ( NewSizee )
    {
      v9 = *((_DWORD *)a1 - 1);                 // Okay minus 4 bytes from beginning of pointed data is size? (must be a special structure of some kind)
      v10 = NewSizee + 4;
      Memory = (char *)a1 - 4;
      if ( v10 == v9 )                          // Check if special attribute (Size?) exists and equals the New Size so it can ignore it.
      {
        result = (char *)a1;
      }
      else
      {
        if ( v9 > (signed int)0x80000u || v10 > (signed int)0x80000u )
        {
          if ( v10 <= (signed int)0x80000u )
            v12 = (char *)malloc(v10);
          else
            v12 = (char *)VirtualAlloc(0, v10, 0x1000u, 4u);
          if ( v12 )
          {
            *(_DWORD *)v12 = v10;
            v13 = v12 + 4;
          }
          else
          {
            v13 = 0;
          }
          if ( !v13 )
          {
            sprintf(Text, "Out of memory (Alloc:%d)", v10 - 4);
            MessageBoxA(0, Text, "Error", 0x30u);
            exit(1);
          }
          v14 = v9 - 4;
          if ( v9 - 4 >= v10 - 4 )
            v14 = v10 - 4;
          memcpy(v13, a1, v14);
          if ( *(_DWORD *)Memory <= (signed int)0x80000u )
          {
            free(Memory);
            result = v13;
          }
          else
          {
            VirtualFree(Memory, 0, 0x8000u);
            result = v13;
          }
        }
        else
        {
          v11 = (char *)realloc((char *)a1 - 4, v10);
          if ( !v11 )
          {
            MessageBoxA(0, "Out of memory (Resize)", "Error", 0x30u);
            exit(1);
          }
          *(_DWORD *)v11 = v10;
          result = v11 + 4;
        }
      }
    }
    else
    {
      v8 = (char *)a1 - 4;
      if ( *((_DWORD *)a1 - 1) <= (signed int)0x80000u )
      {
        free(v8);
        result = 0;
      }
      else
      {
        VirtualFree(v8, 0, 0x8000u);
        result = 0;
      }
    }
  }
  else
  {
    if ( NewSizee + 4 <= (signed int)0x80000u )
      v5 = (char *)malloc(NewSizee + 4);
    else
      v5 = (char *)VirtualAlloc(0, NewSizee + 4, 0x1000u, 4u);
    if ( v5 )
    {
      *(_DWORD *)v5 = NewSizee + 4;
      v6 = v5 + 4;
    }
    else
    {
      v6 = 0;
    }
    if ( !v6 )
    {
      sprintf(Text, "Out of memory (Alloc:%d)", NewSizee);
      MessageBoxA(0, Text, "Error", 0x30u);
      exit(1);
    }
    result = v6;
  }
  return result;
}
1个回答

对我来说,这看起来像是天花板的常见模式

换句话说NewSize = ceil(StartPos/MaxSize) * MaxSize,就是将其四舍五入到最接近的MaxSize大于StartPos.