/*\
|*|
|*| Skype 4142 Decompression v1.002 by Sean O'Neil.
|*| Copyright (c) 2004-2009 by VEST Corporation.
|*| All rights reserved. Strictly Confidential!
|*|
|*| Date: 29.10.2009
|*|
\*/

#include "skype_basics.h"
#pragma warning(disable:4311 4312)

u8 unpack_42_CF2848[8] = {0, 0, 0, 0, '%', 's', 0, 0};

extern void * malloc_719490(void * *the_ptr, u32 bytes);
extern u32 pack_42_find_code_76A070(u32 *code_array, u32 look_for);
extern u32 pack_42_init_769FB0(u32 ctx);
extern u32 pack_42_thing1_E3B7F4[];
extern u16 pack_42_word_E3B7A0[];
extern u32 pack_42_thing2_E3B804[];
extern u16 * pack_42_word_off_E3B748[];

char *unpack_42_off_E3B054[11] =
{
	"",
	"tdmhkpcgwbzfvjq",
	"eaiouy",
	"nrlsx",
	"0216345789",
	"SMTBRLNPKCDHGJWFVZXQ",
	"AEIOUY",
	" ",
	"\x82\x99\xB8\xB3\xA9\x81\xBC\x9C\x85\x95\xA1\x9B\xA8\x84\xB0\x90\x80\xB6\x94\xA4\x91\xBA\x9E\x9A\xA0\xB5\xBD\xBE\xA7\x9D\x97\xA5\x9F\xAA\xB1\x83\x8C\x93\xB2\x98\xA6\xA2\xBB\x88\xAD\x96\x8F\xB4\xA3\x92\xBF\x87\xB7\x8B\x8D\xB9\x89\x8A\x8E\xAE\x86\xAC\xAB\xAF",
	"\xD7\xC3\xD0\xC5\xE5\xC4\xE3\xD1\xE6\xE7\xEC\xE4\xE8\xEF\xE9\xD9\xD8\xEB\xEA\xE2\xC2\xE0\xED\xC6\xDB\xE1\xCE\xCF\xC0\xC1\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xD2\xD3\xD4\xD5\xD6\xDA\xDC\xDD\xDE\xDF\xEE\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF",
	"\x2E\x2D\x2F\x5F\x21\x2B\x2C\x29\x3A\x28\x2A\x3F\x0D\x0A\x27\x26\x22\x3D\x3B\x7E\x40\x3E\x3C\x7C\x5E\x5D\x5B\x5C\x23\x60\x24\x25\x7B\x7D\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F"
};

u8 Load_Byte(u32 ctx)
{
  u32 *bytes; // eax@1
  u8 b; // al@4
  u8 **byte_ptr; // ecx@5
/*
  u32 i;
  u8 c[333*4];

  memcpy (c, (void *)ctx, sizeof(c));
  dword(c,0x1F6) = 0xCCCCCCCC;
  dword(c,0x1FA) = 0xCCCCCCCC;
  dword(c,0x202) = 0xCCCCCCCC;
  dword(c,0x20E) = 0xCCCCCCCC;
  dword(c,0x212) = 0xCCCCCCCC;
  dword(c,0x312) = 0xCCCCCCCC;
  dword(c,0x51E) = 0xCCCCCCCC;
  for (i = 0; i < 333*4; i++)
  {
	  if ((i&15)==0) printf ("\n%04X:", i);
	  printf (" %02X", c[i]);
  }
  printf ("\n");
*/
  bytes = (u32 *)dword(ctx,0x1FA);
  if ( *bytes )
  {
    --*bytes;
    byte_ptr = (u8 **)dword(ctx,0x1F6);
    b = *(*byte_ptr)++;
  }
  else
  {
    ++dword(ctx,0x1FE);
    if ( dword(ctx,0x1FE) > 3 ) dword(ctx,0x202) = 1;
    b = 0;
  }
  return b;
}

void unpack_42_769E50(u32 ctx)
{
  u32 v2; // al@2

  for ( ; dword(ctx,8) <= 0x800000; byte(ctx,12) = (u8)v2 )
  {
    dword(ctx,4) = (2 * dword(ctx,4) | byte(ctx,12) & 1) << 7;
    v2 = Load_Byte(ctx);
    dword(ctx,8) <<= 8;
    dword(ctx,4) |= v2 >> 1;
  }
}

u32 pack_42_bits_769F30(u32 ctx, u8 bits)
{
  u32 result; // eax@1
  u32 v4; // edi@1

  unpack_42_769E50(ctx);
  v4 = dword(ctx,8) >> bits;
  result = dword(ctx,4) / v4;
  if ( result >> bits ) result = (1 << bits) - 1;
  dword(ctx,4) -= v4 * result;
  if ( (result + 1) >> bits ) dword(ctx,8) -= v4 * result; else dword(ctx,8) = v4;
  return result;
}

