⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compile.cpp

📁 flash文件的解码程序
💻 CPP
字号:

#ifndef WIN32
  #include <unistd.h>
#endif

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

#include "common.h"
#include "compile.h"

static int nConstants;
static char *constants[256];

extern int SWF_versionNum;

/* XXX - temp hack until we check at compile time */

enum
{
  SWF_BIG_ENDIAN,
  SWF_LITTLE_ENDIAN
};

static int sbyteorder;

void checksbyteOrder()
{
  unsigned int x;
  unsigned char *p;

  x = 0x01020304;
  p = (unsigned char *)&x;

  if(*p == 1)
    sbyteorder = SWF_BIG_ENDIAN;
  else
    sbyteorder = SWF_LITTLE_ENDIAN;
}


char *stringConcat(char *a, char *b)
{
  if(a)
  {
    a = (char *)realloc(a, strlen(a)+strlen(b)+1);
    strcat(a,b);
    free(b);
    return a;
  }
  else
    return b;
}

void bufferPatchLength(Buffer buffer, int back)
{
  unsigned char *output = (unsigned char *)buffer->buffer;
  int len = bufferLength(buffer);

  output[len-back-1] = (back>>8) & 0xff;
  output[len-back-2] = back & 0xff;
}


/* add len more sbytes to length of the pushdata opcode pointed to by
   buffer->pushloc */

void bufferPatchPushLength(Buffer buffer, int len)
{
  int oldsize;

  if(buffer->pushloc != NULL)
  {
    oldsize = (buffer->pushloc[0] & 0xff) | ((buffer->pushloc[1] & 0xff) << 8);
    oldsize += len;
    buffer->pushloc[0] = oldsize & 0xff;
    buffer->pushloc[1] = (oldsize >> 8) & 0xff;
  }
  else
    SWF_error("problem with bufferPatchPushLength\n");
}


int addConstant(char *s)
{
  int i;

  for(i=0; i<nConstants; ++i)
  {
    if(strcmp(s, constants[i]) == 0)
      return i;
  }

  if(nConstants < 256)
  {
    constants[nConstants] = strdup(s);
    return nConstants++;
  }
  else
    return -1;
}

int bufferWriteConstants(Buffer out)
{
  int i, len=2;

  if(nConstants == 0)
    return 0;

  bufferWriteU8(out, SWFACTION_CONSTANTPOOL);
  bufferWriteS16(out, 0); /* length */
  bufferWriteS16(out, nConstants);

  for(i=0; i<nConstants; ++i)
  {
    len += bufferWriteHardString(out, constants[i], strlen(constants[i])+1);
    free(constants[i]);
  }

  nConstants = 0;

  bufferPatchLength(out, len);

  return len+3;
}

Buffer newBuffer()
{
  Buffer out = (Buffer)malloc(BUFFER_SIZE);
  memset(out, 0, BUFFER_SIZE);

  out->buffer = (char *)malloc(BUFFER_INCREMENT);
  out->pos = out->buffer;
  *(out->pos) = 0;
  out->buffersize = out->free = BUFFER_INCREMENT;
  out->pushloc = NULL;

  return out;
}

void destroyBuffer(Buffer out)
{
  if(out)
  {
    free(out->buffer);
    free(out);
  }
}

int bufferLength(Buffer out)
{
  if(out)
    return (out->pos)-(out->buffer);
  else
    return 0;
}

/* make sure there's enough space for sbytes sbytes */
void bufferCheckSize(Buffer out, int sbytes)
{
  if(sbytes > out->free)
  {
    int new_ = BUFFER_INCREMENT * ((sbytes-out->free-1)/BUFFER_INCREMENT + 1);

    int num = bufferLength(out); /* in case buffer gets displaced.. */
    unsigned char *newbuf = (unsigned char *)realloc(out->buffer, out->buffersize+new_);

    if((char *)newbuf != (char *)out->buffer)
    {
      int pushd;

      if(out->pushloc)
	pushd = out->pos - out->pushloc;

      out->pos = (char *)newbuf+num;

      if(out->pushloc)
	out->pushloc = out->pos - pushd;
    }

    out->buffer = (char *)newbuf;
    out->buffersize += new_;
    out->free += new_;
  }
}

