1 /****************************************************************************
2 *
3 * Copyright (C) 2005-2006 "Stuart R. Anderson" <anderson@netsweng.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 ****************************************************************************/
20
21 #include "action.h"
22 #include "parser.h"
23
24 extern int verbose;
25
26 typedef void (*outputfunc) (SWF_ACTION *act);
27
28 static struct SWF_ACTIONCONSTANTPOOL *pool = NULL;
29
30 struct SWFActionName
31 {
32 Action type;
33 char *name;
34 outputfunc func;
35 };
36
37 #define OUT_BEGIN(block) \
38 struct block *sact = (struct block *)act;
39
40 static int indent = 1;
41
42 #define INDENT {int idt;for(idt=0;idt<indent;idt++)printf(" ");}
43
44 void
outputSWFACTION_CONSTANTPOOL(SWF_ACTION * act)45 outputSWFACTION_CONSTANTPOOL (SWF_ACTION *act)
46 {
47 int i;
48 OUT_BEGIN(SWF_ACTIONCONSTANTPOOL);
49
50 if( verbose ) {
51 INDENT;
52 printf ("Length: %d\n", sact->Length);
53 }
54 pool=sact;
55 for(i=0;i<sact->Count;i++)
56 {
57 INDENT;
58 printf (" [%3.3d] %s\n", i, sact->ConstantPool[i] );
59 }
60 }
61
62 void
outputSWFACTION_STOREREGISTER(SWF_ACTION * act)63 outputSWFACTION_STOREREGISTER (SWF_ACTION *act)
64 {
65 OUT_BEGIN(SWF_ACTIONSTOREREGISTER);
66
67 if( verbose ) {
68 INDENT;
69 printf (" Length: %d\n", sact->Length);
70 }
71 INDENT;
72 printf (" Register: %d\n", sact->Register);
73 }
74
75 void
outputSWFACTION_IF(SWF_ACTION * act)76 outputSWFACTION_IF (SWF_ACTION *act)
77 {
78 int i;
79 OUT_BEGIN(SWF_ACTIONIF);
80
81 if( verbose ) {
82 INDENT;
83 printf (" Length: %d\n", sact->Length);
84 }
85 INDENT;
86 printf (" BranchOffset: %d, TargetOffset: %lu\n", sact->BranchOffset,
87 sact->Offset + sact->Length + sact->BranchOffset + 3);
88 INDENT;
89 printf (" %d Action\n", sact->numActions);
90 if( verbose ) {
91 INDENT;
92 printf (" ****IF-begin\n");
93 }
94 for(i=0;i<sact->numActions;i++)
95 {
96 outputSWF_ACTION (i,&(sact->Actions[i]));
97 }
98 if( verbose ) {
99 INDENT;
100 printf (" ****IF-end\n");
101 }
102 }
103
104 void
outputSWFACTION_JUMP(SWF_ACTION * act)105 outputSWFACTION_JUMP (SWF_ACTION *act)
106 {
107 OUT_BEGIN(SWF_ACTIONJUMP);
108
109 if( verbose ) {
110 INDENT;
111 printf (" Length: %d\n", sact->Length);
112 }
113 INDENT;
114 printf (" BranchOffset: %d, TargetOffset: %lu\n", sact->BranchOffset,
115 sact->Offset + sact->Length + sact->BranchOffset + 3);
116 }
117
118 void
outputSWFACTION_WAITFORFRAME(SWF_ACTION * act)119 outputSWFACTION_WAITFORFRAME (SWF_ACTION *act)
120 {
121 OUT_BEGIN(SWF_ACTIONWAITFORFRAME);
122
123 if( verbose ) {
124 INDENT;
125 printf (" Length: %d\n", sact->Length);
126 }
127 INDENT;
128 printf (" Frame: %d\n", sact->Frame);
129 INDENT;
130 printf (" SkipCount: %d\n", sact->SkipCount);
131 }
132
133 void
outputSWFACTION_SETTARGET(SWF_ACTION * act)134 outputSWFACTION_SETTARGET (SWF_ACTION *act)
135 {
136 OUT_BEGIN(SWF_ACTIONSETTARGET);
137
138 if( verbose ) {
139 INDENT;
140 printf (" Length: %d\n", sact->Length);
141 }
142 INDENT;
143 printf (" TargetName: %s\n", sact->TargetName);
144 }
145
146 void
outputSWFACTION_WITH(SWF_ACTION * act)147 outputSWFACTION_WITH (SWF_ACTION *act)
148 {
149 int i;
150 OUT_BEGIN(SWF_ACTIONWITH);
151
152 if( verbose ) {
153 INDENT;
154 printf (" Length: %d\n", sact->Length);
155 }
156 INDENT;
157 printf (" Size: %d\n", sact->Size);
158 if( verbose )
159 INDENT;
160 printf (" ****WITH-begin\n");
161 indent++;
162 for(i=0;i<sact->numActions;i++)
163 {
164 outputSWF_ACTION (i,&(sact->Actions[i]));
165 }
166 if( verbose )
167 INDENT;
168 printf (" ****WITH-end\n");
169 indent--;
170 }
171
172 void
outputSWFACTION_DEFINEFUNCTION(SWF_ACTION * act)173 outputSWFACTION_DEFINEFUNCTION (SWF_ACTION *act)
174 {
175 int i;
176 OUT_BEGIN(SWF_ACTIONDEFINEFUNCTION);
177
178 if( verbose ) {
179 INDENT;
180 printf (" Length: %d\n", sact->Length);
181 }
182 INDENT;
183 printf (" Name: %s\n", sact->FunctionName);
184 INDENT;
185 printf (" NumParams: %d\n", sact->NumParams);
186 for(i=0;i<sact->NumParams;i++)
187 {
188 INDENT;
189 printf(" [%2.2d] %s\n", i,
190 sact->Params[i] );
191 }
192 INDENT;
193 printf (" CodeSize: %d\n", sact->CodeSize);
194 INDENT;
195 printf (" %d Action\n", sact->numActions);
196 if( verbose ) {
197 INDENT;
198 printf (" ****FUN-begin\n");
199 }
200 for(i=0;i<sact->numActions;i++)
201 {
202 outputSWF_ACTION (i,&(sact->Actions[i]));
203 }
204 if( verbose ) {
205 INDENT;
206 printf (" ****FUN-end\n");
207 }
208 }
209
210 void
outputSWFACTION_DEFINEFUNCTION2(SWF_ACTION * act)211 outputSWFACTION_DEFINEFUNCTION2 (SWF_ACTION *act)
212 {
213 int i, registerCount = 1;
214 OUT_BEGIN(SWF_ACTIONDEFINEFUNCTION2);
215
216 if( verbose ) {
217 INDENT;
218 printf (" Length: %d\n", sact->Length);
219 }
220 INDENT;
221 printf (" Name: %s\n", sact->FunctionName);
222 INDENT;
223 printf (" RegisterCount: %d\n", sact->RegisterCount);
224 INDENT;
225 printf (" Preloaded Registers:\n");
226 if(sact->PreloadThisFlag)
227 printf(" Register %i: this\n", registerCount++);
228 if(sact->PreloadArgumentsFlag)
229 printf(" Register %i: arguments\n", registerCount++);
230 if(sact->PreloadSuperFlag)
231 printf(" Register %i: super\n", registerCount++);
232 if(sact->PreloadRootFlag)
233 printf(" Register %i: _root\n", registerCount++);
234 if(sact->PreloadParentFlag)
235 printf(" Register %i: _parent\n", registerCount++);
236 if(sact->PreloadGlobalFlag)
237 printf(" Register %i: _global\n", registerCount++);
238 INDENT;
239 printf (" NumParams: %d\n", sact->NumParams);
240 for(i=0;i<sact->NumParams;i++)
241 {
242 INDENT;
243 printf(" [%2.2d] %d %s\n", i,
244 sact->Params[i].Register,
245 sact->Params[i].ParamName );
246 }
247 INDENT;
248 printf (" Flags: \n");
249 INDENT;
250 printf (" Suppress: super %d, arguments %d, this %d\n",
251 sact->SuppressSuperFlag, sact->SuppressArgumentsFlag,
252 sact->SuppressThisFlag);
253 INDENT;
254 printf (" CodeSize: %d\n", sact->CodeSize);
255 INDENT;
256 printf (" %d Action\n", sact->numActions);
257 if( verbose ) {
258 INDENT;
259 printf (" ****FUN2-begin\n");
260 }
261 for(i=0;i<sact->numActions;i++)
262 {
263 outputSWF_ACTION (i,&(sact->Actions[i]));
264 }
265 if( verbose ) {
266 INDENT;
267 printf (" ****FUN2-end\n");
268 }
269 }
270
271 const char*
getConstant(unsigned int n)272 getConstant(unsigned int n)
273 {
274 if ( ! pool || n >= pool->Count ) return NULL;
275 return pool->ConstantPool[n];
276 }
277
278 void
outputSWFACTION_PUSHPARAM(struct SWF_ACTIONPUSHPARAM * act)279 outputSWFACTION_PUSHPARAM (struct SWF_ACTIONPUSHPARAM *act)
280 {
281
282 switch( act->Type )
283 {
284 case 0: /* STRING */
285 printf (" String: '%s'\n", act->p.String);
286 break;
287 case 1: /* FLOAT */
288 printf (" Float: %f\n", act->p.Float);
289 break;
290 case 2: /* NULL */
291 printf (" NULL: \n" );
292 break;
293 case 3: /* Undefined */
294 printf (" undefined\n" );
295 break;
296 case 4: /* Register */
297 printf (" Register: %d\n", (int)act->p.RegisterNumber);
298 break;
299 case 5: /* BOOLEAN */
300 printf (" Boolean: %d\n", act->p.Boolean);
301 break;
302 case 6: /* DOUBLE */
303 printf (" Double: %g\n", act->p.Double);
304 break;
305 case 7: /* INTEGER */
306 printf (" Integer: %ld\n", act->p.Integer);
307 break;
308 case 8: /* CONSTANT8 */
309 {
310 const char* v = getConstant(act->p.Constant8);
311 printf (" Constant: %d", act->p.Constant8);
312 if ( v ) printf (" \"%s\"", v);
313 putchar('\n');
314 break;
315 }
316 case 9: /* CONSTANT16 */
317 {
318 const char* v = getConstant(act->p.Constant16);
319 printf (" Constant: %d", act->p.Constant16);
320 if ( v ) printf (" \"%s\"", v);
321 putchar('\n');
322 break;
323 }
324 default:
325 printf (" Unknown type: %d\n", act->Type);
326 break;
327 }
328 }
329
330 void
outputSWFACTION_PUSH(SWF_ACTION * act)331 outputSWFACTION_PUSH (SWF_ACTION *act)
332 {
333 int i;
334 OUT_BEGIN(SWF_ACTIONPUSH);
335
336 if( verbose )
337 printf (" Length: %d\n", sact->Length);
338 for(i=0;i<sact->NumParam;i++)
339 {
340 INDENT;
341 printf (" [%3.3d] ", i );
342 outputSWFACTION_PUSHPARAM(&(sact->Params[i]));
343 }
344 }
345
346 void
outputSWFACTION_GETURL(SWF_ACTION * act)347 outputSWFACTION_GETURL (SWF_ACTION *act)
348 {
349 OUT_BEGIN(SWF_ACTIONGETURL);
350 printf(" UrlString: %s\n", sact->UrlString);
351 printf(" TargetString: %s\n", sact->TargetString);
352 }
353
354 void
outputSWFACTION_GETURL2(SWF_ACTION * act)355 outputSWFACTION_GETURL2 (SWF_ACTION *act)
356 {
357 OUT_BEGIN(SWF_ACTIONGETURL2);
358
359 if( verbose )
360 printf (" Length: %d\n", sact->Length);
361 switch( sact->f.FlagBits.SendVarsMethod )
362 {
363 case 0:
364 printf (" Method: none\n");
365 break;
366 case 1:
367 printf (" Method: GET\n");
368 break;
369 case 2:
370 printf (" Method: POST\n");
371 break;
372 }
373 switch( sact->f.FlagBits.LoadTargetFlag )
374 {
375 case 0:
376 printf (" Target: Window\n");
377 break;
378 case 1:
379 printf (" Target: Sprite\n");
380 break;
381 }
382 switch( sact->f.FlagBits.LoadVariableFlag )
383 {
384 case 0:
385 printf (" LoadVars: No\n");
386 break;
387 case 1:
388 printf (" LoadVars: Yes\n");
389 break;
390 }
391 printf (" Reserved bits: %x\n", sact->f.FlagBits.Reserved);
392 }
393
394 void
outputSWFACTION_GOTOFRAME(SWF_ACTION * act)395 outputSWFACTION_GOTOFRAME (SWF_ACTION *act)
396 {
397 OUT_BEGIN(SWF_ACTIONGOTOFRAME);
398
399 if( verbose ) {
400 INDENT;
401 printf (" Length: %d\n", sact->Length);
402 }
403
404 INDENT;
405 printf (" Frame: %d\n", sact->Frame);
406 }
407
408 void
outputSWFACTION_GOTOFRAME2(SWF_ACTION * act)409 outputSWFACTION_GOTOFRAME2 (SWF_ACTION *act)
410 {
411 OUT_BEGIN(SWF_ACTIONGOTOFRAME2);
412
413 if( verbose )
414 printf (" Length: %d\n", sact->Length);
415
416 printf (" Reserved bits: %x\n", sact->f.FlagBits.Reserved);
417 printf (" Scene bias flag: %x\n", sact->f.FlagBits.SceneBiasFlag);
418 printf (" Play flag : %x\n", sact->f.FlagBits.PlayFlag);
419 if(sact->f.FlagBits.SceneBiasFlag)
420 printf (" Scene bias : %u\n", sact->SceneBias);
421 }
422
423 void
outputSWFACTION_TRY(SWF_ACTION * act)424 outputSWFACTION_TRY (SWF_ACTION *act)
425 {
426 int i;
427 OUT_BEGIN(SWF_ACTIONTRY);
428
429 if( verbose )
430 printf (" Length: %d\n", sact->Length);
431 printf(" Offset %i\n",(int) sact->Offset);
432 printf(" CatchInRegisterFlag %d, FinallyBlockFlag %d, CatchBlockFlag %d\n",
433 sact->CatchInRegisterFlag, sact->FinallyBlockFlag, sact->CatchBlockFlag);
434 printf(" TrySize %d\n", sact->TrySize);
435 printf(" CatchSize %d\n", sact->CatchSize);
436 printf(" FinallySize %d\n", sact->FinallySize);
437 if(sact->CatchInRegisterFlag)
438 printf(" CatchRegister %i\n", sact->CatchRegister);
439 else
440 printf(" CatchName %s\n", sact->CatchName);
441
442 printf(" Try Actions: %i\n", sact->numTryActs);
443 for(i = 0; i < sact->numTryActs; i++)
444 {
445 outputSWF_ACTION(4, sact->TryActs + i);
446 }
447 printf("\n");
448
449 printf(" Catch Actions: %i\n", sact->numCatchActs);
450 for(i = 0; i < sact->numCatchActs; i++)
451 {
452 outputSWF_ACTION(4, sact->CatchActs + i);
453 }
454 printf("\n");
455
456 printf(" Finally Actions: %i\n", sact->numFinallyActs);
457 for(i = 0; i < sact->numFinallyActs; i++)
458 {
459 outputSWF_ACTION(4, sact->FinallyActs + i);
460 }
461 printf(" ## TRY END ##\n\n");
462 }
463
464 #define ActionType( action ) \
465 { action, #action, NULL }
466
467 #define ActionTypeLong( action ) \
468 { action, #action, output##action }
469
470 static struct SWFActionName actions[] = {
471 ActionType (SWFACTION_END),
472 /* v3 actions */
473 /* Simple Actions */
474 ActionType (SWFACTION_NEXTFRAME),
475 ActionType (SWFACTION_PLAY),
476 ActionType (SWFACTION_STOP),
477 ActionType (SWFACTION_TOGGLEQUALITY),
478 ActionType (SWFACTION_STOPSOUNDS),
479 /* Actions with additional Data */
480 ActionTypeLong (SWFACTION_GOTOFRAME),
481 ActionTypeLong (SWFACTION_GETURL),
482 ActionTypeLong (SWFACTION_WAITFORFRAME),
483 ActionTypeLong (SWFACTION_SETTARGET),
484 ActionType (SWFACTION_GOTOLABEL),
485 /* v4 actions */
486 ActionTypeLong (SWFACTION_PUSH),
487 ActionType (SWFACTION_POP),
488 ActionType (SWFACTION_ADD),
489 ActionType (SWFACTION_SUBTRACT),
490 ActionType (SWFACTION_MULTIPLY),
491 ActionType (SWFACTION_DIVIDE),
492 ActionType (SWFACTION_EQUAL),
493 ActionType (SWFACTION_LESSTHAN),
494 ActionType (SWFACTION_LOGICALAND),
495 ActionType (SWFACTION_LOGICALOR),
496 ActionType (SWFACTION_LOGICALNOT),
497 ActionType (SWFACTION_STRINGEQ),
498 ActionType (SWFACTION_STRINGLENGTH),
499 ActionType (SWFACTION_STRINGCONCAT),
500 ActionType (SWFACTION_SUBSTRING),
501 ActionType (SWFACTION_STRINGCOMPARE),
502 ActionType (SWFACTION_MBLENGTH),
503 ActionType (SWFACTION_MBSUBSTRING),
504 ActionType (SWFACTION_INT),
505 ActionType (SWFACTION_ORD),
506 ActionType (SWFACTION_CHR),
507 ActionType (SWFACTION_MBORD),
508 ActionType (SWFACTION_MBCHR),
509 ActionTypeLong (SWFACTION_JUMP),
510 ActionTypeLong (SWFACTION_IF),
511 ActionType (SWFACTION_CALLFRAME),
512 ActionType (SWFACTION_GETVARIABLE),
513 ActionType (SWFACTION_SETVARIABLE),
514 ActionTypeLong (SWFACTION_GETURL2),
515 ActionTypeLong (SWFACTION_GOTOFRAME2),
516 ActionType (SWFACTION_SETTARGET2),
517 ActionType (SWFACTION_GETPROPERTY),
518 ActionType (SWFACTION_SETPROPERTY),
519 ActionType (SWFACTION_DUPLICATECLIP),
520 ActionType (SWFACTION_REMOVECLIP),
521 ActionType (SWFACTION_STARTDRAG),
522 ActionType (SWFACTION_ENDDRAG),
523 ActionType (SWFACTION_WAITFORFRAME2),
524 ActionType (SWFACTION_TRACE),
525 ActionType (SWFACTION_GETTIME),
526 ActionType (SWFACTION_RANDOMNUMBER),
527 /* v5 actions */
528 ActionType (SWFACTION_CALLFUNCTION),
529 ActionType (SWFACTION_CALLMETHOD),
530 ActionTypeLong (SWFACTION_CONSTANTPOOL),
531 ActionTypeLong (SWFACTION_DEFINEFUNCTION),
532 ActionType (SWFACTION_DEFINELOCAL),
533 ActionType (SWFACTION_DEFINELOCAL2),
534 ActionType (SWFACTION_DELETE),
535 ActionType (SWFACTION_DELETE2),
536 ActionType (SWFACTION_ENUMERATE),
537 ActionType (SWFACTION_EQUALS2),
538 ActionType (SWFACTION_GETMEMBER),
539 ActionType (SWFACTION_INITARRAY),
540 ActionType (SWFACTION_INITOBJECT),
541 ActionType (SWFACTION_NEWMETHOD),
542 ActionType (SWFACTION_NEWOBJECT),
543 ActionType (SWFACTION_SETMEMBER),
544 ActionType (SWFACTION_TARGETPATH),
545 ActionTypeLong (SWFACTION_WITH),
546 ActionType (SWFACTION_TONUMBER),
547 ActionType (SWFACTION_TOSTRING),
548 ActionType (SWFACTION_TYPEOF),
549 ActionType (SWFACTION_ADD2),
550 ActionType (SWFACTION_LESS2),
551 ActionType (SWFACTION_MODULO),
552 ActionType (SWFACTION_BITWISEAND),
553 ActionType (SWFACTION_SHIFTLEFT),
554 ActionType (SWFACTION_BITWISEOR),
555 ActionType (SWFACTION_SHIFTRIGHT),
556 ActionType (SWFACTION_SHIFTRIGHT2),
557 ActionType (SWFACTION_BITWISEXOR),
558 ActionType (SWFACTION_DECREMENT),
559 ActionType (SWFACTION_INCREMENT),
560 ActionType (SWFACTION_PUSHDUP),
561 ActionType (SWFACTION_RETURN),
562 ActionType (SWFACTION_STACKSWAP),
563 ActionTypeLong (SWFACTION_STOREREGISTER),
564 /* v6 actions */
565 ActionType (SWFACTION_INSTANCEOF),
566 ActionType (SWFACTION_ENUMERATE2),
567 ActionType (SWFACTION_STRICTEQUALS),
568 ActionType (SWFACTION_GREATER),
569 ActionType (SWFACTION_STRINGGREATER),
570 /* v7 actions */
571 ActionTypeLong (SWFACTION_DEFINEFUNCTION2),
572 ActionType (SWFACTION_EXTENDS),
573 ActionType (SWFACTION_CASTOP),
574 ActionType (SWFACTION_IMPLEMENTSOP),
575 ActionTypeLong (SWFACTION_TRY),
576 ActionType (SWFACTION_THROW),
577 ActionType (SWFACTION_FSCOMMAND2),
578 };
579
580 static int numActions = sizeof (actions) / sizeof (struct SWFActionName);
581
582 const char *
actionName(Action header)583 actionName (Action header)
584 {
585 int i;
586
587 for (i = 0; i < numActions; i++)
588 {
589 if (actions[i].type == header)
590 {
591 return actions[i].name;
592 }
593 }
594 return "Confused Action Type"; /* Should never get here */
595
596 }
597
598 void
outputSWF_ACTION(int n,SWF_ACTION * act)599 outputSWF_ACTION (int n, SWF_ACTION *act)
600 {
601 struct SWF_ACTIONRECORD *action = (struct SWF_ACTIONRECORD *)act;
602 int i;
603
604 for (i = 0; i < numActions; i++)
605 {
606 if (actions[i].type == action->ActionCode)
607 {
608 INDENT;
609 if( verbose )
610 printf (" Action: %d ", n );
611 printf (" %lu:%s\n", action->Offset, actionName (action->ActionCode));
612 if( verbose ) {
613 INDENT;
614 printf (" Offset: %lx\n", action->Offset );
615 }
616 if (actions[i].func != NULL )
617 {
618 actions[i].func(act);
619 } else {
620 if (action->ActionCode >= 0x80)
621 {
622 if( verbose ) {
623 INDENT;
624 printf (" Length: %d\n", action->Length);
625 }
626 }
627 }
628 }
629 }
630 }
631
632