u32 unpack_42_769EA0(u32 ctx, u16 *word_array)
{
  u32 v2; // ecx@1
  u32 v3; // ebx@1
  u32 v6; // eax@3
  u32 result; // eax@5
  u32 v8; // ecx@5
  u32 v9; // ebp@5

  unpack_42_769E50(ctx);
  v3 = dword(ctx,8) >> 12;
  v2 = dword(ctx,4) / v3;
  if ( v2 & 0xFFFFF000 ) v2 = 0xFFF;
  v6 = 1;
  if ( word_array[1] <= v2 ) while ( word_array[++v6] <= v2 );
  v8 = word_array[v6];
  v9 = word_array[v6-1];
  result = v6 - 1;
  dword(ctx,4) -= v3 * v9;
  if ( v8 & 0xFFFFF000 ) dword(ctx,8) -= v3 * v9;
  else dword(ctx,8) = v3 * (v8 - v9);
  return result;
}

u32 unpack_42_769F30(u32 ctx, u32 bits)
{
  u32 result; // eax@1
  u32 v4; // edi@1

  unpack_42_769E50(ctx);
  v4 = dword(ctx,8) >> bits;
  result = dword(ctx,4) / v4;
  if ( (u32)result >> bits ) result = (1 << bits) - 1;
  dword(ctx,4) -= v4 * result;
  if ( (u32)(result + 1) >> bits ) dword(ctx,8) -= v4 * result;
  else dword(ctx,8) = v4;
  return result;
}

u32 unpack_42_dword_76ADE0(u32 ctx, u32 *word_ptr, u32 a3)
{
  u32 result; // eax@1
  u32 v5;
  u32 v6; // esi@2
  u32 v7; // eax@4
  u32 v8; // edi@4
  u32 v9; // ebp@7
  u32 v10; // edi@7
  u32 v11; // esi@7
  u32 v15; // ebx@11
  u32 v16; // edx@11

  result = unpack_42_769EA0(ctx, (u16 *)word_ptr[3]);
  if ( result >= ((u32)1 << word_ptr[1]) )
  {
    v6 = result - word_ptr[2];
    if ( v6 >= word_ptr[0] )
    {
      if ( a3 || (v7 = unpack_42_dword_76ADE0(ctx, word_ptr, 1), v8 = word_ptr[0], v7 > 32 - v8) )
      {
        dword(ctx,0x202) = 1;
        return 0;
      }
      v6 = v8 + v7;
    }
    v11 = v6 - 1;
    v9 = 1 << v11;
    v10 = 0;
    if ( v6 > 1 )
    {
      v5 = 16;
      do
      {
		v15 = __min ( v11 - v10, 16 );
        v16 = (u16)unpack_42_769F30(ctx, v15) << (u8)v10;
        v10 += v15;
        v9 += v16;
      }
      while ( v10 < v11 );
    }
    result = v9;
  }
  return result;
}

u32 unpack_42_76AEA0(u32 a1, u32 ctx)
{
  u32 v2; // eax@1
  u32 result; // eax@2

  v2 = dword(ctx,0x20E);
  if ( *(u32 *)v2 >= a1 )
  {
    *(u32 *)v2 -= a1;
    result = 1;
  }
  else
  {
    dword(ctx,0x202) = 1;
    result = 0;
  }
  return result;
}

void unpack_42_from_9944D0(u32 *where_from)
{
  u32 v3, *where_to; // eax@2

  v3 = where_from[65] + 1;
  if ( v3 > where_from[66] )
  {
    v3 = where_from[65] + 32;
    where_from[66] = v3;
    if ( where_from[64] == (u32)where_from ) where_from[64] = 0;
    where_to = (u32 *)where_from[64];
    malloc_719490((void * *)&where_to, 8 * v3);
    if ( !where_from[64] ) memcpy(where_to, where_from, 8 * where_from[65]);
    where_from[64] = (u32)where_to;
  }
}

u32 *unpack_42_from_951460(u32 *where_from)
{
  u32 *result; // eax@3

  if ( where_from[65] >= where_from[66] ) unpack_42_from_9944D0(where_from);
  result = (u32 *) (where_from[64] + 8 * where_from[65]);
  where_from[65]++;
  if ( result )
  {
    result[0] = 0;
    result[1] = 0;
  }
  return result;
}

void unpack_42_inc_85BEE0(u32 increment, u32 ctx)
{
  u32 v3; // eax@1
  u32 v4; // eax@2
  u32 v5; // esi@4
  u32 v7; // [sp+0h] [bp-4h]@1

  v3 = increment + dword(ctx,0x204);
  if ( (u32)v3 > dword(ctx,0x208) )
  {
    v4 = v3 + 0x1FF;
    dword(ctx,0x208) = v4;
    if (dword(ctx,0x200) == ctx) dword(ctx,0x200) = 0;
    v7 = dword(ctx,0x200);
    malloc_719490((void * *)&v7, v4);
    v5 = v7;
    if ( !dword(ctx,0x200) ) memcpy((void *)v7, (void *)ctx, dword(ctx,0x204));
    dword(ctx,0x200) = v5;
  }
}