int bufferWriteData(Buffer b, sbyte *data, int length)
{
  int i;

  bufferCheckSize(b, length);

  for(i=0; i<length; ++i)
    bufferWriteU8(b, data[i]);

  return length;
}

int bufferWriteBuffer(Buffer a, Buffer b)
{
  if(!a)
    return 0;

  if(b)
    return bufferWriteData(a, b->buffer, bufferLength(b));

  return 0;
}

/* if a's last op and b's first op are both PUSHDATA, concat into one op */

int bufferWriteDataAndPush(Buffer a, Buffer b)
{
  int i, pushd;

  sbyte *data = b->buffer;
  int length = b->pos - b->buffer;

  if(a->pushloc && (b->buffer[0] == SWFACTION_PUSHDATA) && SWF_versionNum > 4)
  {
    pushd = (b->buffer[1] & 0xff) | ((b->buffer[2] & 0xff) << 8);
    bufferPatchPushLength(a, pushd);
    data += 3;
    length -= 3;
  }

  if(b->pushloc)
    pushd = b->pos - b->pushloc;

  bufferCheckSize(a, length);

  for(i=0; i<length; ++i)
    bufferWriteU8(a, data[i]);

  if(a->pushloc &&
     (b->buffer[0] == SWFACTION_PUSHDATA) && (b->pushloc == b->buffer+1))
    ; /* b is just one pushdata, so do nothing.. */
  else if(b->pushloc)
    a->pushloc = a->pos - pushd;
  else
    a->pushloc = 0;

  return length;
}

int bufferConcat(Buffer a, Buffer b)
{
  int len = 0;

  if(!a)
    return 0;

  if(b)
    len = bufferWriteDataAndPush(a, b);

  destroyBuffer(b);

  return len;
}

int bufferWriteOp(Buffer out, int data)
{
  bufferWriteU8(out, data);
  out->pushloc = NULL;

  return 1;
}

int bufferWritePushOp(Buffer out)
{
  bufferWriteU8(out, SWFACTION_PUSHDATA);
  out->pushloc = out->pos;

  return 1;
}

int bufferWriteU8(Buffer out, int data)
{
  bufferCheckSize(out, 1);
  *(out->pos) = data;
  out->pos++;
  out->free--;

  return 1;
}

int bufferWriteS16(Buffer out, int data)
{
  if(data < 0)
    data = (1<<16)+data;

  bufferWriteU8(out, data%256);
  data >>= 8;
  bufferWriteU8(out, data%256);

  return 2;
}

int bufferWriteHardString(Buffer out, sbyte *string, int length)
{
  int i;

  for(i=0; i<length; ++i)
    bufferWriteU8(out, string[i]);

  return length;
}

int bufferWriteConstantString(Buffer out, sbyte *string, int length)
{
  int n;

  if(SWF_versionNum < 5)
    return -1;

  n = addConstant(string);

  if(n == -1)
  {
    bufferWriteU8(out, PUSH_STRING);
    return bufferWriteHardString(out, string, length) + 1;
  }
  else
  {
    bufferWriteU8(out, PUSH_CONSTANT);
    return bufferWriteU8(out, n) + 1;
  }
}

int bufferWriteString(Buffer out, sbyte *string, int length)
{
  if(SWF_versionNum < 5)
  {
    bufferWritePushOp(out);
    bufferWriteS16(out, length+1);
    bufferWriteU8(out, PUSH_STRING);
    bufferWriteHardString(out, string, length);

    return 4 + length;
  }
  else
  {
    int l;

    if(out->pushloc == NULL)
    {
      bufferWritePushOp(out);
      bufferWriteS16(out, 0);
    }

    l = bufferWriteConstantString(out, string, length);

    bufferPatchPushLength(out, l);
    return l;
  }
}

