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