u32 unpack_42_byte_85BDC0(u32 ctx, u32 the_byte)
{
  u32 str; // eax@3
  u32 v4; // ecx@3
  u32 v5; // eax@3

  if ( dword(ctx,0x204) >= dword(ctx,0x208) ) unpack_42_inc_85BEE0(1, ctx);
  v4 = dword(ctx,0x204);
  v5 = dword(ctx,0x200);
  str = v4 + v5;
  dword(ctx,0x204) = v4 + 1;
  if (str) *(u8 *)str = *(u8 *)the_byte;
  return str;
}

void unpack_42_inc_76AD90(u32 ctx, u32 increment)
{
  u32 *v2; // ecx@1

  v2 = (u32 *)dword(ctx,0x1FA);
  dword(ctx,0x206) += increment;
  if ( *v2 < increment )
  {
    dword(ctx,0x1FE) += increment - *v2;
    *(u8 **)dword(ctx,0x1F6) += *v2 - increment;
    *(u32 *)dword(ctx,0x1FA) = 0;
    if ( dword(ctx,0x1FE) > 3 ) dword(ctx,0x202) = 1;
  }
  else
  {
    *v2 -= increment;
  }
}

u32 *unpack_41_dword_715D70(u32 *a1, u32 a3)
{
  u32 v3; // eax@1
  u32 v6; // edi@3
  u32 *result; // eax@6
  u32 *v8; // eax@6

  v3 = a1[2];
  if ( v3 >= a1[1] )
  {
    if ( v3 >= 8 ) v6 = (((v3 >= 32) - 1) & -24) + 32; else v6 = 4;
    malloc_719490((void * *)a1, 16 * (v6 + v3));
    a1[1] += v6;
  }
  memmove((void *) (16 * a3 + a1[0] + 16), (void *) (16 * a3 + a1[0]), 16 * (a1[2] - a3));
  v8 = (u32 *)a1[0];
  ++a1[2];
  result = v8 + 4 * a3;
  if ( result )
  {
    result[0] = 0;
    result[1] = 0;
    result[2] = 0;
  }
  return result;
}

u32 *unpack_42_dword_714540(u32 *a1, u32 a3, u32 a4)
{
  u32 *result; // eax@1

  result = unpack_41_dword_715D70(a1 + 1, a1[3]);
  result[0] = 0;
  result[1] = a3;
  result[2] = a4;
  return result;
}

u32 *unpack_42_5_7147B0(u32 * a1, u32 a3)
{
  u32 *the_thing; // eax@1
  u32 *v4; // esi@1
  u32 *v5; // eax@1

  v5 = unpack_41_dword_715D70(a1 + 1, a1[3]);
  v4 = v5;
  v5[0] = 5;
  v5[1] = a3;
  the_thing = (u32 *)malloc(16);
  if ( the_thing )
  {
    the_thing[0] = -1;
    the_thing[1] = 0;
    the_thing[2] = 0;
    the_thing[3] = 0;
    v4[2] = (u32)the_thing;
  }
  else
  {
    the_thing = 0;
    v4[2] = 0;
  }
  return the_thing;
}

u32 *unpack_42_3_7145D0(u32 *a1, const u8 *a2, u32 skype_id, u32 a5)
{
  u32 *v5; // eax@1
  u32 *v8; // esi@1
  u8 *v9; // eax@4

  v5 = unpack_41_dword_715D70(a1 + 1, *(a1 + 3));
  v8 = v5;
  v5[0] = 3;
  v5[1] = skype_id;
  if ( !a2 ) a2 = unpack_42_CF2848;
  v5[3] = a5 + 1;
  if ( a5 )
  {
    v9 = memchr(a2, 0, a5);
    if ( v9 ) *(v8 + 3) = (u32) (v9 - a2 + 1);
  }
  v8[2] = (u32)malloc(v8[3]);
  memcpy((void *)v8[2], a2, v8[3]);
  *(u8 *)(*(v8 + 3) + *(v8 + 2) - 1) = 0;
  return v8;
}

void unpack_42_6_7393A0(u32 *context, u32 a2)
{
  u32 *v8; // ebp@1
  u32 *v9; // eax@4
  void *v10; // esi@14
  u32 *v11; // eax@15
  void *v13; // [sp+8h] [bp-4h]@14

  v8 = context + 33;
  if ( a2 != *(context + 33) )
  {
    if ( (u32)a2 > 32 )
    {
	// if ( (u32)a2 > 0x3FFFFFFF ) __asm int 3;
      *(context + 34) = a2;
      if ( *(context + 32) == (u32)context ) *(context + 32) = 0;
      v13 = (void *)*(context + 32);
      malloc_719490(&v13, 4 * a2);
      v10 = v13;
      if ( !*(context + 32) )
      {
        v11 = &a2;
        if ( a2 >= *v8 ) v11 = (u32 *)(context + 33);
        memcpy(v13, context, 4 * *v11);
      }
      *(context + 32) = (u32)v10;
      *v8 = a2;
    }
    else
    {
      if ( *(context + 32) != (u32)context )
      {
        v9 = &a2;
        if ( a2 >= *v8 ) v9 = (u32 *)(context + 33);
        memcpy(context, (void *)*(context + 32), 4 * *v9);
        if ( *(context + 32) ) free((void *)*(context + 32));
        *(context + 32) = (u32)context;
      }
      *v8 = a2;
      *(context + 34) = 32;
    }
  }
}

