Exetools  

Go Back   Exetools > General > General Discussion

Notices

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #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
 

Tags
wince dll unpack

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
WinCE Floating-Point operators - HELP leader General Discussion 0 01-31-2018 03:18


All times are GMT +8. The time now is 21:32.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )