X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfaction.c;h=6b59ca0046c4fc0008ae687a580856e51e3299df;hb=2f05025d37446c2b81801a00e6786ee891d7e688;hp=652fd6d2cd8809d3580230e8e9f903a4ff432e09;hpb=b3393ea6b04c1033e12b1738b5e2e930213e1ded;p=swftools.git diff --git a/lib/modules/swfaction.c b/lib/modules/swfaction.c index 652fd6d..6b59ca0 100644 --- a/lib/modules/swfaction.c +++ b/lib/modules/swfaction.c @@ -13,6 +13,8 @@ #include "../rfxswf.h" +#define MAX_LOOKUP 1024 // make cross references in dumps + struct Action { int version; @@ -33,7 +35,7 @@ m: method (byte) swf_GetUrl2:(0=none, 1=get, 2=post)/GotoFrame2:(1=play) b: branch (word) (number of bytes) p (push): type(byte), type=0:string, type=1:double {: define function (name (string), num (word), params (num strings), codesize (word) -o: object (string) +o: codesize (word) object (string) r: register (byte) */ {3,"End", 0x00, ""}, @@ -124,7 +126,9 @@ r: register (byte) {5,"ToString", 0x4b,""}, //? {5,"TypeOf", 0x44,""}, {5,"Add2", 0x47,""}, -{5,"Less2", 0x48,""} +{5,"Less2", 0x48,""}, +{5/*6?*/,"Less3?", 0x67,""}, +{5/*6?*/,"GetMembers?", 0x55,""} }; static int definedactions = sizeof(actions)/sizeof(struct Action); @@ -189,7 +193,7 @@ void swf_ActionSet(TAG*tag, ActionTAG*action) } } -int OpAdvance(char c, char*data) +int OpAdvance(char c, U8*data) { switch (c) { @@ -211,6 +215,8 @@ int OpAdvance(char c, char*data) return 1; case 'b': return 2; + case 'r': + return 1; case 'p': { U8 type = *data++; if(type == 0) { @@ -229,100 +235,209 @@ int OpAdvance(char c, char*data) return 1+4; //int } else if (type == 8) { return 1+1; //lookup - } + } else return 1; break; } + case 'o': { + return 2; + } + case '{': { + U16 num; + U16 codesize; + U8* odata = data; + int t; + while(*data++); //name + num = (*data++)*256; //num + num += (*data++); + for(t=0;tlen + 1 + ((atag)->op&0x80?2:0)) +#define MAX_LEVELS 16 +/* TODO: * this should be in swfdump.c */ void swf_DumpActions(ActionTAG*atag, char*prefix) { int t; U8*data; char* cp; - if(!prefix) - prefix=""; + int entry = 0; + char spaces[MAX_LEVELS*4+1]; + struct { + char*text; + int count; + } counter[MAX_LEVELS]; + int countpos = 0; +#ifdef MAX_LOOKUP + char * lookup[MAX_LOOKUP]; + memset(lookup,0x00,sizeof(lookup)); +#endif + memset(spaces, 32, sizeof(spaces)); + spaces[sizeof(spaces)-1] = 0; + + if (!prefix) + prefix=""; + while(atag) { + char*indent = &spaces[sizeof(spaces)-1-countpos*4]; U8 poollen = 0; for(t=0;top) break; if(t==definedactions) { - printf("%s (%5d bytes) action: %02x\n", prefix, atag->len, atag->op); - atag = atag->next; - continue; + printf("%s (%5d bytes) action:%s unknown[%02x]", prefix, atag->len, indent, atag->op); + } else { + printf("%s (%5d bytes) action:%s %s", prefix, atag->len, indent, actions[t].name); } - printf("%s (%5d bytes) action: %s", prefix, atag->len, actions[t].name); - cp = actions[t].flags; data = atag->data; - if(atag->len) //TODO: check for consistency: should we have a length? - while(*cp) + if(atag->len && t!=definedactions) //TODO: check for consistency: should we have a length? { - switch(*cp) - { - case 'f': { - printf(" %d", *(U16*)data); //FIXME: le/be - } break; - case 'u': { - printf(" URL:\"%s\"", data); - } break; - case 't': { - printf(" Target:\"%s\"", data); - } break; - case 'l': { - printf(" Label:\"%s\"", data); - } break; - case 'c': { - printf(" String:\"%s\"", data); - } break; - case 'C': { - poollen = *data; - printf("(%d entries)", poollen); - } break; - case 's': { - printf(" +%d", *data); - } break; - case 'm': { - //m: method (byte) url:(0=none, 1=get, 2=datat)/gf2:(1=play) - printf(" %d", *data); - } break; - case 'b': { - printf(" %d", *(U16*)data); - } break; - case 'p': { - U8 type = *data; - char*value = data+1; - if(type == 0) { - printf(" String:\"%s\"", value); - } else if (type == 1) { - printf(" Float:%f", *(float*)value); - } else if (type == 2) { - printf(" NULL"); - } else if (type == 4) { - printf(" register:%d", *value); - } else if (type == 5) { - printf(" bool:%s", *value?"true":"false"); - } else if (type == 6) { - printf(" float:%f", *(double*)value); - } else if (type == 7) { - printf(" int:%d", *(int*)value); - } else if (type == 8) { - printf(" Lookup:%d", *value); - } else { - printf(" UNKNOWN[%02x]",type); - } - } break; - } - data += OpAdvance(*cp, data); - if((*cp!='c' || !poollen) && - (*cp!='p' || !(data<&atag->data[atag->len]))) - cp++; - if(poollen) - poollen--; + cp = actions[t].flags; + while(*cp) + { + switch(*cp) + { + case 'f': { //frame + printf(" %d", data[0]+256*data[1]); + } break; + case 'u': { + printf(" URL:\"%s\"", data); + } break; + case 't': { + printf(" Target:\"%s\"", data); + } break; + case 'l': { + printf(" Label:\"%s\"", data); + } break; + case 'c': { + printf(" String:\"%s\"", data); +#ifdef MAX_LOOKUP + if (entry=15) { + printf("Error: nested too deep\n"); + continue; + } + counter[countpos].text = "}"; + counter[countpos].count = codesize + ATAG_FULLLENGTH(atag); + countpos++; + } break; + case 'o': { + int t; + U16 codesize = data[0]+256*data[1]; + printf(" codesize:%d ", codesize); + + /* the following tries to find the "string" + the flash documentation speaks of- I've + never actually seen one yet. -mk */ + for(t=2;tlen;t++) + printf("[%02x]", atag->data[t]); + + printf("\n%s %s{", prefix, indent); + if(countpos>=15) { + printf("Error: nested too deep\n"); + continue; + } + counter[countpos].text = "}"; + counter[countpos].count = codesize + ATAG_FULLLENGTH(atag); + countpos++; + } break; + case 'b': { + printf(" %d", data[0]+256*(signed char)data[1]); + } break; + case 'r': { + printf(" %d", data[0]); + } break; + case 'p': { + U8 type = *data; + unsigned char*value = data+1; + if(type == 0) { + printf(" String:\"%s\"", value); + } else if (type == 1) { + U32 f = value[0]+(value[1]<<8)+ + (value[2]<<16)+(value[3]<<24); + printf(" Float:%f", *(float*)&f); + } else if (type == 2) { + printf(" NULL"); + } else if (type == 4) { + printf(" register:%d", *value); + } else if (type == 5) { + printf(" bool:%s", *value?"true":"false"); + } else if (type == 6) { + U8 a[8]; + int t; + memcpy(&a[4],value,4); + memcpy(a,&value[4],4); +#ifdef WORDS_BIGENDIAN + for(t=0;t<4;t++) { + U8 tmp = a[t]; + a[t]=a[7-t]; + a[7-t] = tmp; + } +#endif + printf(" double:%f", *(double*)a); + } else if (type == 7) { + printf(" int:%d", value[0]+(value[1]<<8)+ + (value[2]<<16)+(value[3]<<24)); + } else if (type == 8) { + printf(" Lookup:%d", *value); +#ifdef MAX_LOOKUP + if (lookup[*value]) + printf(" (\"%s\")",lookup[*value]); +#endif + } else { + printf(" UNKNOWN[%02x]",type); + } + } break; + } + data += OpAdvance(*cp, data); + if((*cp!='c' || !poollen) && + (*cp!='p' || !(data<&atag->data[atag->len]))) + cp++; + if(poollen) + poollen--; + } } if(data < atag->data + atag->len) @@ -339,8 +454,30 @@ void swf_DumpActions(ActionTAG*atag, char*prefix) printf("\")"); } printf("\n"); + + for(t=0;tnext; } + +#ifdef MAX_LOOKUP + for (t=0;top == ACTION_IF || a1->op == ACTION_JUMP) { - *(U16*)(a1->data) = len; + *(U16*)(a1->data) = SWAP16(len); } else if(a1->op == ACTION_WAITFORFRAME) { @@ -715,17 +852,17 @@ void action_Call() {swf_AddActionTAG(ACTION_CALL, 0, 0);} void action_End() {swf_AddActionTAG(ACTION_END, 0, 0);} void action_GotoFrame(U16 frame) { - *(U16*)currentatag->tmp = frame; + *(U16*)currentatag->tmp = SWAP16(frame); swf_AddActionTAG(ACTION_GOTOFRAME, (U8*)currentatag->tmp, 2); } void action_Jump(U16 branch) { - *(U16*)currentatag->tmp = branch; + *(U16*)currentatag->tmp = SWAP16(branch); swf_AddActionTAG(ACTION_JUMP, (U8*)currentatag->tmp, 2); } void action_If(U16 branch) { - *(U16*)currentatag->tmp = branch; + *(U16*)currentatag->tmp = SWAP16(branch); swf_AddActionTAG(ACTION_IF, (U8*)currentatag->tmp, 2); } void action_StoreRegister(U8 reg) @@ -750,7 +887,7 @@ void action_WaitForFrame2(U8 skip) } void action_WaitForFrame(U16 frame, U8 skip) { - *(U16*)currentatag->tmp = frame; + *(U16*)currentatag->tmp = SWAP16(frame); *(U8*)¤tatag->tmp[2] = skip; swf_AddActionTAG(ACTION_WAITFORFRAME, (U8*)currentatag->tmp, 3); } @@ -793,21 +930,39 @@ void action_PushString(char*str) void action_PushFloat(float f) { char*ptr = (char*)malloc(5); + U32 fd = *(U32*)&f; ptr[0] = 1; //float - *(float*)&ptr[1] = f; + ptr[1] = fd; + ptr[2] = fd>>8; + ptr[3] = fd>>16; + ptr[4] = fd>>24; swf_AddActionTAG(ACTION_PUSH, (U8*)ptr, 5); } void action_PushDouble(double d) { char*ptr = (char*)malloc(9); + U8*dd = (U8*)&d; ptr[0] = 6; //double - *(double*)&ptr[1] = d; +#ifdef WORDS_BIGENDIAN + ptr[1] = dd[7];ptr[2] = dd[6]; + ptr[3] = dd[5];ptr[4] = dd[4]; + ptr[5] = dd[3];ptr[6] = dd[2]; + ptr[7] = dd[1];ptr[8] = dd[0]; +#else + ptr[1] = dd[0];ptr[2] = dd[1]; + ptr[3] = dd[2];ptr[4] = dd[3]; + ptr[5] = dd[4];ptr[6] = dd[5]; + ptr[7] = dd[6];ptr[8] = dd[7]; +#endif swf_AddActionTAG(ACTION_PUSH, (U8*)ptr, 9); } void action_PushInt(int i) { *(U8*)currentatag->tmp = 7; //int - *(U32*)¤tatag->tmp[1] = i; + currentatag->tmp[1] = i; + currentatag->tmp[2] = i>>8; + currentatag->tmp[3] = i>>16; + currentatag->tmp[4] = i>>24; swf_AddActionTAG(ACTION_PUSH, (U8*)currentatag->tmp, 5); } void action_GotoLabel(char* label)