/*
 *  Copyright (C) 2005 aCaB <acab@clamav.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */

/*
** spin.c
** 
** 19/07/2k5 - Finally started coding something
** 21/07/2k5 - Works, started clearing the mess
** 31/07/2k5 - Porting to libclamav
*/

/*
** Unpacks pespin v1.1
**
** Funny thing to reverse
**
** [ A big fat thank to christoph for not letting me give up ]
*/


/*
** TODO ( a fat one ):
**
** OEP restore and unhijacking
** code redir handling (at least near OEP)
** passwd protection (didn't really look at it)
**
** All this stuff really needs a way better emu and a hell of unlaming
** ATM not worth the effort... and pespin v1.3 is out :@
**
*/


#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif

#include <stdlib.h>
#include <string.h>

#include "cltypes.h"
#include "pe.h"
#include "rebuildpe.h"
#include "execs.h"
#include "others.h"
#include "packlibs.h"
#include "spin.h"


static char exec86(uint8_t aelle, uint8_t cielle, char *curremu, int *retval) {
  int len = 0;
  *retval=0;
  while (len <0x24) {
    uint8_t opcode = curremu[len], support;
    len++;
    switch (opcode) {
      case 0xeb:
        len++;
      case 0x0a:
        len++;
      case 0x90:
      case 0xf8:
      case 0xf9:
        break;

      case 0x02: /* add al, cl */
        aelle+=cielle;
	len++;
        break;
      case 0x2a: /* sub al, cl */
        aelle-=cielle;
	len++;
        break;
      case 0x04: /* add al, ?? */
        aelle+=curremu[len];
	len++;
        break;
      case 0x2c: /* sub al, ?? */
        aelle-=curremu[len];
	len++;
        break;
      case 0x32: /* xor al, cl */
        aelle^=cielle;
	len++;
        break;
      case 0x34: /* xor al, ?? */
        aelle^=curremu[len];
	len++;
        break;

      case 0xfe: /* inc/dec al */
        if ( curremu[len] == '\xc0' ) aelle++;
	else aelle--;
        len++;
        break;

      case 0xc0: /* ror/rol al, ?? */
	support = curremu[len];
        len++;
        if ( support == 0xc0 ) CLI_ROL(aelle, curremu[len]);
        else CLI_ROR(aelle, curremu[len]);
        len++;
        break;

      default:
        cli_dbgmsg("spin: bogus opcode %x\n", opcode);
	*retval=1;
	return aelle;
    }
  }
  if ( len!=0x24 || curremu[len]!='\xaa' ) {
    cli_dbgmsg("spin: bad emucode\n");
    *retval=1;
  }
  return aelle;
}


static uint32_t summit (char *src, int size) 
{
  uint32_t eax=0xffffffff, ebx=0xffffffff;
  int i;

  while(size) {
    eax ^= *src++<<8 & 0xff00;
    eax = eax>>3 & 0x1fffffff;
    for (i=0; i<4; i++) {
      uint32_t swap;
      eax ^= ebx>>8 & 0xff;
      eax += 0x7801a108;
      eax ^= ebx;
      CLI_ROR(eax, ebx&0xff);
      swap = eax;
      eax = ebx;
      ebx = swap;
    }
    size--; 
  }
  return ebx;
}