void unpack_42_end_context_720CA0(u32 *context)
{
  if ( context[32] != (u32)context )
  {
    if ( context[32] ) free((void *)context[32]);
    context[32] = (u32)context;
  }
  context[33] = 0;
  context[34] = 32;
}

u32 *unpack_42_6_714690(u32 *a1, u32 dwords, u32 skype_id, u32 a4)
{
  u32 *v6; // eax@1
  u32 *v8; // esi@1
  u32 v9; // ecx@2
  u32 v13; // qax@1

  v13 = 4 * dwords;
// if (v13 < dwords) __asm int 3;
  v8 = unpack_41_dword_715D70(a1 + 1, *(a1 + 3));
  v8[0] = 6;
  v8[1] = skype_id;
  v8[3] = 4 * dwords;
  v6 = (u32 *)malloc(v13);
  v8[2] = (u32)v6;
  if ( dwords )
  {
    v9 = a4 - (u32)v6;
    do
    {
      *v6 = *(u32 *)((u8 *)v6 + v9);
      ++v6;
      --dwords;
    }
    while ( dwords );
  }
  return v8;
}

void unpack_42_list_76B1B0(u32 ctx, u32 *into_list, u32 a3)
{
  u32 *v4; // eax@3
  u32 *v5; // esi@5
  u32 *v6; // ecx@10
  u32 v7; // ebx@10
  u32 v8; // eax@11
  u32 v9; // edi@14
  u32 v10; // ebx@16
  u32 v12; // eax@21
  u16 **v13; // edi@25
  u32 v14; // eax@26
  u32 v15; // eax@27
  u32 v17; // esi@27
  u8 v18; // bl@29
  u32 v20; // eax@38
  u32 v21; // ebx@38
  u32 v22; // esi@41
  u32 increment; // esi@45
  u32 v25; // eax@5
  u32 v26; // eax@7
  u32 v33; // ebx@17
  u32 v34; // eax@23
  u32 v35; // ST08_4@24
  u32 *v36; // eax@24
  char *v39; // ecx@29
  u32 v40; // edi@43
  u32 v41; // eax@45
  u32 *v42; // eax@48
  u32 *v44; // eax@48
  u32 v45; // ecx@48
  u32 v46; // eax@52
  u32 v50; // [sp+28h] [bp-9Ch]@3
  u32 v52; // [sp+24h] [bp-A0h]@5
  u8 skype_id[5]; // [sp+17h] [bp-ADh]@8
  u32 context[37]; // [sp+2Ch] [bp-98h]@41

  if ( a3 >= dword(ctx,0x1F2) ) goto LABEL_2;
  v50 = 2;
  v4 = &v50;
  if ( a3 <= 2 ) v4 = &a3;
  v25 = *v4;
  v5 = &dword(ctx,18+160*v25);
  v52 = 0;
  if ( a3 )
  {
    if ( v5[39] )
    {
      v26 = unpack_42_dword_76ADE0(ctx, pack_42_thing1_E3B7F4, 0);
      v52 = v26;
      if (v26 > v5[39])
      {
LABEL_2:
        dword(ctx,0x202) = 1;
        return;
      }
    }
  }
  v5[39] = 0;
  *(u32 *)(skype_id+1) = 0;
  if ( dword(ctx,0x202) == 0 )
  {
    while ( 1 )
    {
      if ( !v52 )
      {
        v8 = unpack_42_769EA0(ctx, pack_42_word_E3B7A0);
        if ( !v8 ) return;
        if ( (u32)v8 > 6 )
        {
          v10 = v8 - 6;
          v9 = unpack_42_dword_76ADE0(ctx, pack_42_thing1_E3B7F4, 0);
          if ( v10 )
          {
            v33 = v5[v10];
            memmove(v5 + 1, v5, 4 * v10);
            v5[0] = v33;
          }
        }
        else
        {
          if ( v8 != 6 ) v9 = v8 - 1;
          else v9 = unpack_42_dword_76ADE0(ctx, pack_42_thing1_E3B7F4, 0) + 5;
        }
        v7 = v5[0];
        *(u32 *)(skype_id+1) += v9;
      }
      else
      {
        v7 = v5[v5[39]*2+8];
        --v52;
        *(u32 *)(skype_id+1) = v5[v5[39]*2+7];
        pack_42_find_code_76A070(v5, v7);
      }
      if ( v5[39] < 16 )
      {
        v6 = *(u32 **)(skype_id+1);
        v5[v5[39]*2+7] = *(u32 *)(skype_id+1);
        v5[8+2*v5[39]++] = v7;
      }
      v12 = dword(ctx,0x20E);
      if ( *(u32 *)v12 < 16 ) goto LABEL_2;
      *(u32 *)v12 -= 16;
      switch ( v7 )
      {
        case 0:
          v34 = unpack_42_dword_76ADE0(ctx, pack_42_thing2_E3B804, 0);
          unpack_42_dword_714540(into_list, *(u32 *)(skype_id+1), v34);
          goto LABEL_50;
        case 5:
          v35 = a3 + 1;
          v36 = unpack_42_5_7147B0(into_list, *(u32 *)(skype_id+1));
          unpack_42_list_76B1B0(ctx, v36, v35);
          goto LABEL_50;
        case 3:
          v13 = pack_42_word_off_E3B748;
          v50 = 0;
          while ( 2 )
          {
            v14 = dword(ctx,0x20E);
            if ( *(u32 *)v14 < 1 )
            {
LABEL_39:
              dword(ctx,0x202) = 1;
              goto LABEL_50;
            }
            --*(u32 *)v14;
            v17 = unpack_42_769EA0(ctx, v13[1]);
            v13 = pack_42_word_off_E3B748 + 2 * v17;
            v15 = 0;
            if ( (*v13)[1] != 0x1000 ) v15 = unpack_42_769EA0(ctx, v13[0]);
            v39 = unpack_42_off_E3B054[v17];
            v18 = v39[v15];
            skype_id[0] = v39[v15];
            if ( dword(ctx,0x202) != 0 )
            {
              v18 = 0;
              skype_id[0] = 0;
            }
            if ( (u32)v50 >= dword(ctx,0x522) ) unpack_42_byte_85BDC0(ctx + 0x31E, (u32)skype_id);
            else *(u8 *)(v50 + dword(ctx,0x51E)) = v18;
            if ( !v18 ) break;
            v50++;
          }
          if ( !dword(ctx,0x202) ) unpack_42_3_7145D0(into_list, (const u8 *)dword(ctx,0x51E), *(u32 *)(skype_id+1), 0x7FFFFFFF);
          goto LABEL_49;
        case 6:
          v20 = unpack_42_dword_76ADE0(ctx, pack_42_thing2_E3B804, 0);
          v21 = v20;
          if ( (u32)v20 > 0x3FFFFFFF ) goto LABEL_39;
          if ( !unpack_42_76AEA0(4 * v20, ctx) ) goto LABEL_50;
          v22 = 0;
          context[32] = (u32)context;
          context[33] = 0;
          context[34] = 32;
          unpack_42_6_7393A0(context, v21);
          if ( !v21 ) goto LABEL_44;
          break;
        case 4:
          v41 = unpack_42_dword_76ADE0(ctx, pack_42_thing2_E3B804, 0);
          increment = v41;
          unpack_42_76AEA0(v41, ctx);
          goto LABEL_46;
        case 1:
          v46 = unpack_42_dword_76ADE0(ctx, pack_42_thing2_E3B804, 0);
          increment = v46;
          if ( v46 > 8 ) dword(ctx,0x202) = 1;
LABEL_46:
          if ( increment < -1 ) goto LABEL_47;
          goto LABEL_49;
        case 2:
          increment = 6;
LABEL_47:
          if ( !dword(ctx,0x202) )
          {
            v42 = unpack_42_from_951460(&dword(ctx,0x212));
            v42[0] = (u32)into_list;
            v42[1] = into_list[3];
            v44 = unpack_41_dword_715D70(into_list + 1, into_list[3]);
            v45 = *(u32 *)(skype_id+1);
            v44[0] = 2;
            v44[1] = v45;
            v44[2] = increment;
            v44[3] = v7;
            unpack_42_inc_76AD90(ctx, increment);
          }
          goto LABEL_49;
        default:
          goto LABEL_50;
      }
      do
      {
        if ( dword(ctx,0x202) )
        {
          unpack_42_end_context_720CA0(context);
          return;
        }
        v40 = context[32] + 4 * v22++;
        *(u32 *)v40 = unpack_42_dword_76ADE0(ctx, pack_42_thing2_E3B804, 0);
      }
      while ( v22 < v21 );
LABEL_44:
      unpack_42_6_714690(into_list, v21, *(u32 *)(skype_id+1), context[32]);
      unpack_42_end_context_720CA0(context);
LABEL_49:
LABEL_50:
      if ( dword(ctx,0x202) ) return;
    }
  }
}

