decompile.c

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

C
1,406
字号
      case SWFACTION_GETURL2:	printf("getURL(");	listItem(t->right->data.tree->left, SWFACTION_GETURL2);	printf(", ");	listItem(t->right->data.tree->right, SWFACTION_GETURL2);	switch((int)t->left)	{	  case 0: printf(")"); break;	  case 1: printf(", GET)"); break;	  case 2: printf(", POST)"); break;	  default: printf(", 0x%x /* ??? */)", (int)t->left);	}	break;      case SWFACTION_CALLFRAME:	printf("callFrame(");	listItem(t->left, SWFACTION_CALLFRAME);        putchar(')');	break;      case SWFACTION_GOTOEXPRESSION:	printf("gotoFrame(");	listItem(t->left, SWFACTION_GOTOEXPRESSION);        putchar(')');	if((int)t->right == 1)	  printf(";\nplay()");	break;      case SWFACTION_SETTARGET:	if(((char *)t->left)[0] == '\0')	  printf("setTarget(this)");	else	  printf("setTarget('%s')", (char *)t->left);	break;      case SWFACTION_GOTOLABEL:	printf("gotoFrame('%s')", (char *)t->left);	break;	/* branches - shouldn't see these */      case SWFACTION_BRANCHIFTRUE:	printf("if(");	listItem(t->left, SWFACTION_BRANCHIFTRUE);	printf(") branch %i", (int)t->right);	break;      case SWFACTION_BRANCHALWAYS:	printf("branch %i", (int)t->right);	break;      case SWFACTION_WAITFORFRAME:	printf("Wait for frame %i ", (int)t->left);	printf(" else skip %i", (int)t->right);	break;      default:	break;      }  }}static int isStatement(Stack s){  Tree t;  if(s->type != 't')    return 0;  t = s->data.tree;  switch(t->action)  {    case SWFACTION_NEXTFRAME:    case SWFACTION_PREVFRAME:    case SWFACTION_PLAY:    case SWFACTION_STOP:    case SWFACTION_TOGGLEQUALITY:    case SWFACTION_STOPSOUNDS:    case SWFACTION_GOTOFRAME:    case SWFACTION_GETURL:    case SWFACTION_SETTARGET:    case SWFACTION_GOTOLABEL:    case SWFACTION_SETVARIABLE:    case SWFACTION_SETTARGETEXPRESSION:    case SWFACTION_SETPROPERTY:    case SWFACTION_DUPLICATECLIP:    case SWFACTION_REMOVECLIP:    case SWFACTION_TRACE:    case SWFACTION_STARTDRAGMOVIE:    case SWFACTION_STOPDRAGMOVIE:    case SWFACTION_WAITFORFRAMEEXPRESSION:    case SWFACTION_BRANCHALWAYS:    case SWFACTION_GETURL2:    case SWFACTION_BRANCHIFTRUE:    case SWFACTION_CALLFRAME:    case SWFACTION_GOTOEXPRESSION:	case SWFACTION_POP:      return 1;    default:      return 0;  }}static Stack readStatement(FILE *f){  Stack s;  for(;;)  {    if(feof(f))      return NULL;    if((s = readActionRecord(f)) == NULL)      return NULL;    if(stack == NULL && isStatement(s))      /* supposedly, we've got a complete statement. */      return s;    else      push(s);  }}static Stack negateExpression(Stack s){  Tree t = s->data.tree;  Stack ret;  if(s->type != 't')    return s;  if(t->action == SWFACTION_LOGICALNOT)  {    ret = t->left;    /* free(t); */    return ret;  }  return newTree(s, SWFACTION_LOGICALNOT, NULL);}#define STATEMENTS_INCREMENT 16void decompile4Action(FILE *f, int length, int indent){  Stack s, *statements = NULL;  int /*i, j,*/ off, nStatements = 0;  int end = fileOffset+length;  /* pass 1: read all statements */  while(fileOffset<end)  {    if(nStatements%STATEMENTS_INCREMENT == 0)      statements = (Stack *)realloc(statements,				    (nStatements+STATEMENTS_INCREMENT) * 				    sizeof(Stack));    off = fileOffset;    s = readStatement(f);    if(s!=NULL)    {      s->offset = off;      statements[nStatements++] = s;    }    else    {      /* give branch something to target */      s = newStack();      statements[nStatements] = s;      s->offset = off;      if(fileOffset<end)	error("unexpected End action!");    }  }  /*  for(i=0; i<nStatements; ++i)  {    printf("%03i|%04i:  ", i, statements[i]->offset);    listItem(statements[i], SWFACTION_END);    putchar(';');    putchar('\n');  }  */  resolveOffsets(statements, nStatements);  untangleBranches(statements, 0, nStatements, BRANCH_NONE, 0);  putchar('\n');  if(stack != NULL)  {    printf("Decompiler error: stack not empty!\n");    printf("Here's what's left over:\n\n");    /* dump stack remains */    while(stack)    {      listItem(stack, SWFACTION_END);      putchar(';');      putchar('\n');      stack = stack->next;    }    destroy(stack);    stack = NULL;  }}static void resolveOffsets(Stack *statements, int nStatements){  int i, j;  /* first change branch byte offsets to statement offsets */  for(i=0; i<nStatements; ++i)  {    Tree t = statements[i]->data.tree;    if(t->action == SWFACTION_BRANCHIFTRUE ||       t->action == SWFACTION_BRANCHALWAYS)    {      int offset = (int)t->right + statements[i+1]->offset;      if((int)t->right > 0)      {	for(j=i+2; j<nStatements; ++j)	{	  if(statements[j]->offset > offset)	    error("went too far!");	  if(statements[j]->offset == offset)	    break;	}	if(j==nStatements+1)	  error("couldn't find (forward) target offset!");      }      else      {	for(j=i; j>=0; --j)	{	  if(statements[j]->offset < offset)	    error("went too far!");	  if(statements[j]->offset == offset)	    break;	}	if(j==-1)	  error("couldn't find (backward) target offset!");      }      t->right = (Stack)j;      statements[j]->target = i;    }  }}#define INDENT { int ii=indent; while(ii-->0) { putchar(' '); putchar(' '); } }static void untangleBranches(Stack *statements, int start, int stop,			     Branchtype type, int indent){  Stack s;  Tree t;  int i, offset, end, hasElse, wasIf = 0;  for(i=start; i<stop; ++i)  {    s = statements[i];    t = s->data.tree;    if(s->target > i && t->action != SWFACTION_BRANCHIFTRUE)    {      /* it's a do loop */      int target = s->target;      if(s->target < start || s->target > stop)	error("stmt %i: do target (%i) outside scope (%i,%i)!",	      i, s->target, start, stop);      putchar('\n');      INDENT        printf("do\n");      INDENT	printf("{\n");      s->target = -1;      untangleBranches(statements, i, target, BRANCH_DO, indent+1);      INDENT	printf("}\n");      INDENT	printf("while(");        listItem(statements[target]->data.tree->left, SWFACTION_END);        printf(");\n");      wasIf = 1;      i = target;      continue;    }    if(t->action == SWFACTION_BRANCHALWAYS)      error("stmt %i: unexpected unconditional branch!", i);    if(t->action != SWFACTION_BRANCHIFTRUE)    {      /* it's just a statement. */      if(wasIf)	putchar('\n');      INDENT	listItem(s, SWFACTION_END);        putchar(';');        putchar('\n');      wasIf = 0;      continue;    }    offset = (int)t->right;    if(offset < start || offset > stop)      error("stmt %i: branch target (%i) outside scope (%i,%i)!",	    i, offset, start, stop);    if(offset < i)      error("stmt %i: Unexpected backwards branch!", i);    if(type==BRANCH_WHILE || type==BRANCH_DO)    {      if(offset == stop)      {	INDENT	  printf("break;\n");	continue;      }      else if(offset == start)      {	INDENT	  printf("continue;\n");	continue; /*ha!*/      }    }    if(statements[offset-1]->data.tree->action == SWFACTION_BRANCHALWAYS &&       (int)statements[offset-1]->data.tree->right == i)    {      /* it's a while loop */      putchar('\n');      INDENT	printf("while(");        listItem(negateExpression(t->left), SWFACTION_END);        printf(")\n");      if(i < offset-3)      {	INDENT	  putchar('{');	  putchar('\n');      }      untangleBranches(statements, i+1, offset-1, BRANCH_WHILE, indent+1);      if(i < offset-3)      {	INDENT	  putchar('}');	  putchar('\n');      }      wasIf = 1;      i = offset-1;      continue;    }    /* it's an if */    if(i>start)      putchar('\n');    if(statements[offset-1]->data.tree->action == SWFACTION_BRANCHALWAYS)    {      /* got an else */      hasElse = 1;      end = (int)statements[offset-1]->data.tree->right;    }    else    {      hasElse = 0;      end = offset;    }    if(end < start || end > stop)      error("stmt %i: else target (%i) outside scope (%i,%i)!",	    i, end, start, stop);    if(end < i)      error("stmt %i: Unexpected backwards branch!", i);    INDENT      printf("if(");    /* XXX - would like to reverse else and if if expression is already       negated.. */    listItem(negateExpression(t->left), SWFACTION_END);    putchar(')');    putchar('\n');    if(i < offset-(hasElse?3:2))    {      INDENT	putchar('{');        putchar('\n');    }    /* if hasElse, i+1 to offset-1 */    untangleBranches(statements, i+1, offset-(hasElse?1:0), BRANCH_IF, indent+1);    if(i < offset-(hasElse?3:2))    {      INDENT	putchar('}');        putchar('\n');    }    if(hasElse)    {      INDENT	printf("else\n");      if(offset+2 < end)      {	INDENT	  putchar('{');          putchar('\n');      }      untangleBranches(statements, offset, end, BRANCH_ELSE, indent+1);      if(offset+2 < end)      {	INDENT	  putchar('}');	  putchar('\n');      }    }    wasIf = 1;    i = end-1;  }}

⌨️ 快捷键说明

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