📄 decomp_action.c
字号:
case SWFACTION_NEXTFRAME: case SWFACTION_PREVFRAME: case SWFACTION_PLAY: case SWFACTION_STOP: case SWFACTION_TOGGLEQUALITY: case SWFACTION_STOPSOUNDS: return newTree(NULL, type, NULL,0); /*get variable取栈顶变量的值,需从栈中弹出栈顶节点,如果栈顶节点 */ /*包含数据类型不是树则简单的用get variable构成新树,否则:用eval action构建新树*/ /*如果对一个表达式树节点进行get variable操作则判断为eval()函数调用*/ case SWFACTION_GETVARIABLE: { thistmp=pop(); if(thistmp->type=='t') { return(newTree(thistmp,SWFACTION_EVAL,NULL,0)); } else return(newTree(thistmp,type,NULL,0)); } /*以下action需要一个数据元素参与操作*/ 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_REMOVECLIP: case SWFACTION_TRACE: case SWFACTION_SETTARGETEXPRESSION: case SWFACTION_CALLFRAME: return newTree(pop(), type, NULL,0); /*双目操作,需要从栈中弹出2个节点*/ 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_STRINGCONCAT: case SWFACTION_STRINGCOMPARE: { Stack right = pop(); Stack left = pop(); return newTree(left, type, right,0); } /*set variable操作将一个节点的值赋予另一个变量节点,所以要pop 2各节点*/ /*但是有一点需要指出,当set variable弹出的right节点为一个DECREMENT或*/ /*INCREMENT操作时,需要继续判断POP两个节点后的栈顶节点否是对set variable同一个变量 */ /*进行GET VARIABLE操作的树节点,如果是则为a++形式而非++a的形式*/ /*此时需要继续pop一个节点否则会打乱while条件判断 */ case SWFACTION_SETVARIABLE: { int i; Stack right = pop(); Stack left = pop(); Stack temp=NULL; if(right->type == 't' && right->data.tree->action == SWFACTION_SETREGISTER) { i=(int)right->data.tree->left; if(i<0||i>=reg_current->len) err_debug(ERR_REGISTER,"Wrong register number %d",i); if(!reg_current->reglist) err_debug(ERR_REGISTER,"Wrong register structure!"); reg_current->reglist[i] = newTree(left, type, right->data.tree->right,0); destroy(right); return NULL; } else if(right->type=='t' && (right->data.tree->action == SWFACTION_DECREMENT || right->data.tree->action == SWFACTION_INCREMENT)&& right->data.tree->left->type=='t'&& right->data.tree->left->data.tree->action==SWFACTION_GETVARIABLE&& right->data.tree->left->data.tree->left->type=='s'&&stack!=NULL&& stack->type=='t'&& stack->data.tree->action==SWFACTION_GETVARIABLE&& stack->data.tree->left->type=='s' && (stack->data.tree->left->data.string==right->data.tree->left->data.tree->left->data.string|| my_strcmp(stack->data.tree->left->data.string,right->data.tree->left->data.tree->left->data.string)==0)) { temp=pop(); right->data.tree->right=temp; right->offset=MIN(temp->offset,right->offset); } return newTree(left, type, right,0); } /*get property操作,没什么特殊的,因为该操作要求property是一个引索号*/ /*所以当栈顶节点包含的是字符串时,要用atio进行变换*/ 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,0); } /*减法操作*/ 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,0); } /*set property操作,pop值,pop property,pop target*/ /*将target和property构成树节点,再将树节点和value构成树节点*/ 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; } set_stack(target,IS_TARGET,VALUE_UNDEF); set_stack(property,IS_PROPERTY,value->t.value_type); return newTree(newTree(target, type, property,0), SWFACTION_SETVARIABLE, value,0); } /*以下action的pop操作顺序及作用请参阅<<SWF format reference>>*/ /*部分内容来自于flasm的pop顺序方式和gameswf的*/ case SWFACTION_MBSUBSTRING: case SWFACTION_SUBSTRING: { Stack s3 = pop(); Stack s2 = pop(); Stack s1 = pop(); return newTree(s1, type, newTree(s2, type, s3,0),0); } case SWFACTION_DUPLICATECLIP: { Stack level = pop(); Stack target = pop(); Stack source = pop(); Stack arg=NULL; if(level->type == 'i' && level->data.inum >= DUPCLIP_NUMBER) { arg = level; arg->data.inum -= DUPCLIP_NUMBER; } else { if(level->type != 't' || (level->data.tree->action != SWFACTION_ADD && level->data.tree->action != SWFACTION_NEWADD)) err_debug(ERR_PCODE,"magic number 0x4000 not found in duplicateClip target level!"); if(level->data.tree->left->type == 'i' && level->data.tree->left->data.inum == DUPCLIP_NUMBER) { arg = level->data.tree->right; level->data.tree->right = NULL; } else if(level->data.tree->right->type == 'i' && level->data.tree->right->data.inum == DUPCLIP_NUMBER) { arg = level->data.tree->left; level->data.tree->left = NULL; } else err_debug(ERR_PCODE,"magic number 0x4000 not found in duplicateClip target level!"); destroy(level); } return newTree(source, type, newTree(target, type, arg,0),0); } case SWFACTION_STARTDRAGMOVIE: { Stack target = pop(); Stack lockmouse = pop(); Stack constraint = pop(); if(constraint->type == 't') err_debug(ERR_OPERATE,"Sorry, decompiler can't deal with conditional constraint in dragMovie!"); if(intVal(constraint) == 0) return newTree(constraint, type, newTree(lockmouse, type, target,0),0); else { Stack p4 = pop(); Stack p3 = pop(); Stack p2 = pop(); Stack p1 = pop(); return newTree(newTree(newTree(p1, type, p2,0), type, newTree(p3, type, p4,0),0), type, newTree(lockmouse, type, target,0),0); } } /*压入数据操作,在该action 的pcode之后是表示压入数据类型的数字*/ case SWFACTION_PUSHDATA: { Stack s = NULL; int end = ptr_offset + length; int type; uint8_t n; int off = ptr_offset - 3; while(ptr_offset < end) { if(s != NULL) push(s); switch(type = My_readUInt8()) { /*压入普通字符串,将构建一个新的string数据节点*/ case 0: s = newString(My_readString()); break; /*压入属性引索,将构建一个属性引索节点*/ case 1: My_readUInt16(); s = newProperty(getSetProperty(My_readUInt16())); break; case 2: { /*压入null,将构建一个新的string节点,该节点的指向常量"NULL"*/ s = newString(null_str); set_stack(s,IS_CONSTANT,VALUE_NULL); break; } case 3: { /*压入未定义*/ s = newString(undef_str); set_stack(s,IS_CONSTANT,VALUE_UNDEF); break; } break; case 4: { /*压入的值在寄存器中*/ /*读寄存器引索*/ n=My_readUInt8(); /*如果当前环境中的寄存器数组为NULL,说明有错误发生*/ /*常态下,reg_current指向global的4个寄存器数组*/ /*当递归处理function2时将reg_current指向私有的256个寄存器*/ if(reg_current==NULL) err_debug(ERR_REGISTER,"PUSH:Wrong register num or reg_array pointer"); if(n>=reg_current->len||reg_current->reglist[n]==NULL) err_debug(ERR_REGISTER,"PUSH:Wrong register num or reg_array pointer"); s=reg_current->reglist[n]; s->offset = reg_current->reglist[n]->offset; break; } case 5: { /*压入一个bool值,将构建一个新的string节点,指针值指向常量"false"或"true"*/ s = newString((My_readUInt8() == 0) ? false_str : true_str); set_stack(s,IS_CONSTANT,VALUE_BOOL); break; } /*压入一个double数据,构建一个double类型的栈节点*/ case 6: s = newDouble(My_readDouble()); break; /*压入一个integer数据,构建一个integer类型的栈节点*/ case 7: s = newInteger(My_readSInt32()); break; case 8: { /*压入的是字符串,但是常量池中的引索,此时取常量池中的字符串*/ /*并同时取该字符串(变量名)在常量池中维护的属性和取值类型*/ uint8_t dict_tmp=My_readUInt8(); s = newString(dictionary[dict_tmp].ptr); s->t=dictionary[dict_tmp].t; s->index=dict_tmp; break; } /*同上,只不过是16位常量池引索,当常量池引索大于256时使用*/ case 9: { uint16_t dict_tmp=My_readUInt16(); s = newString(dictionary[dict_tmp].ptr); s->t=dictionary[dict_tmp].t; s->index=dict_tmp; break; } default: { err_debug(ERR_PCODE,"Unknown data type %x", type); } } if(s->offset == -1) s->offset = off; } return s; } case SWFACTION_GOTOFRAME: { return(newTreeBase((Stack)((int)My_readUInt16()), type, NULL,LEFT_CANNOT_FREE)); } case SWFACTION_GETURL: { char *url = My_readString(); char *target = My_readString(); return (newTreeBase((Stack)url, type, (Stack)target,LEFT_CAN_FREE|RIGHT_CAN_FREE)); } case SWFACTION_GETURL2: { Stack target = pop(); Stack url = pop(); Stack s = newTree(url, type, target,0); Stack t = newTreeBase((Stack)((int)My_readUInt8()), type, s,LEFT_CANNOT_FREE); t->offset = s->offset; return t; } case SWFACTION_WAITFORFRAMEEXPRESSION: { return(newTreeBase((Stack)((int)My_readUInt8()), type, NULL,LEFT_CANNOT_FREE)); } case SWFACTION_GOTOEXPRESSION: { Stack s = pop(); Stack t = newTreeBase(s, type, (Stack)((int)My_readUInt8()),RIGHT_CANNOT_FREE); t->offset = s->offset; return t; } case SWFACTION_SETTARGET: case SWFACTION_GOTOLABEL: { return(newTreeBase((Stack)My_readString(), type, NULL,LEFT_CAN_FREE)); } case SWFACTION_BRANCHIFTRUE: { Stack s = pop(), t; int offset = My_readSInt16(); Action action; if(s->type == 't' && ((action = s->data.tree->action) == SWFACTION_DUP || /* it's an or */ ((action = s->data.tree->action) == SWFACTION_LOGICALNOT && /* and */ s->data.tree->left->type == 't' && s->data.tree->left->data.tree-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -