/*
 *  Copyright (C) 2006 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.
 */


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

#include "others.h"
#include "execs.h"
#include "pe.h"
#include "packlibs.h"

static int doubledl(char **scur, uint8_t *mydlptr, char *buffer, uint32_t buffersize)
{
  unsigned char mydl = *mydlptr;
  unsigned char olddl = mydl;

  mydl*=2;
  if ( !(olddl & 0x7f)) {
    if ( *scur < buffer || *scur >= buffer+buffersize-1 )
      return -1;
    olddl = **scur;
    mydl = olddl*2+1;
    *scur=*scur + 1;
  }
  *mydlptr = mydl;
  return (olddl>>7)&1;
}


int cli_unfsg(char *source, char *dest, int ssize, int dsize, char **endsrc, char **enddst) {
  uint8_t mydl=0x80;
  uint32_t backbytes, backsize, oldback = 0;
  char *csrc = source, *cdst = dest;
  int oob, lostbit = 1;

  if (ssize<=0 || dsize<=0) return -1;
  *cdst++=*csrc++;

  while ( 1 ) {
    if ((oob=doubledl(&csrc, &mydl, source, ssize))) {
      if (oob == -1)
	return -1;
      /* 164 */
      backsize = 0;
      if ((oob=doubledl(&csrc, &mydl, source, ssize))) {
	if (oob == -1)
	  return -1;
	/* 16a */
	backbytes = 0;
	if ((oob=doubledl(&csrc, &mydl, source, ssize))) {
	  if (oob == -1)
	    return -1;
	  /* 170 */
	  lostbit = 1;
	  backsize++;
	  backbytes = 0x10;
	  while ( backbytes < 0x100 ) {
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	    backbytes = backbytes*2+oob;
	  }
	  backbytes &= 0xff;
	  if ( ! backbytes ) {
	    if (cdst >= dest+dsize)
	      return -1;
	    *cdst++=0x00;
	    continue;
	  }
	} else {
	  /* 18f */
	  if (csrc >= source+ssize)
	    return -1;
	  backbytes = *(unsigned char*)csrc;
	  backsize = backsize * 2 + (backbytes & 1);
	  backbytes = (backbytes & 0xff)>>1;
	  csrc++;
	  if (! backbytes)
	    break;
	  backsize+=2;
	  oldback = backbytes;
	  lostbit = 0;
	}
      } else {
	/* 180 */
	backsize = 1;
	do {
	  if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	    return -1;
	  backsize = backsize*2+oob;
	  if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	    return -1;
	} while (oob);

	backsize = backsize - 1 - lostbit;
	if (! backsize) {
	  /* 18a */
	  backsize = 1;
	  do {
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	    backsize = backsize*2+oob;
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	  } while (oob);

	  backbytes = oldback;
	} else {
	  /* 198 */
	  if (csrc >= source+ssize)
	    return -1;
	  backbytes = *(unsigned char*)csrc;
	  backbytes += (backsize-1)<<8;
	  backsize = 1;
	  csrc++;
	  do {
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	    backsize = backsize*2+oob;
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	  } while (oob);

          if (backbytes >= 0x7d00)
            backsize++;
          if (backbytes >= 0x500)
            backsize++;
          if (backbytes <= 0x7f)
            backsize += 2;

	  oldback = backbytes;
	}
	lostbit = 0;
      }
      if (!CLI_ISCONTAINED(dest, dsize, cdst, backsize) || !CLI_ISCONTAINED(dest, dsize, cdst-backbytes, backsize))
	return -1;
      while(backsize--) {
	*cdst=*(cdst-backbytes);
	cdst++;
      }

    } else {
      /* 15d */
      if (cdst < dest || cdst >= dest+dsize || csrc < source || csrc >= source+ssize)
	return -1;
      *cdst++=*csrc++;
      lostbit=1;
    }
  }

  if (endsrc) *endsrc = csrc;
  if (enddst) *enddst = cdst;
  return 0;
}