void unpack_42_2_715200(u32 *the_thing, u32 a2, u32 a3)
{
  if ( (the_thing[0] == 3) || (the_thing[0] == 4) || (the_thing[0] == 6) )
  {
    if ( the_thing[2] ) free((void *)the_thing[2]);
  }
  else
  {
    if ( the_thing[0] == 5 )
    {
      if ( the_thing[2] ) Load_Byte(the_thing[2]);
    }
  }
  the_thing[0] = 2;
  the_thing[2] = a2;
  the_thing[3] = a3;
}

void unpack_42_4_715250(u32 bytes, u32 *the_thing, u32 blob)
{
  if ( the_thing[0] == 3 || the_thing[0] == 4 || the_thing[0] == 6 )
  {
    if ( the_thing[2] ) free((void *)the_thing[2]);
  }
  else
  {
    if ( the_thing[0] == 5 )
    {
      if ( the_thing[2] ) Load_Byte(the_thing[2]);
    }
  }
  the_thing[0] = 4;
  the_thing[2] = (u32)malloc(bytes);
  the_thing[3] = bytes;
  memcpy((void *)the_thing[2], (void *)blob, bytes);
}

void unpack_42_1_7151B0(u32 *the_thing, u32 a2, u32 a3)
{
  if ( the_thing[0] == 3 || the_thing[0] == 4 || the_thing[0] == 6 )
  {
    if ( the_thing[2] ) free((void *)the_thing[2]);
  }
  else
  {
    if ( the_thing[0] == 5 )
    {
      if ( the_thing[2] ) Load_Byte(the_thing[2]);
    }
  }
  the_thing[0] = 1;
  the_thing[2] = a2;
  the_thing[3] = a3;
}

