📄 decompile5.c
字号:
if(s->offset == 0) s->offset = off; } } while(stack && stack->next && stack->next->type == 't') { if(stack->next->data.tree->action == SWFACTION_POP && (stack->next->next->data.tree->action == SWFACTION_LOGICALAND || stack->next->next->data.tree->action == SWFACTION_LOGICALOR)) { t = pop(); pop(); if(stack->data.tree->right != NULL) error("Was expecting logical op's right side to be empty!"); stack->data.tree->right = t; } else break; } return NULL; } /* check for conditions left on the stack from code above */ while(stack && stack->type == 't') { if(stack->data.tree->action == SWFACTION_LOGICALOR) { stack->data.tree->right = negateExpression(s); s = newTree(pop(), SWFACTION_LOGICALNOT, NULL); } else if(stack->data.tree->action == SWFACTION_LOGICALAND) { stack->data.tree->right = negateExpression(s); s = newTree(pop(), SWFACTION_LOGICALNOT, NULL); } else break; } t = newTreeBase(s, SWFACTION_BRANCHIFTRUE, (Stack)offset); t->offset = s->offset; return t; } case SWFACTION_BRANCHALWAYS: return newTreeBase(NULL, type, (Stack)readSInt16(f)); case SWFACTION_WAITFORFRAME: { Stack left = (Stack)readUInt16(f); Stack right = (Stack)readUInt8(f); return newTreeBase(left, type, right); } case SWFACTION_END: return NULL; /* v5 ops */ case SWFACTION_VAR: return newTree(pop(), type, NULL); case SWFACTION_VAREQUALS: { Stack right = pop(); Stack left = pop(); return newTree(left, type, right); } case SWFACTION_DELETE: return newTree(pop(), type, NULL); case SWFACTION_CALLFUNCTION: { Stack last = NULL, t; int i, off; Stack name = pop(); Stack nargs = pop(); if(nargs->type == 't') error("Sorry, decompiler can't deal with conditional nargs!"); for(i=intVal(nargs); i>0; --i) last = newTree(pop(), type, last); if(intVal(nargs) > 0) off = last->offset; else off = nargs->offset; last = newTreeBase((Stack)intVal(nargs), type, last); t = newTreeBase(name, type, last); t->offset = off; return t; } case SWFACTION_INCREMENT: case SWFACTION_DECREMENT: case SWFACTION_TYPEOF: case SWFACTION_RETURN: case SWFACTION_DUP: case SWFACTION_TONUMBER: case SWFACTION_TOSTRING: return newTree(pop(), type, NULL); case SWFACTION_MODULO: case SWFACTION_NEW: case SWFACTION_NEWADD: case SWFACTION_NEWLESSTHAN: case SWFACTION_NEWEQUAL: case SWFACTION_SHIFTLEFT: case SWFACTION_SHIFTRIGHT: case SWFACTION_SHIFTRIGHT2: case SWFACTION_BITWISEAND: case SWFACTION_BITWISEOR: case SWFACTION_BITWISEXOR: case SWFACTION_GETMEMBER: { Stack right = pop(); Stack left = pop(); return newTree(left, type, right); } case SWFACTION_SETMEMBER: { Stack p3 = pop(); Stack p2 = pop(); Stack p1 = pop(); return newTree(p1, type, newTree(p2, type, p3)); } case SWFACTION_CALLMETHOD: { Stack last = NULL, t; int i, off; Stack name = pop(); Stack object = pop(); Stack nargs = pop(); if(nargs->type == 't') error("Sorry, decompiler can't deal with conditional nargs!"); for(i=intVal(nargs); i>0; --i) last = newTree(pop(), type, last); if(intVal(nargs) > 0) off = last->offset; else off = nargs->offset; last = newTreeBase((Stack)intVal(nargs), type, last); t = newTree(name, type, newTree(object, type, last)); t->offset = off; return t; } case SWFACTION_DECLARENAMES: { int i, items = readUInt8(f); readUInt8(f); /* should just keep static dictionary[256]? */ dictionary = realloc(dictionary, items*sizeof(char *)); for(i=0; i<items; ++i) dictionary[i] = readString(f); return NULL; } case SWFACTION_WITH: { Stack *statements; int size = readUInt16(f); int n = readStatements(f, size, &statements); return newTree(pop(), type, newTreeBase((Stack)n, type, (Stack)statements)); } case SWFACTION_DEFINEFUNCTION: { Stack tree, p, *statements; int nargs, size, n; char *name = readString(f); tree = newTreeBase((Stack)name, type, NULL); nargs = readUInt16(f); p = tree; for(; nargs>0; --nargs) { p->data.tree->right = newTreeBase((Stack)readString(f), type, NULL); p = p->data.tree->right; } size = readUInt16(f); n = readStatements(f, size, &statements); return newTree(tree, type, newTreeBase((Stack)n, type, (Stack)statements)); } case SWFACTION_ENUMERATE: return newTree(pop(), type, NULL); case SWFACTION_SETREGISTER: { Stack s, t; if(length != 1) error("Unexpected length (!=1) in setregister"); s = pop(); t = newTreeBase((Stack)readUInt8(f), type, s); t->offset = s->offset; return t; } case SWFACTION_INITOBJECT: { Stack *names, *values; int i, nEntries = intVal(pop()); names = malloc(sizeof(Stack) * nEntries); values = malloc(sizeof(Stack) * nEntries); for(i=0; i<nEntries; ++i) { names[i] = pop(); values[i] = pop(); } return newTreeBase((Stack)nEntries, type, newTreeBase((Stack)names, type, (Stack)values)); } case SWFACTION_INITARRAY: { Stack *names, *values; int i, nEntries = intVal(pop()); values = malloc(sizeof(Stack) * nEntries); for(i=0; i<nEntries; ++i) values[i] = pop(); return newTreeBase((Stack)nEntries, type, (Stack)values); } default: printf("Unknown Action: 0x%02X\n", type); dumpBytes(f, length); putchar('\n'); assert(0); return NULL; }}static void listProperty(Property prop){ switch(prop) { case PROPERTY_X: printf("_x"); break; case PROPERTY_Y: printf("_y"); break; case PROPERTY_XMOUSE: printf("_xMouse"); break; case PROPERTY_YMOUSE: printf("_yMouse"); 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_NEWEQUAL: return 3; case SWFACTION_SHIFTLEFT: return 4; case SWFACTION_SHIFTRIGHT: return 4; case SWFACTION_SHIFTRIGHT2: return 4; case SWFACTION_NEWADD: return 5; case SWFACTION_ADD: return 5; case SWFACTION_SUBTRACT: return 5; case SWFACTION_MULTIPLY: return 6; case SWFACTION_DIVIDE: return 6; case SWFACTION_BITWISEAND: return 7; case SWFACTION_BITWISEOR: return 7; case SWFACTION_BITWISEXOR: return 7; case SWFACTION_GETVARIABLE: return 8; case SWFACTION_GETPROPERTY: return 8; case SWFACTION_STRINGEQ: return 9; case SWFACTION_STRINGCONCAT: return 9; case SWFACTION_PUSHDATA: return 9; case SWFACTION_SETPROPERTY: return 10; 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; /* put variable on left */ if(left->type == 's' || (right->type == 't' && right->data.tree->action == SWFACTION_GETVARIABLE)) { listItem(right, SWFACTION_LESSTHAN); if(negate == NEGATE) printf(" <= "); else printf(" > "); listItem(left, SWFACTION_LESSTHAN); } else { listItem(left, SWFACTION_LESSTHAN); if(negate == NEGATE) printf(" >= "); else printf(" < "); listItem(right, SWFACTION_LESSTHAN); }}static void listNot(Stack s, Action parent){ /* check for !<, !=, !! */ /* put variable on left */ if(s->type == 't') { Tree t = s->data.tree; if(t->action == SWFACTION_LESSTHAN) { listLessThan(s, NEGATE); return; } else if(t->action == SWFACTION_LOGICALNOT) { listItem(s->data.tree->left, parent); return; } else if(t->action == SWFACTION_EQUAL) { listItem(s->data.tree->left, SWFACTION_EQUAL); printf(" != "); listItem(s->data.tree->right, SWFACTION_EQUAL); return; } } printf("!"); listItem(s, SWFACTION_LOGICALNOT);}static void listAssign(Stack s){ Stack left = s->data.tree->left; Stack right = s->data.tree->right; /* if it's a string, quote it (can't do it in listItem because we don't know what side of the equals sign we are..) */ if(right->type == 's') { listItem(left, SWFACTION_SETVARIABLE); puts(" = '"); listItem(right, SWFACTION_SETVARIABLE); putchar('\''); return; } /* check for ++a w/ increment op */ if(right->type == 't' && (right->data.tree->action == SWFACTION_INCREMENT || right->data.tree->action == SWFACTION_DECREMENT)) { Stack rleft = right->data.tree->left; if(rleft->type == 't' && rleft->data.tree->action == SWFACTION_GETVARIABLE && rleft->data.tree->left->type == 's' && left->type == 's' && strcmp(rleft->data.tree->left->data.string, left->data.string) == 0) { if(right->data.tree->action == SWFACTION_INCREMENT) puts("++"); else puts("--"); listItem(left, SWFACTION_SETVARIABLE); return; } } /* check for ++a and a+=b w/ traditional ops */ if(right->type == 't' && (right->data.tree->action == SWFACTION_NEWADD || (right->data.tree->action >= SWFACTION_ADD && right->data.tree->action <= SWFACTION_DIVIDE))) { Stack rleft = right->data.tree->left; Stack rright = right->data.tree->right; const char *op; if(right->data.tree->action == SWFACTION_ADD || right->data.tree->action == SWFACTION_NEWADD) op = " += "; else if(right->data.tree->action == SWFACTION_SUBTRACT) op = " -= "; else if(right->data.tree->action == SWFACTION_MULTIPLY) op = " -= "; else if(right->data.tree->action == SWFACTION_DIVIDE) op = " /= "; else error("Unexpected operation in listAssign!"); if(rleft->type == 't' && rleft->data.tree->action == SWFACTION_GETVARIABLE && rleft->data.tree->left->type == 's' && left->type == 's' && strcmp(rleft->data.tree->left->data.string, left->data.string) == 0) { if(rright->type == 's' && strcmp(rright->data.string, "1") == 0) { if(right->data.tree->action == SWFACTION_ADD || right->data.tree->action == SWFACTION_NEWADD) { puts("++"); listItem(left, SWFACTION_SETVARIABLE); return; } else if(right->data.tree->action == SWFACTION_SUBTRACT) { puts("--"); listItem(left, SWFACTION_SETVARIABLE); return; } } listItem(left, SWFACTION_SETVARIABLE); puts(op); listItem(rright, right->data.tree->action); return; } else if(rright->type == 't' && rright->data.tree->action == SWFACTION_GETVARIABLE && rright->data.tree->left->type == 's' && strcmp(rright->data.tree->left->data.string, left->data.string) == 0) { if(rleft->type == 's' && strcmp(rleft->data.string, "1") == 0) { if(right->data.tree->action == SWFACTION_ADD || right->data.tree->action == SWFACTION_NEWADD) { puts("++"); listItem(left, SWFACTION_SETVARIABLE); return; } else if(right->data.tree->action == SWFACTION_SUBTRACT) { puts("--"); listItem(left, SWFACTION_SETVARIABLE); return; } } listItem(left, SWFACTION_SETVARIABLE); puts(op); listItem(rleft, right->data.tree->action); return; } } listItem(left, SWFACTION_SETVARIABLE); puts(" = "); listItem(right, SWFACTION_SETVARIABLE);}static void listArithmetic(Stack s, Action parent){ int isShort, parens = 0; const char *op; Tree t = s->data.tree; Stack left = t->left, right = t->right; /* leave out spaces around op if either side's just a constant or variable */ /* but not if op is divide and right side starts w/ '/' */ isShort = !(t->action == SWFACTION_DIVIDE && right->type == 't' && right->data.tree->action == SWFACTION_GETVARIABLE && right->data.tree->left->data.string[0] == '/') && (left->type == 's' || (left->type == 't' && left->data.tree->action == SWFACTION_GETVARIABLE) || right->type == 's' || (right->type == 't' && right->data.tree->action == SWFACTION_GETVARIABLE)); switch(t->action) { case SWFACTION_NEWADD: case SWFACTION_ADD: op = (isShort?"+":" + "); break; case SWFACTION_SUBTRACT: op = (isShort?"-":" - "); break; case SWFACTION_MULTIPLY: op = (isShort?"*":" * "); break; case SWFACTION_DIVIDE: op = (isShort?"/":" / "); break; case SWFACTION_MODULO: op = (isShort?"%":" % "); break; case SWFACTION_BITWISEOR: op = (isShort?"|":" | "); break; case SWFACTION_BITWISEAND: op = (isShort?"&":" & "); break; case SWFACTION_BITWISEXOR: op = (isShort?"^":" ^ "); break; case SWFACTION_SHIFTLEFT: op = (isShort?"<<":" << "); break; case SWFACTION_SHIFTRIGHT: op = (isShort?">>":" >> "); break; case SWFACTION_SHIFTRIGHT2: op = (isShort?">>>":" >>> "); break; case SWFACTION_NEWEQUAL: case SWFACTION_EQUAL: op = " == "; break; case SWFACTION_LOGICALAND: op = " && "; break; case SWFACTION_LOGICALOR: op = " || "; break; case SWFACTION_STRINGEQ: op = " eq "; break; case SWFACTION_STRINGCONCAT: op = " & "; break; case SWFACTION_STRINGCOMPARE: op = " <=> "; break; default: op = " ??? "; break; } if(t->action == SWFACTION_MULTIPLY)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -