5

I want to decompress some files, and found some information on how. Apparently they are encrypted with AES 128 in CFB mode, and sometimes compressed using ZLIB. Each file's key and IV is supposedly generated from the file size. This code is supposed to get them:

Generate_Key_IV   proc near
      mov   eax, [ecx]
      movzx   edx, ax
      imul   edx, 9069h
      shr   eax, 10h
      add   edx, eax
      mov   eax, [ecx+4]
      push   esi                            ; Here file size
      movzx   esi, ax
      imul   esi, 4650h
      shr   eax, 10h
      add   eax, esi
      mov   [ecx], edx
      mov   [ecx+4], eax
      pop   esi
      test   edx, edx
      jnz   short loc_495EA2
      mov   dword ptr [ecx], 1
loc_495EA2:
      test   eax, eax
      jnz   short loc_495EAD
      mov   dword ptr [ecx+4], 0FFFFFFFFh
loc_495EAD:
      mov   eax, [ecx]
      shl   eax, 10h
      add   eax, [ecx+4]
      retn
Generate_Key_IV   endp

I understand that this is in Assembly, but unfortunately I don't have a clue how it works. I could of course learn it, but I expect that that would take a great deal of time, and I don't think I'd use it for much more than figuring out what the above means.

So yeah I'd be really grateful if someone could kind of outline what the above does and generally the method and/or algorithm for getting the key and IV.

This C code was also given, and apparently shows how to use the above:

int __usercall sub_47AFA0<eax>(int a1<eax>, int a2<ebp>, void *a3, size_t a4, __int64 a5)
{
  unsigned int v5;  // edi@1
  unsigned int v6;  // edi@3
  char v8;          // [sp-1A0h] [bp-1ACh]@2
  int v9;           // [sp-198h] [bp-1A4h]@1
  void *v10;        // [sp-194h] [bp-1A0h]@1
  char v11;         // [sp-190h] [bp-19Ch]@5
  char v12;         // [sp-140h] [bp-14Ch]@5
  int v13;          // [sp-40h] [bp-4Ch]@6
  void *v14;        // [sp-3Ch] [bp-48h]@5
  char v15;         // [sp-34h] [bp-40h]@2
  char v16;         // [sp-24h] [bp-30h]@4
  unsigned int v17; // [sp-14h] [bp-20h]@1
  char *v18;        // [sp-10h] [bp-1Ch]@1
  int v19;          // [sp-Ch] [bp-18h]@1
  int (__cdecl *v20)(int, int); // [sp-8h] [bp-14h]@1
  signed int v21;   // [sp-4h] [bp-10h]@1
  int v22;          // [sp+0h] [bp-Ch]@1
  void *v23;        // [sp+4h] [bp-8h]@1
  char v24;         // [sp+8h] [bp-4h]@1
  int v25;          // [sp+Ch] [bp+0h]@1

  v22 = a2;
  v23 = (void *)v25;
  v21 = -1;
  v20 = sub_72CCC6;
  v19 = a1;
  v18 = &v24;
  v17 = (unsigned int)&v22 ^ __security_cookie;
  v10 = a3;
  v9 = sub_5657C0(a4);
  sub_495EC0(a4 * a5, (unsigned __int64)a4 * a5 >> 32);
  v5 = 0;
  do
    *(&v15 + v5++) = Generate_Key_IV((int)&v8);                          ;Generating KEY
  while ( v5 < 0x10 );
  v6 = 0;
  do
    *(&v16 + v6++) = Generate_Key_IV((int)&v8);                          ;Generating IV
  while ( v6 < 0x10 );
  sub_47AC20(&v15, 16, &v16);                          ; AES Routine
  v21 = 0;
  sub_433E00(v9, v10, a4);
  v21 = 1;
  sub_4799F0(&v11);
  if ( v14 == &v12 + (-(signed int)&v12 & 0xF) )
    memset(v14, 0, 4 * v13);
  return __security_check_cookie((unsigned int)&v22 ^ v17);
}

I assume that this simply uses the key and IV to decode files using AES. However if it contains anything necessary that I should know then that would also of course be great.

1 Answer 1

4

It's a Pseudorandom number generator: it's a simple piece of code that produces values that are hard to predict while not taking too long to compute. Check the Wikipedia article for more informations.

edit: the equivalent C code is something like:

int random(unsigned int *seed)
{
  int temp1;
  int temp2;

  temp1 = (*seed >> 16) + 36969 * (unsigned short)*seed;
  temp2 = 18000 * (unsigned short)seed[1] + (seed[1] >> 16);
  *seed = temp1;
  seed[1] = temp2;
  if (!temp1) *seed = 1;
  if (!temp2) seed[1] = -1;
  return seed[1] + (*seed << 16);
}
3
  • 1
    While I appreciate your answer, what I really would prefer is a more specific description of the exact algorithm that the code performs, in such a way that I would be able to port it to some other language.
    – puggsoy
    Oct 30, 2013 at 10:46
  • @puggsoy The PRNG is a multiply with carry. It's described on Wikipedia's RNG article. Oct 30, 2013 at 12:38
  • This looks simple enough. However, I'm a bit confused, shouldn't this produce two values, the key and the IV? If needed I can supply some example values.
    – puggsoy
    Oct 30, 2013 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.