int unmew(char *source, char *dest, int ssize, int dsize, char **endsrc, char **enddst) {
  uint8_t mydl=0x80;
  uint32_t myeax_backbytes, myecx_backsize, oldback = 0;
  char *csrc = source, *cdst = dest;
  int oob, lostbit = 1;

  *cdst++=*csrc++;

  while ( 1 ) {
    if ((oob=doubledl(&csrc, &mydl, source, ssize))) {
      if (oob == -1)
	return -1;
      /* 164 */
      myecx_backsize = 0;
      if ((oob=doubledl(&csrc, &mydl, source, ssize))) {
	if (oob == -1)
	  return -1;
	/* 16a */
	myeax_backbytes = 0;
	if ((oob=doubledl(&csrc, &mydl, source, ssize))) {
	  if (oob == -1)
	    return -1;
	  /* 170 */
	  lostbit = 1;
	  myecx_backsize++;
	  myeax_backbytes = 0x10;
	  while ( myeax_backbytes < 0x100 ) {
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	    myeax_backbytes = myeax_backbytes*2+oob;
	  }
	  myeax_backbytes &= 0xff;
	  if ( ! myeax_backbytes ) {
	    if (cdst >= dest+dsize)
	      return -1;
	    *cdst++=0x00;
	    /*cli_dbgmsg("X%02x  ", *(cdst-1)&0xff);*/
	    continue;
	  }
	} else {
	  /* 18f */
	  if (csrc >= source+ssize)
	    return -1;
	  myeax_backbytes = *(unsigned char*)csrc;
	  myecx_backsize = myecx_backsize * 2 + (myeax_backbytes & 1);
	  myeax_backbytes = (myeax_backbytes & 0xff)>>1;
	  csrc++;
	  if (! myeax_backbytes)
	  {
	    /* cli_dbgmsg("\nBREAK \n"); */
	    break;
	  }
	  myecx_backsize+=2;
	  oldback = myeax_backbytes;
	  lostbit = 0;
	}
      } else {
	/* 180 */
	myecx_backsize = 1;
	do {
	  if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	    return -1;
	  myecx_backsize = myecx_backsize*2+oob;
	  if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	    return -1;
	} while (oob);

	myecx_backsize = myecx_backsize - 1 - lostbit;
	if (! myecx_backsize) {
	  /* 18a */
	  myecx_backsize = 1;
	  do {
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	    myecx_backsize = myecx_backsize*2+oob;
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	  } while (oob);

	  myeax_backbytes = oldback;
	} else {
	  /* 198 */
	  if (csrc >= source+ssize)
	    return -1;
	  myeax_backbytes = *(unsigned char*)csrc;
	  myeax_backbytes += (myecx_backsize-1)<<8;
	  myecx_backsize = 1;
	  csrc++;
	  do {
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	    myecx_backsize = myecx_backsize*2+oob;
	    if ((oob=doubledl(&csrc, &mydl, source, ssize)) == -1)
	      return -1;
	  } while (oob);

          if (myeax_backbytes >= 0x7d00)
            myecx_backsize++;
          if (myeax_backbytes >= 0x500)
            myecx_backsize++;
          if (myeax_backbytes <= 0x7f)
            myecx_backsize += 2;

	  oldback = myeax_backbytes;
	}
	lostbit = 0;
      }
      if (!CLI_ISCONTAINED(dest, dsize, cdst, myecx_backsize) || !CLI_ISCONTAINED(dest, dsize, cdst-myeax_backbytes, myecx_backsize))
      {
	cli_dbgmsg("MEW: rete: %d %d %d %d %d || %d %d %d %d %d\n", dest, dsize, cdst, myecx_backsize,
			CLI_ISCONTAINED(dest, dsize, cdst, myecx_backsize),
			dest, dsize, cdst-myeax_backbytes, myecx_backsize,
      			CLI_ISCONTAINED(dest, dsize, cdst-myeax_backbytes, myecx_backsize) );
	return -1;
      }
      while(myecx_backsize--) {
	*cdst=*(cdst-myeax_backbytes);
	cdst++;
      }

    } else {
      /* 15d */
      if (cdst < dest || cdst >= dest+dsize || csrc < source || csrc >= source+ssize)
      {
	cli_dbgmsg("MEW: retf %08x %08x+%08x=%08x, %08x %08x+%08x=%08x\n",
			cdst, dest, dsize, dest+dsize, csrc, source, ssize, source+ssize);
	return -1;
      }
      *cdst++=*csrc++;
      /* cli_dbgmsg("Z%02x  ", *(cdst-1)&0xff); */
      lostbit=1;
    }
  }

  *endsrc = csrc;
  *enddst = cdst;
  return 0;
}