u32 unpack_42_76AEC0(u32 *list_size, u32 ctx, u32 *into_list)
{
  u32 v3;
  u32 t2;
  u32 t3;
  u32 v7; // eax@5
  u32 v8; // eax@9
  u32 v9; // eax@13
  u32 v10; // edx@13
  u32 *v12; // ecx@18
  u32 *the_thing; // esi@19
  u32 v17; // eax@37
  u32 v18; // eax@41
  u8 v19; // al@13
  u32 *v22; // ecx@18
  u8 *v24; // ecx@27
  u64 the_qword; // [sp+14h] [bp-8h]@28

  dword(ctx,0x206) = 0;
  dword(ctx,0x202) = 0;
  dword(ctx,0x1FE) = 0;
  dword(ctx,0x20A) = -1;
  dword(ctx,0x20E) = (u32)list_size;
  if ( Load_Byte(ctx) != 0x42 ) return 0;
  v7 = dword(ctx,0x51E);
  if ( v7 != ctx + 0x31E )
  {
    if ( v7 ) free((void *)dword(ctx,0x51E));
    dword(ctx,0x51E) = ctx + 0x31E;
  }
  dword(ctx,0x522) = 0;
  dword(ctx,0x526) = 0x200;
  v8 = dword(ctx,0x312);
  if ( v8 != ctx + 0x212 )
  {
    if ( v8 ) free((void *)dword(ctx,0x312));
    dword(ctx,0x312) = ctx + 0x212;
  }
  dword(ctx,0x316) = 0;
  dword(ctx,0x31A) = 32;
  pack_42_init_769FB0(ctx);
  v19 = Load_Byte(ctx);
  byte(ctx,12) = v19;
  dword(ctx,4) = (u32)v19 >> 1;
  dword(ctx,8) = 128;
  unpack_42_list_76B1B0(ctx, into_list, 0);
  dword(ctx,8) >>= 1;
  unpack_42_769E50(ctx);
  v9 = dword(ctx,0x1FE);
  if ( v9 <= 3 )
  {
    *(u8 **)dword(ctx,0x1F6) += v9 - 3;
    v10 = 3 - dword(ctx,0x1FE);
    *(u32 *)dword(ctx,0x1FA) += v10;
    dword(ctx,0x1FE) = 0;
  }
  else
  {
    dword(ctx,0x202) = 1;
  }
  v3 = 0;
  if ( dword(ctx,0x316) != 0 )
  {
    while ( 1 )
    {
      if ( dword(ctx,0x202) != 0 ) goto LABEL_37;
      v22 = (u32 *)dword(ctx,0x312) + 2 * v3;
      v12 = (u32 *)v22[0];
      if ( v22[1] >= v12[3] )
      {
        the_thing = 0;
      }
      else
      {
        the_thing = (u32 *)v12[1] + 4 * v22[1];
      }
	  t2 = the_thing[2];
	  t3 = the_thing[3];
      if ( t2 > dword(ctx,0x206) )
      {
        dword(ctx,0x202) = 1;
        goto LABEL_37;
      }
      if ( t3 == 1 ) break;
      if ( t3 == 2 )
      {
        v24 = *(u8 **)dword(ctx,0x1F6);
        unpack_42_2_715200(the_thing, v24[0]+((v24[1]+((v24[2]+(v24[3]<<8))<<8))<<8),v24[4]+(v24[5]<<8));
      }
      else
      {
        if ( t3 == 4 )
        {
          unpack_42_4_715250(t2, the_thing, *(u32 *)dword(ctx,0x1F6));
LABEL_33:
          goto LABEL_34;
        }
		// __asm int 3;
      }
LABEL_34:
      *(u8 **)dword(ctx,0x1F6) += t2;
      dword(ctx,0x206) -= t2;
      if ( ++v3 >= dword(ctx,0x316) ) goto LABEL_37;
    }
	the_qword = 0;
    if ( t2 )
    {
      memcpy ((void *)&the_qword, *(u8 **)dword(ctx,0x1F6), t2);
    }
    unpack_42_1_7151B0(the_thing, (u32)the_qword, (u32)(the_qword>>32));
    goto LABEL_33;
  }
LABEL_37:
  v17 = dword(ctx,0x312);
  if ( v17 != ctx + 0x212 )
  {
    if ( v17 != 0 ) free((void *)dword(ctx,0x312));
    dword(ctx,0x312) = ctx + 0x212;
  }
  dword(ctx,0x316) = 0;
  dword(ctx,0x31A) = 32;
  v18 = dword(ctx,0x51E);
  if ( v18 != ctx + 0x31E )
  {
    if ( v18 != 0 ) free((void *)dword(ctx,0x51E));
    dword(ctx,0x51E) = ctx + 0x31E;
  }
  dword(ctx,0x522) = 0;
  dword(ctx,0x526) = 0x200;
  return dword(ctx,0x202) == 0;
}

