View Single Post
  #2  
Old 01-20-2018, 02:14
leader leader is offline
Friend
 
Join Date: Oct 2017
Posts: 10
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 15
Thanks Rcvd at 3 Times in 2 Posts
leader Reputation: 0
Hi,

I have a problem with the analyze one function.
I think this function make the decompression of the code in the memory.
It has many integer overflow checks and it will be overflow in short time:

Code:
char *__fastcall sub_9F92(char *a1, int a2, _BYTE *a3, _DWORD *a4)
{
  char *v4; // r7
  unsigned int v5; // r5
  int v6; // r4
  char *result; // r0
  char v8; // r3
  unsigned __int8 v9; // cf
  int i; // r1
  int v11; // r1
  unsigned __int8 v12; // cf
  unsigned __int8 v13; // cf
  int v14; // r4
  unsigned int v15; // r1
  unsigned __int8 v16; // cf
  int v17; // r3
  signed int v18; // r1
  int v19; // r5
  int v20; // r5
  unsigned __int8 v21; // cf
  unsigned __int8 v22; // cf
  unsigned __int8 v23; // cf
  int v24; // r4
  unsigned __int8 v25; // cf
  int v26; // r1
  unsigned __int8 v27; // cf
  int v28; // r3
  _BYTE *v29; // [sp+0h] [bp-1Ch]
  _DWORD *v30; // [sp+4h] [bp-18h]

  v29 = a3;
  v30 = a4;
  v4 = &a1[a2];
  v5 = -1;
  v6 = 0x80000000;
  while ( 1 )
  {
    v9 = __CFADD__(v6, v6);
    v6 *= 2;
    if ( !v6 )
      return a1 + 1;
    if ( !v9 )
    {
      for ( i = 1; ; i = v11 + v12 + v11 )
      {
        v13 = __CFADD__(v6, v6);
        v14 = 2 * v6;
        if ( !v14 )
          return a1 + 1;
        v15 = i + v13 + i;
        v16 = __CFADD__(v14, v14);
        v6 = 2 * v14;
        if ( !v6 )
          return a1 + 1;
        if ( v16 )
          break;
        v11 = v15 - 1;
        v12 = __CFADD__(v6, v6);
        v6 *= 2;
        if ( !v6 )
          return a1 + 1;
      }
      v9 = v15 >= 3;
      v17 = v15 - 3;
      v18 = 0;
      if ( v9 )
      {
        v19 = (unsigned __int8)*a1++;
        v20 = ~(v19 | (v17 << 8));
        if ( !v20 )
        {
          result = (char *)(a1 - v4);
          *v30 = a3 - v29;
          return result;
        }
        v9 = v20 & 1;
        v5 = v20 >> 1;
        if ( !v9 )
        {
LABEL_21:
          v18 = 1;
          v22 = __CFADD__(v6, v6);
          v6 *= 2;
          if ( !v6 )
            return a1 + 1;
          if ( !v22 )
          {
            while ( 1 )
            {
              v23 = __CFADD__(v6, v6);
              v24 = 2 * v6;
              if ( !v24 )
                break;
              v18 += v23 + v18;
              v25 = __CFADD__(v24, v24);
              v6 = 2 * v24;
              if ( !v6 )
                break;
              if ( v25 )
              {
                v26 = v18 + 4;
                goto LABEL_30;
              }
            }
            return a1 + 1;
          }
        }
      }
      else
      {
        v21 = __CFADD__(v6, v6);
        v6 *= 2;
        if ( !v6 )
          return a1 + 1;
        if ( !v21 )
          goto LABEL_21;
      }
      v27 = __CFADD__(v6, v6);
      v6 *= 2;
      if ( !v6 )
        return a1 + 1;
      v26 = v18 + v27 + v18 + 2;
LABEL_30:
      if ( v5 < 0xFFFFFB00 )
        ++v26;
      v28 = (unsigned __int8)*a3;
      do
      {
        *a3 = a3[v5];
        ++a3;
        --v26;
      }
      while ( v26 );
      continue;
    }
    v8 = *a1++;
    *a3++ = v8;
  }
}
The function arguments are:
- a1 => compressed code buffer
- a2 => length of compressed code buffer
- a3 => To this address will be decompressed the the code
- a4 => I think it will store the lengh of decompressed code (not sure)

__CFADD__ check if the sum of 2 integers is overflow or not. Tipically used to check the sum of the same integer.
There is another overflow check by multiply the integer with 2 (For example v6 *= 2)

As you see the inital value of integer v6 is 0x80000000, so it produce very fast overflow and the function will return without decompressing the code.

I try to reproduce this ARM code on X86 but without success. I spent many time on it, but I can not understand the purpose of this overflow checks and how the decompression made.

I would be very pleased with all your useful ideas.

Thanks,
leader

Last edited by leader; 01-20-2018 at 02:32. Reason: Put formated code into CODE section instead of QUOTE...
Reply With Quote