int bufferWriteInt(Buffer out, int i)
{
  int len = 0;
  unsigned char *p = (unsigned char *)&i;

  if(out->pushloc == NULL || SWF_versionNum < 5)
  {
    len = 3;
    bufferWritePushOp(out);
    bufferWriteS16(out, 5);
  }
  else
    bufferPatchPushLength(out, 5);

  bufferWriteU8(out, PUSH_INT);

  if(sbyteorder == SWF_LITTLE_ENDIAN)
  {
    bufferWriteU8(out, p[0]);
    bufferWriteU8(out, p[1]);
    bufferWriteU8(out, p[2]);
    bufferWriteU8(out, p[3]);
  }
  else
  {
    bufferWriteU8(out, p[3]);
    bufferWriteU8(out, p[2]);
    bufferWriteU8(out, p[1]);
    bufferWriteU8(out, p[0]);
  }

  return len + 5;
}

int bufferWriteDouble(Buffer out, double d)
{
  int len = 0;
  unsigned char *p = (unsigned char *)&d;

  if(out->pushloc == NULL || SWF_versionNum < 5)
  {
    len = 3;
    bufferWritePushOp(out);
    bufferWriteS16(out, 9);
  }
  else
    bufferPatchPushLength(out, 5);

  bufferWriteU8(out, PUSH_DOUBLE);

  if(sbyteorder == SWF_LITTLE_ENDIAN)
  {
    bufferWriteU8(out, p[4]);
    bufferWriteU8(out, p[5]);
    bufferWriteU8(out, p[6]);
    bufferWriteU8(out, p[7]);
    bufferWriteU8(out, p[0]);
    bufferWriteU8(out, p[1]);
    bufferWriteU8(out, p[2]);
    bufferWriteU8(out, p[3]);
  }
  else
  {
    bufferWriteU8(out, p[3]);
    bufferWriteU8(out, p[2]);
    bufferWriteU8(out, p[1]);
    bufferWriteU8(out, p[0]);
    bufferWriteU8(out, p[7]);
    bufferWriteU8(out, p[6]);
    bufferWriteU8(out, p[5]);
    bufferWriteU8(out, p[4]);
  }

  return len + 9;
}

int bufferWriteNull(Buffer out)
{
  int len = 0;

  if(out->pushloc == NULL || SWF_versionNum < 5)
  {
    len = 3;
    bufferWritePushOp(out);
    bufferWriteS16(out, 1);
  }
  else
    bufferPatchPushLength(out, 1);

  bufferWriteU8(out, PUSH_NULL);

  return len + 1;
}

int bufferWriteBoolean(Buffer out, int val)
{
  int len = 0;

  if(out->pushloc == NULL || SWF_versionNum < 5)
  {
    len = 3;
    bufferWritePushOp(out);
    bufferWriteS16(out, 2);
  }
  else
    bufferPatchPushLength(out, 2);

  bufferWriteU8(out, PUSH_BOOLEAN);
  bufferWriteU8(out, val ? 1 : 0);

  return len + 2;
}

int bufferWriteRegister(Buffer out, int num)
{
  int len = 0;

  if(out->pushloc == NULL || SWF_versionNum < 5)
  {
    len = 3;
    bufferWritePushOp(out);
    bufferWriteS16(out, 2);
  }
  else
    bufferPatchPushLength(out, 2);

  bufferWriteU8(out, PUSH_REGISTER);
  bufferWriteU8(out, num);

  return len + 2;
}

int bufferWriteSetRegister(Buffer out, int num)
{
  bufferWriteU8(out, SWFACTION_SETREGISTER);
  bufferWriteS16(out, 1);
  bufferWriteU8(out, num);
  return 4;
}

void lower(char *s)
{
  while(*s)
  {
    *s = tolower(*s);
    ++s;
  }
}

/* replace MAGIC_CONTINUE_NUMBER and MAGIC_BREAK_NUMBER with jumps to
   head or tail, respectively */
/* jump offset is relative to end of jump instruction */
/* I can't believe this actually worked */