u32 unpack_41_dword_896070(u32 *into_dword, u8 **packed_dword, u32 *packed_bytes)
{
  u32 v5; // esi@1
  u8 v8; // dl@3

  *into_dword = 0;
  v5 = 0;
  while ( 1 )
  {
    if ( (*packed_bytes)-- == 0 ) break;
    v8 = *(*packed_dword)++;
    *into_dword |= (v8 & 127) << v5;
    v5 += 7;
    if ( v8 <= 127 ) return 1;
  }
  return 0;
}

u32 * unpack_41_0_715D70(u32 *the_thing, u32 the_dword)
{
  u32 v2; // eax@1
  u32 v5; // edi@3
  u32 * new_thing; // eax@6
  u32 * v7; // eax@6

  v2 = the_thing[2];
  if ( v2 >= the_thing[1] )
  {
    if ( v2 >= 8 ) v5 = (((v2 >= 32) - 1) & -24) + 32; else v5 = 4;
    malloc_719490((void * *)the_thing, 16 * (v5 + v2));
    *(the_thing + 1) += v5;
  }
  memmove((void *)(16 * the_dword + *the_thing + 16), (void *)(16 * the_dword + *the_thing), 16 * (*(the_thing + 2) - the_dword));
  v7 = (u32 *)*the_thing;
  ++*(the_thing + 2);
  new_thing = v7 + 4 * the_dword;
  if ( new_thing )
  {
    new_thing[0] = 0;
    new_thing[1] = 0;
    new_thing[2] = 0;
    new_thing[3] = 0;
  }
  return new_thing;
}

u32 unpack_42_ctx_init_76ACD0(u32 max_depth, u32 ctx, u32 packed_blob, u32 packed_bytes)
{
  memset ((void *)ctx, 0xCC, 333*4);
  dword(ctx,0x1F2) = max_depth;
  dword(ctx,0x1FA) = packed_bytes;
  dword(ctx,0x1F6) = packed_blob;
  dword(ctx,0x312) = ctx + 0x212;
  dword(ctx,0x316) = 0;
  dword(ctx,0x31A) = 32;
  dword(ctx,0x51E) = ctx + 0x31E;
  dword(ctx,0x522) = 0;
  dword(ctx,0x526) = 0x200;
  return ctx;
}

void unpack_42_ctx_end_714D90(u32 ctx)
{
  if ( dword(ctx,0x51E) != ctx + 0x31E )
  {
    if ( dword(ctx,0x51E) ) free(*(void * *)(ctx + 0x51E));
    dword(ctx,0x51E) = ctx + 0x31E;
  }
  dword(ctx,0x522) = 0;
  dword(ctx,0x526) = 0x200;
  if ( *(void * *)(ctx + 0x312) != (void *)(ctx + 0x212) )
  {
    if ( *(void * *)(ctx + 0x312) ) free(*(void * *)(ctx + 0x312));
    dword(ctx,0x312) = ctx + 0x212;
  }
  dword(ctx,0x316) = 0;
  dword(ctx,0x31A) = 32;
  *(u32 *)ctx = 0;
}

u32 unpack_4142(u32 *into_list, u8 **packed_blob, u32 *packed_bytes, u8 *pack_42, u32 max_depth, u32 *list_size);

