decompile.c

来自「flash swf file player」· C语言 代码 · 共 1,406 行 · 第 1/3 页

C
1,406
字号
/*  take a stack, turn it into a tree.  e.g.:  cmd        stack  push 'a'   'a'  push 'a'   'a' 'a'  getvar     'a'  a  push '1'   'a'  a   1  add        'a'  a+1  setvar     a = a+1*/#include <assert.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "decompile.h"#include "read.h"#include "action.h"typedef enum{  BRANCH_NONE = 0,  BRANCH_WHILE,  BRANCH_DO,  BRANCH_IF,  BRANCH_ELSE} Branchtype;static void listItem(Stack s, Action parent);static void resolveOffsets(Stack *statements, int nStatements);static void untangleBranches(Stack *statements, int start, int stop,			     Branchtype type, int indent);static int isNum(char *s){  float f = atof(s);  if(f != 0 || s[0] == '0')    return true;  else    return false;}static Stack stack = NULL;static Stack newStack(){  Stack s = (Stack)malloc(sizeof(struct _stack));  memset(s, 0, sizeof(struct _stack));  s->target = -1;  return s;}static void destroy(Stack s){  if(!s)    return;  if(s->type == 't')  {    destroy(s->data.tree->left);    destroy(s->data.tree->right);    free(s->data.tree);  }  else if(s->type == 's')    free(s->data.string);  free(s);}static Stack newTree(Stack left, Action action, Stack right){  Tree t = (Tree)malloc(sizeof(struct _tree));  Stack s = newStack();  t->left = left;  t->right = right;  t->action = action;  s->type = 't';  s->data.tree = t;  return s;}static Stack newString(char *string){  Stack s = newStack();  s->type = 's';  s->data.string = string;  return s;}static Stack newProperty(Property prop){  Stack s = newStack();  s->type = 'p';  s->data.prop = prop;  return s;}static Stack pop(){  Stack s = stack;  if(!stack)    error("blown stack!");  stack = stack->next;  return s;}static void push(Stack s){  s->next = stack;  stack = s;}static char *negateString(char *s){  int i, l = strlen(s)+1;  char *New = realloc(s, l+1);  for(i=l; i>0; --i)    New[i] = New[i-1];  New[0] = '-';  return New;}static Property getSetProperty(int prop){  switch(prop)  {    case SWF_SETPROPERTY_X:		  return PROPERTY_X;    case SWF_SETPROPERTY_Y:		  return PROPERTY_Y;    case SWF_SETPROPERTY_XSCALE:	  return PROPERTY_XSCALE;    case SWF_SETPROPERTY_YSCALE:	  return PROPERTY_YSCALE;    case SWF_SETPROPERTY_ALPHA:		  return PROPERTY_ALPHA;    case SWF_SETPROPERTY_VISIBILITY:	  return PROPERTY_VISIBLE;    case SWF_SETPROPERTY_ROTATION:	  return PROPERTY_ROTATION;    case SWF_SETPROPERTY_NAME:		  return PROPERTY_NAME;    case SWF_SETPROPERTY_HIGHQUALITY:	  return PROPERTY_HIGHQUALITY;    case SWF_SETPROPERTY_SHOWFOCUSRECT:	  return PROPERTY_FOCUSRECT;    case SWF_SETPROPERTY_SOUNDBUFFERTIME: return PROPERTY_SOUNDBUFTIME;    case SWF_SETPROPERTY_WTHIT:		  return PROPERTY_WTHIT;    default:      error("unknown property: 0x%04x!", prop);      return SWF_SETPROPERTY_WTHIT;  }}static Stack readActionRecord(FILE *f){  int length = 0, type = readUInt8(f);  if((type&0x80) == 0x80)    length = readUInt16(f);  switch(type)  {    /* no-arg */    case SWFACTION_GETTIMER:    case SWFACTION_STOPDRAGMOVIE:    case SWFACTION_NEXTFRAME:    case SWFACTION_PREVFRAME:    case SWFACTION_PLAY:    case SWFACTION_STOP:    case SWFACTION_TOGGLEQUALITY:    case SWFACTION_STOPSOUNDS:      return newTree(NULL, type, NULL);    case SWFACTION_POP:	  /* pop(); */      return newTree(NULL, type, NULL);    /* one-arg */    case SWFACTION_STRINGLENGTH:    case SWFACTION_INT:    case SWFACTION_RANDOM:    case SWFACTION_MBLENGTH:    case SWFACTION_ORD:    case SWFACTION_CHR:    case SWFACTION_MBORD:    case SWFACTION_MBCHR:    case SWFACTION_LOGICALNOT:    case SWFACTION_GETVARIABLE:    case SWFACTION_REMOVECLIP:    case SWFACTION_TRACE:    case SWFACTION_SETTARGETEXPRESSION:    case SWFACTION_CALLFRAME:      return newTree(pop(), type, NULL);    /* two-arg */    case SWFACTION_ADD:    case SWFACTION_MULTIPLY:    case SWFACTION_DIVIDE:    case SWFACTION_EQUAL:    case SWFACTION_LESSTHAN:    case SWFACTION_LOGICALAND:    case SWFACTION_LOGICALOR:    case SWFACTION_STRINGEQ:    case SWFACTION_SETVARIABLE:    case SWFACTION_STRINGCONCAT:    case SWFACTION_STRINGCOMPARE:	{      Stack right = pop();      Stack left = pop();      return newTree(left, type, right);	}    case SWFACTION_GETPROPERTY:    {      Stack right = pop();      Stack left = pop();      if(right->type == 's')      {	Stack New = newProperty(atoi(right->data.string));	destroy(right);	right = New;      }      return newTree(left, type, right);    }    case SWFACTION_SUBTRACT:    {      Stack right = pop();      Stack left = pop();      if(left->type == 's' &&	 strcmp(left->data.string, "0") == 0)      {	destroy(left);	right->data.string = negateString(right->data.string);	return right;      }      return newTree(left, type, right);    }    /* three-arg */    case SWFACTION_SETPROPERTY:	{	  Stack value = pop();	  Stack property = pop();	  Stack target = pop();      if(property->type == 's')      {	Stack New = newProperty(atoi(property->data.string));	destroy(property);	property = New;      }      return newTree(newTree(target, type, property),		     SWFACTION_SETVARIABLE, value);	}    case SWFACTION_MBSUBSTRING:    case SWFACTION_SUBSTRING:	{	  Stack s3 = pop();	  Stack s2 = pop();	  Stack s1 = pop();      return newTree(s1, type, newTree(s2, type, s3));	}    case SWFACTION_DUPLICATECLIP:    {      Stack level = pop();      Stack target = pop();      Stack source = pop();      Stack arg;      if(level->type != 't' ||	 level->data.tree->action != SWFACTION_ADD)	error("WTHIT property not found in duplicateClip target level!");      if(level->data.tree->left->type == 'p' &&	 level->data.tree->left->data.prop == PROPERTY_WTHIT)      {        arg = level->data.tree->right;	level->data.tree->right = NULL;      }      else if(level->data.tree->right->type == 'p' &&	      level->data.tree->right->data.prop == PROPERTY_WTHIT)      {        arg = level->data.tree->left;        level->data.tree->left = NULL;      }      else	error("WTHIT property not found in duplicateClip target level!");      destroy(level);      return newTree(source, type, newTree(target, type, arg));    }    /* weird ops */    case SWFACTION_STARTDRAGMOVIE:    {      Stack target = pop();      Stack lockmouse = pop();      Stack constraint = pop();      if(constraint->type != 's')	error("Sorry, decompiler can't deal with conditional constraint!");      if(strcmp(constraint->data.string, "0") == 0)	return newTree(constraint, type, newTree(lockmouse, type, target));      else	  {		Stack s4 = pop();		Stack s3 = pop();		Stack s2 = pop();		Stack s1 = pop();	return newTree(newTree(newTree(s1, type, s2), type,			       newTree(s3, type, s4)), type,		       newTree(lockmouse, type, target));	  }    }    case SWFACTION_PUSHDATA:    {      int local_type = readUInt8(f);      if(local_type==0)	return newString(readString(f));      else      {	readUInt16(f); /* 0x0000 */        return newProperty(getSetProperty(readUInt16(f)));      }    }    case SWFACTION_GOTOFRAME:      return newTree((Stack)readUInt16(f), type, NULL);    case SWFACTION_GETURL:    {      char *url = readString(f);      char *target = readString(f);      return newTree((Stack)url, type, (Stack)target);    }    case SWFACTION_GETURL2:	{	  Stack target = pop();	  Stack url = pop();      return newTree((Stack)readUInt8(f), type, newTree(url, type, target));	}    case SWFACTION_WAITFORFRAMEEXPRESSION:      return newTree((Stack)readUInt8(f), type, NULL);    case SWFACTION_GOTOEXPRESSION:      return newTree(pop(), type, (Stack)readUInt8(f));    case SWFACTION_SETTARGET:    case SWFACTION_GOTOLABEL:      return newTree((Stack)readString(f), type, NULL);    /* branches */    case SWFACTION_BRANCHIFTRUE:      return newTree(pop(), type, (Stack)readSInt16(f));    case SWFACTION_BRANCHALWAYS:      return newTree(NULL, type, (Stack)readSInt16(f));    case SWFACTION_WAITFORFRAME:	{	  Stack left = (Stack)readUInt16(f);	  Stack right = (Stack)readUInt8(f);      return newTree(left, type, right);	}    case SWFACTION_END:      return NULL;    default:      printf("Unknown Action: %02X\n", type);      dumpBytes(f, length);      return NULL;  }}static void listProperty(Property prop){  switch(prop)  {    case PROPERTY_X:		   printf("x"); break;    case PROPERTY_Y:		   printf("y"); break;    case PROPERTY_XSCALE:	   printf("xScale"); break;    case PROPERTY_YSCALE:	   printf("yScale"); break;    case PROPERTY_CURRENTFRAME:	   printf("currentFrame"); break;    case PROPERTY_TOTALFRAMES:	   printf("totalFrames"); break;    case PROPERTY_ALPHA:	   printf("alpha"); break;    case PROPERTY_VISIBLE:	   printf("visible"); break;    case PROPERTY_WIDTH:	   printf("width"); break;    case PROPERTY_HEIGHT:	   printf("height"); break;    case PROPERTY_ROTATION:	   printf("rotation"); break;    case PROPERTY_TARGET:	   printf("target"); break;    case PROPERTY_FRAMESLOADED:	   printf("framesLoaded"); break;    case PROPERTY_NAME:		   printf("name"); break;    case PROPERTY_DROPTARGET:	   printf("dropTarget"); break;    case PROPERTY_URL:  	   printf("url"); break;    case PROPERTY_HIGHQUALITY:	   printf("quality"); break;    case PROPERTY_FOCUSRECT:       printf("focusRect"); break;    case PROPERTY_SOUNDBUFTIME:    printf("soundBufTime"); break;    case PROPERTY_WTHIT:	   printf("WTHIT!?"); break;    default:			   printf("unknown property!"); break;  }}static int precedence(Action type){  switch(type)  {    case SWFACTION_SETVARIABLE:    return 0;    case SWFACTION_LOGICALAND:     return 1;    case SWFACTION_LOGICALOR:      return 1;    case SWFACTION_LOGICALNOT:     return 2;    case SWFACTION_LESSTHAN:       return 3;    case SWFACTION_EQUAL:          return 3;    case SWFACTION_ADD:            return 4;    case SWFACTION_SUBTRACT:       return 4;    case SWFACTION_MULTIPLY:       return 5;    case SWFACTION_DIVIDE:         return 5;    case SWFACTION_GETVARIABLE:    return 6;    case SWFACTION_GETPROPERTY:    return 6;    case SWFACTION_STRINGEQ:       return 7;    case SWFACTION_STRINGCONCAT:   return 7;    case SWFACTION_PUSHDATA:       return 7;    case SWFACTION_SETPROPERTY:    return 8;    default:                       return 0;  }}typedef enum{  NONEGATE = 0,  NEGATE = 1} negateFlag;static void listLessThan(Stack s, negateFlag negate){  Stack left = s->data.tree->left, right = s->data.tree->right;

⌨️ 快捷键说明

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