void bufferResolveJumps(Buffer out)
{
  sbyte *p = out->buffer;
  int l, target;

  while(p < out->pos)
  {
    if(*p & 0x80) /* then it's a multisbyte instruction */
    {
      if(*p == SWFACTION_BRANCHALWAYS)
      {
	p += 3; /* plus instruction plus two-sbyte length */

	if(*p == MAGIC_CONTINUE_NUMBER_LO &&
	   *(p+1) == MAGIC_CONTINUE_NUMBER_HI)
	{
	  target = out->buffer - (p+2);
	  *p = target & 0xff;
	  *(p+1) = (target>>8) & 0xff;
	}
	else if(*p == MAGIC_BREAK_NUMBER_LO &&
		*(p+1) == MAGIC_BREAK_NUMBER_HI)
	{
	  target = out->pos - (p+2);
	  *p = target & 0xff;
	  *(p+1) = (target>>8) & 0xff;
	}

	p += 2;
      }
      else
      {
	++p;
	l = *p;
	++p;
	l += *p<<8;
	++p;

	p += l;
      }
    }
    else
      ++p;
  }
}

int lookupSetProperty(char *string)
{
  lower(string);

  if(strcmp(string,"x")==0)		return 0x0000;
  if(strcmp(string,"y")==0)		return 0x3f80;
  if(strcmp(string,"xscale")==0)	return 0x4000;
  if(strcmp(string,"yscale")==0)	return 0x4040;
  if(strcmp(string,"alpha")==0)		return 0x40c0;
  if(strcmp(string,"visible")==0)	return 0x40e0;
  if(strcmp(string,"rotation")==0)	return 0x4120;
  if(strcmp(string,"name")==0)		return 0x4140;
  if(strcmp(string,"quality")==0)	return 0x4180;
  if(strcmp(string,"focusrect")==0)	return 0x4188;
  if(strcmp(string,"soundbuftime")==0)	return 0x4190;

  SWF_error("No such property: %s\n", string);
  return -1;
}

int bufferWriteSetProperty(Buffer out, char *string)
{
  int property = lookupSetProperty(string);

  bufferWriteU8(out, SWFACTION_PUSHDATA);
  bufferWriteS16(out, 5);
  bufferWriteU8(out, PUSH_PROPERTY);
  bufferWriteS16(out, 0);
  bufferWriteS16(out, property);

  return 8;
}

int bufferWriteWTHITProperty(Buffer out)
{
  bufferWriteU8(out, SWFACTION_PUSHDATA);
  bufferWriteS16(out, 5);
  bufferWriteU8(out, PUSH_PROPERTY);
  bufferWriteS16(out, 0);
  bufferWriteS16(out, 0x4680);

  return 8;
}

char *lookupGetProperty(char *string)
{
  lower(string);

  if(strcmp(string,"x")==0)		return "0";
  if(strcmp(string,"y")==0)		return "1";
  if(strcmp(string,"xscale")==0)	return "2";
  if(strcmp(string,"yscale")==0)	return "3";
  if(strcmp(string,"currentframe")==0)	return "4";
  if(strcmp(string,"totalframes")==0)	return "5";
  if(strcmp(string,"alpha")==0)		return "6";
  if(strcmp(string,"visible")==0)	return "7";
  if(strcmp(string,"width")==0)		return "8";
  if(strcmp(string,"height")==0)	return "9";
  if(strcmp(string,"rotation")==0)	return "10";
  if(strcmp(string,"target")==0)	return "11";
  if(strcmp(string,"framesloaded")==0)	return "12";
  if(strcmp(string,"name")==0)		return "13";
  if(strcmp(string,"droptarget")==0)	return "14";
  if(strcmp(string,"url")==0)		return "15";
  if(strcmp(string,"quality")==0)	return "16";
  if(strcmp(string,"focusrect")==0)	return "17";
  if(strcmp(string,"soundbuftime")==0)	return "18";

  SWF_error("No such property: %s\n", string);
  return "";
}

int bufferWriteGetProperty(Buffer out, char *string)
{
  char *property = lookupGetProperty(string);

  bufferWriteU8(out, SWFACTION_PUSHDATA);
  bufferWriteS16(out, strlen(property)+2);
  bufferWriteU8(out, PUSH_STRING);

  return 4 + bufferWriteData(out, property, strlen(property)+1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -