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 + -
显示快捷键?