int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt, uint32_t nep, int desc, cli_ctx *ctx) {
  char *curr, *emu, *ep, *spinned;
  char **sects;
  int blobsz=0, j;
  uint32_t key32, bitmap, bitman;
  uint32_t len;
  uint8_t key8;

  cli_dbgmsg("in unspin\n");

  if ((spinned = (char *) cli_malloc(sections[sectcnt].rsz)) == NULL )
    return 1;

  memcpy(spinned, src + sections[sectcnt].raw, sections[sectcnt].rsz); 
  ep = spinned + nep - sections[sectcnt].rva;

  curr = ep+0xdb;
  if ( *curr != '\xbb' ) {
    free(spinned);
    cli_dbgmsg("spin: Not spinned or bad version\n");
    return 1;
  }
  
  key8 = (uint8_t)*++curr;
  curr+=4;
  if ( *curr != '\xb9' ) {
    free(spinned);
    cli_dbgmsg("spin: Not spinned or bad version\n");
    return 1;
  }

  if ( (len = cli_readint32(curr+1)) != 0x11fe ) {
    free(spinned);
    cli_dbgmsg("spin: Not spinned or bad version\n");
    return 1;
  }

  cli_dbgmsg("spin: Key8 is %x, Len is %x\n", key8, len);

  if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep, len+0x1fe5-1) || !CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep+0x3217, 4)) {
    free(spinned);
    cli_dbgmsg("spin: len or key out of bounds, giving up\n");
    return 1;
  }

  if ( ep[0x1e0]!='\xb8' )
    cli_dbgmsg("spin: prolly not spinned, expect failure\n");
  
  if ( (cli_readint32(ep+0x1e1) & 0x00200000) )
    cli_dbgmsg("spin: password protected, expect failure\n");

  curr = ep+0x1fe5+len-1;
  while ( len-- ) {
    *curr=(*curr)^(key8--);
    curr--;
  }

  curr = ep+0x26eb;
  key32 = cli_readint32(curr);
  if ( (len = cli_readint32(curr+5)) != 0x5a0) {
    free(spinned);
    cli_dbgmsg("spin: Not spinned or bad version\n");
    return 1;
  }

  curr = ep+0x2d5;
  cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);

  while ( len-- ) {
    if ( key32 & 1 ) {
      key32 = key32>>1;
      key32 ^= 0x8c328834;
    } else {
      key32 = key32>>1;
    }
    *curr = *curr ^ (key32 & 0xff);
    curr++;
  }

  len = ssize - cli_readint32(ep+0x429); /* sub size, value */
  if ( len >= (uint32_t)ssize ) {
    free(spinned);
    cli_dbgmsg("spin: crc out of bounds, giving up\n");
    return 1;
  }
  key32 = cli_readint32(ep+0x3217) - summit(src,len);

  memcpy(src + sections[sectcnt].raw, spinned, sections[sectcnt].rsz); 
  free(spinned); /* done CRC'ing - can have a dirty buffer now */
  ep = src + nep + sections[sectcnt].raw - sections[sectcnt].rva; /* Fix the helper */

  if (!CLI_ISCONTAINED(src, ssize, ep+0x3207, 4)) { /* this one holds all ep based checks */
    cli_dbgmsg("spin: key out of bounds, giving up\n");
    return 1;
  }
  bitmap = cli_readint32(ep+0x3207);
  cli_dbgmsg("spin: Key32 is %x - XORbitmap is %x\n", key32, bitmap);
  
  cli_dbgmsg("spin: Decrypting sects (xor)\n");
  for (j=0; j<sectcnt; j++) {

    if (bitmap&1) {
      uint32_t size = sections[j].rsz;
      char *ptr = src + sections[j].raw;
      uint32_t keydup = key32;
      
      if (!CLI_ISCONTAINED(src, (unsigned int)ssize, ptr, size)) {
	cli_dbgmsg("spin: sect %d out of file, giving up\n", j);
	return 1; /* FIXME: Already checked in pe.c? */
      }

      while (size--) {
	if (! (keydup & 1)) {
	  keydup = keydup>>1;
	  keydup ^= 0xed43af31;
	} else {
	  keydup = keydup>>1;
	}
	*ptr = *ptr ^ (keydup & 0xff);
	ptr++;
      }
    } 
    bitmap = bitmap >>1;
  }
  
  cli_dbgmsg("spin: done\n");

  
  curr = ep+0x644;
  if ( (len = cli_readint32(curr)) != 0x180) {
    cli_dbgmsg("spin: Not spinned or bad version\n");
    return 1;
  }

  key32 = cli_readint32(curr+0x0c);
  cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
  curr = ep+0x28d3;

  if (!CLI_ISCONTAINED(src, (unsigned int)ssize, curr, len)) { /* always true but i may decide to remove the previous check */
    cli_dbgmsg("spin: key out of bounds, giving up\n");
    return 1;
  }
  while ( len-- ) {
    if ( key32 & 1 ) {
      key32 = key32>>1;
      key32 ^= 0xed43af32;
    } else {
      key32 = key32>>1;
    }
    *curr = *curr ^ (key32 & 0xff);
    curr++;
  }


  curr = ep+0x28dd;
  if ( (len = cli_readint32(curr)) != 0x1a1 ) {
    cli_dbgmsg("spin: Not spinned or bad version\n");
    return 1;
  }

  cli_dbgmsg("spin: POLY1 len is %x\n", len);
  curr+=0xf; /* POLY1 */
  emu = ep+0x6d4;
  if (!CLI_ISCONTAINED(src, (unsigned int)ssize, emu, len)) {
    cli_dbgmsg("spin: poly1 out of bounds\n");
    return 1;
  }
  while (len) {
    int xcfailure=0;
    *emu=exec86(*emu, len-- & 0xff, curr, &xcfailure); /* unlame POLY1 */
    if (xcfailure) {
      cli_dbgmsg("spin: cannot exec poly1\n");
      return 1;
    }
    emu++;
  }


  bitmap = cli_readint32(ep+0x6f1);
  cli_dbgmsg("spin: POLYbitmap is %x - decrypting sects (poly)\n", bitmap);
  curr = ep+0x755;

  for (j=0; j<sectcnt; j++) {
    if (bitmap&1) {
      uint32_t notthesamelen = sections[j].rsz;

      emu = src + sections[j].raw;

      if (!CLI_ISCONTAINED(src,ssize,curr,0x24)) { /* section bounds already checked twice now */
	cli_dbgmsg("spin: poly1 emucode is out of file?\n");
	return 1;
      }

      while (notthesamelen) {
	int xcfailure=0;
        *emu=exec86(*emu, notthesamelen-- & 0xff, curr, &xcfailure);
	if (xcfailure) {
	  cli_dbgmsg("spin: cannot exec section\n");
	  return 1;
	}
        emu++;
      }
    }
      bitmap = bitmap >>1;
  }
  
  cli_dbgmsg("spin: done\n");

  bitmap = cli_readint32(ep+0x3061);
  bitman = bitmap;

  cli_dbgmsg("spin: Compression bitmap is %x\n", bitmap);
  if ( (sects= (char **) cli_malloc(sectcnt*sizeof(char *))) == NULL )
    return 1;

  key8 = 0;
  for (j=0; j<sectcnt; j++) {
    uint32_t thissize = (bitmap&1) ? sections[j].vsz : sections[j].rsz;
    if(ctx->limits && ctx->limits->maxfilesize && ((unsigned long int)thissize > ctx->limits->maxfilesize || (unsigned long int)blobsz > ctx->limits->maxfilesize - thissize)) {
      key8++;
      cli_dbgmsg("spin: section %d size exceeded (%u, %lu)\n", j, thissize, ctx->limits->maxfilesize);
      break;
    }
    if (bitmap&1) {
      if ( (sects[j] = (char *) cli_calloc(thissize, sizeof(char)) ) == NULL ) {
	cli_dbgmsg("spin: malloc(%d) failed\n", thissize);
	key8++;
	break;
      }
      blobsz+=thissize;
      cli_dbgmsg("spin: Growing sect%d: was %x will be %x\n", j, sections[j].rsz, thissize);
      if ( cli_unfsg(src + sections[j].raw, sects[j], sections[j].rsz, thissize, NULL, NULL) == -1 ) {
	key8++;
	j++;
	cli_dbgmsg("spin: Unpack failure\n");
	break;
      }
    } else {
      blobsz+=thissize;
      sects[j] = src + sections[j].raw;
      cli_dbgmsg("spin: Not growing sect%d\n", j);
    }
    bitmap>>=1;
  }
  
  cli_dbgmsg("spin: decompression complete\n");
 
  if ( key8 ) {
    int t;
    for (t=0 ; t<j ; t++) {
      if (bitman&1)
	free(sects[t]);
      bitman = bitman >>1;
    }
    free(sects);
    return 1;
  }


  key32 = cli_readint32(ep+0x2fee);
  if (key32) {
    /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */

    for (j=0; j<sectcnt; j++) {
      if (sections[j].rva <= key32 && sections[j].rva+sections[j].rsz > key32)
	break;
    }

    if (j!=sectcnt && ((bitman & (1<<j)) == 0)) { /* FIXME: not really sure either the res sect is lamed or just compressed, but this'll save some major headakes */
      cli_dbgmsg("spin: Resources (sect%d) appear to be compressed\n\tuncompressed offset %x, len %x\n\tcompressed offset %x, len %x\n", j, sections[j].rva, key32 - sections[j].rva, key32, sections[j].vsz - (key32 - sections[j].rva));

      if ( (curr=(char *)cli_malloc(sections[j].vsz)) != NULL ) {
	memcpy(curr, src + sections[j].raw, key32 - sections[j].rva); /* Uncompressed part */
	memset(curr + key32 - sections[j].rva, 0, sections[j].vsz - (key32 - sections[j].rva)); /* bzero */
	if ( cli_unfsg(src + sections[j].raw + key32 - sections[j].rva, curr + key32 - sections[j].rva, sections[j].rsz - (key32 - sections[j].rva), sections[j].vsz - (key32 - sections[j].rva), NULL, NULL) ) {
      
	  free(curr);
	  cli_dbgmsg("spin: Failed to grow resources, continuing anyway\n");
	  blobsz+=sections[j].rsz;
	} else {
	  sects[j]=curr;
	  bitman|=1<<j;
	  cli_dbgmsg("spin: Resources grown\n");
	  blobsz+=sections[j].vsz;
	}
      } else {
	/* malloc failed but i'm too deep into this crap to quit without leaking more :( */
	blobsz+=sections[j].rsz;
      }
    } else {
      cli_dbgmsg("spin: No res?!\n");
    }
  }
  

  bitmap=bitman; /* save as a free() bitmap */

  if ( (ep = (char *) cli_malloc(blobsz)) != NULL ) {
    struct cli_exe_section *rebhlp;
    if ( (rebhlp = (struct cli_exe_section *) cli_malloc(sizeof(struct cli_exe_section)*(sectcnt))) != NULL ) {
      char *to = ep;
      int retval = 0;

      for (j = 0; j < sectcnt; j++) {
	rebhlp[j].raw = (j>0)?(rebhlp[j-1].raw + rebhlp[j-1].rsz):0;
	rebhlp[j].rsz = (bitmap &1) ? sections[j].vsz : sections[j].rsz;
	rebhlp[j].rva = sections[j].rva;
	rebhlp[j].vsz = sections[j].vsz;

	memcpy(to, sects[j], rebhlp[j].rsz);
	to+=rebhlp[j].rsz;
	if ( bitmap & 1 ) free(sects[j]);
	bitmap = bitmap >>1;
      }

      if (! cli_rebuildpe(ep, rebhlp, sectcnt, 0x400000, 0x1000, 0, 0, desc)) { /* can't be bothered fixing those values: the rebuilt exe is completely broken anyway. */
	cli_dbgmsg("spin: Cannot write unpacked file\n");
	retval = 1;
      }
      free(rebhlp);
      free(ep);
      free(sects);
      return retval;
    }
    free(ep);
  }

  cli_dbgmsg ("spin: free bitmap is %x\n", bitman);
  for (j=0; j<sectcnt; j++) {
    if (bitmap&1) free(sects[j]);
    bitman = bitman >>1;
  }
  free(sects);
  return 1; /* :( */
}