u32 unpack_41_715680(u8 **packed_blob, u32 *the_thing, u32 *packed_bytes, u32 max_depth, u32 *list_size)
{
	u32 *v9; // ebx@8
	u8 *v12; // eax@16
	u32 v15; // ecx@17
	u32 v25; // ebx@35
	u32 tt;
	
	--*packed_bytes;
	if (*packed_bytes == 0) return 0;
	the_thing[0] = *(*packed_blob)++;
	the_thing[1] = 0;
	the_thing[2] = 0;
	the_thing[3] = 0;
	if (!unpack_41_dword_896070(the_thing + 1, packed_blob, packed_bytes)) return 0;
	switch (*the_thing)
	{
	case 0:
		return unpack_41_dword_896070(the_thing + 2, packed_blob, packed_bytes);
	case 1:
		v9 = packed_bytes;
		if (*packed_bytes < 8) return 0;
		the_thing[2] = _bswap32(dword(*packed_blob,4));
		the_thing[3] = _bswap32(dword(*packed_blob,0));
		*packed_blob += 8;
		*v9 -= 8;
		return 1;
	case 2:
		if (*packed_bytes < 6) return 0;
		the_thing[2] = _bswap32(dword(*packed_blob,0));
		the_thing[3] = ntohs(word(*packed_blob,4));
		*packed_blob += 6;
		*packed_bytes -= 6;
		return 1;
	case 3:
		v12 = memchr(*packed_blob, 0, *packed_bytes);
		if (!v12 || (v15 = (u32)(v12 - *packed_blob + 1), the_thing[3] = (u32)(v12 - *packed_blob + 1), *list_size < v15)) return 0;
		*list_size -= v15;
		memcpy((void *)(the_thing[2] = (u32)malloc(the_thing[3])), *packed_blob, the_thing[3]);
		*packed_blob += the_thing[3];
		*packed_bytes -= the_thing[3];
		return 1;
	case 4:
		if (!unpack_41_dword_896070(the_thing+3, packed_blob, packed_bytes) || (*packed_bytes < the_thing[3]) || (*list_size < the_thing[3])) return 0;
		*list_size -= the_thing[3];
		memcpy((void *)(the_thing[2] = (u32)malloc(the_thing[3])), *packed_blob, the_thing[3]);
		*packed_blob += the_thing[3];
		*packed_bytes -= the_thing[3];
		return 1;
	default:
		if (*the_thing != 5)
		{
			if ((*the_thing != 6)
				|| !unpack_41_dword_896070(&tt, packed_blob, packed_bytes)
				|| (tt > *packed_bytes)
				|| (tt >= 128*1024*1024)
				|| (*list_size < (the_thing[3] = 4*tt)))
				return 0;
			*list_size -= 4*tt;
			the_thing[2] = (u32) malloc(the_thing[3]);
			if (!tt) return 1;
			for (v25 = 0; v25 < tt; v25++)
			{
				if (!unpack_41_dword_896070(&dword(the_thing[2],v25*4), packed_blob, packed_bytes)) return 0;
			}
			return 1;
		}
		if (*list_size < 16) return 0;
		*list_size -= 16;
		if (the_thing[2] = (u32) malloc (16))
		{
			dword(the_thing[2],0) = -1;
			dword(the_thing[2],4) = 0;
			dword(the_thing[2],8) = 0;
			dword(the_thing[2],12) = 0;
		}
		return unpack_4142((u32 *)the_thing[2], packed_blob, packed_bytes, 0, max_depth - 1, list_size);
	}
}

u32 unpack_4142(u32 *into_list, u8 **packed_blob, u32 *packed_bytes, u8 *pack_42, u32 max_depth, u32 *list_size)
{
  u32 v13;
  u32 length;
  u32 *length_ptr;
  u32 max_length;
  u32 *the_thing;
  u32 v22;
  u32 n;
  u32 ctx[333];

  if ( pack_42 ) *pack_42 = 0;
  if ( !max_depth || !*packed_bytes ) return 0;
  if ( **packed_blob == 0x41 )
  {
    --*packed_bytes;
    ++*packed_blob;
    if ( unpack_41_dword_896070(&length, packed_blob, packed_bytes) )
    {
      v22 = 100;
      length_ptr = (u32 *)&v22;
      if ( length <= 100 ) length_ptr = &length;
      max_length = into_list[3] + *length_ptr;
      if ( into_list[2] < max_length )
      {
        into_list[2] = max_length;
        malloc_719490((void **)into_list + 1, 16 * max_length);
      }
      n = 0;
      if ( !length ) return 1;
      while ( *list_size >= 16 )
      {
        *list_size -= 16;
        the_thing = unpack_41_0_715D70(into_list+1, into_list[3]);
		if ( !unpack_41_715680(packed_blob, the_thing, packed_bytes, max_depth, list_size)) break;
        if ( ++n >= length ) return 1;
      }
    }
    return 0;
  }
  if ( pack_42 ) *pack_42 = 1;
  unpack_42_ctx_init_76ACD0(max_depth, (u32)ctx, (u32)packed_blob, (u32)packed_bytes);
  v13 = unpack_42_76AEC0(list_size, (u32)ctx, into_list) != 0;
  unpack_42_ctx_end_714D90((u32)ctx);
  return v13;
}
