/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- println
- readUInt8
- readSInt8
- readSInt16
- readUInt16
- readSInt32
- readUInt32
- readDouble
- readString
- dumpBytes
- printActionRecord
- printDoAction
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "action.h"
#include "compile.h"
#define print(x) {fputs(x,stdout);}
int gIndent;
#define INDENT_LEVEL 2
void println(const char *s, ...)
{
va_list ap;
int n = gIndent*INDENT_LEVEL;
while(n-- > 0)
putchar(' ');
va_start(ap, s);
vprintf(s, ap);
va_end(ap);
putchar('\n');
}
int fileOffset = 0;
int readUInt8(Buffer f)
{
return f->buffer[fileOffset++];
}
int readSInt8(Buffer f)
{
return (signed char)readUInt8(f);
}
int readSInt16(Buffer f)
{
return readUInt8(f) + readSInt8(f)*256;
}
int readUInt16(Buffer f)
{
return readUInt8(f) + (readUInt8(f)<<8);
}
long readSInt32(Buffer f)
{
return (long)readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24);
}
unsigned long readUInt32(Buffer f)
{
return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
}
double readDouble(Buffer f)
{
double d;
unsigned char *p = (unsigned char *)&d;
p[4] = readUInt8(f);
p[5] = readUInt8(f);
p[6] = readUInt8(f);
p[7] = readUInt8(f);
p[0] = readUInt8(f);
p[1] = readUInt8(f);
p[2] = readUInt8(f);
p[3] = readUInt8(f);
return d;
}
char *readString(Buffer f)
{
int len = 0, buflen = 256;
char c, *buf, *p;
buf = (char *)malloc(sizeof(char)*256);
p = buf;
while((c=(char)readUInt8(f)) != '\0')
{
if(len==buflen)
{
buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
buflen += 256;
p = buf+len;
}
*(p++) = c;
++len;
}
*p = 0;
return buf;
}
void dumpBytes(Buffer f, int length)
{
int j=0, i, k;
unsigned char buf[16];
if(length==0)
return;
for(;;)
{
for(i=0; i<16; ++i)
{
printf("%02x ", buf[i] = readUInt8(f));
++j;
if(j==length)
break;
}
if(j==length)
{
for(k=i+1; k<16; ++k)
print(" ");
++i;
}
print(" ");
for(k=0; k<i; ++k)
if((buf[k] > 31) && (buf[k] < 128))
putchar(buf[k]);
else
putchar('.');
putchar('\n');
if(j==length)
break;
}
putchar('\n');
putchar('\n');
}
void printDoAction(Buffer f, int length);
char *dictionary[256];
int printActionRecord(Buffer f)
{
int length = 0, type;
printf("(%i)\t", fileOffset);
type = readUInt8(f);
if((type&0x80) == 0x80)
length = readUInt16(f);
switch(type)
{
case SWFACTION_ADD:
println("Add");
break;
case SWFACTION_SUBTRACT:
println("Subtract");
break;
case SWFACTION_MULTIPLY:
println("Multiply");
break;
case SWFACTION_DIVIDE:
println("Divide");
break;
case SWFACTION_EQUAL:
println("Equals");
break;
case SWFACTION_LESSTHAN:
println("Less Than");
break;
case SWFACTION_LOGICALAND:
println("And");
break;
case SWFACTION_LOGICALOR:
println("Or");
break;
case SWFACTION_LOGICALNOT:
println("Not");
break;
case SWFACTION_STRINGEQ:
println("String eq");
break;
case SWFACTION_STRINGLENGTH:
println("String Length");
break;
case SWFACTION_SUBSTRING:
println("Substring");
break;
case SWFACTION_POP:
println("Pop");
break;
case SWFACTION_INT:
println("Int");
break;
case SWFACTION_GETVARIABLE:
println("Get Variable");
break;
case SWFACTION_SETVARIABLE:
println("Set Variable");
break;
case SWFACTION_SETTARGETEXPRESSION:
println("Set Target Expression");
break;
case SWFACTION_STRINGCONCAT:
println("String Concat");
break;
case SWFACTION_GETPROPERTY:
println("Get Property");
break;
case SWFACTION_SETPROPERTY:
println("Set Property");
break;
case SWFACTION_DUPLICATECLIP:
println("Duplicate Clip");
break;
case SWFACTION_REMOVECLIP:
println("Remove Clip");
break;
case SWFACTION_TRACE:
println("Trace");
break;
case SWFACTION_STARTDRAGMOVIE:
println("Start Drag Movie");
break;
case SWFACTION_STOPDRAGMOVIE:
println("Stop Drag Movie");
break;
case SWFACTION_STRINGCOMPARE:
println("String Compare");
break;
case SWFACTION_RANDOM:
println("Random");
break;
case SWFACTION_MBLENGTH:
println("String MB Length");
break;
case SWFACTION_ORD:
println("Ord");
break;
case SWFACTION_CHR:
println("Chr");
break;
case SWFACTION_GETTIMER:
println("Get Timer");
break;
case SWFACTION_MBSUBSTRING:
println("MB Substring");
break;
case SWFACTION_MBORD:
println("MB Ord");
break;
case SWFACTION_MBCHR:
println("MB Chr");
break;
case SWFACTION_NEXTFRAME:
println("Next Frame");
break;
case SWFACTION_PREVFRAME:
println("Previous Frame");
break;
case SWFACTION_PLAY:
println("Play");
break;
case SWFACTION_STOP:
println("Stop");
break;
case SWFACTION_TOGGLEQUALITY:
println("Toggle Quality");
break;
case SWFACTION_STOPSOUNDS:
println("Stop Sounds");
break;
/* ops with args */
case SWFACTION_PUSHDATA:
{
int type;
int start = fileOffset;
while(fileOffset < start+length)
{
switch(type = readUInt8(f))
{
case 0: /* string */
println("Push String: %s", readString(f));
break;
case 1: /* property */
readUInt16(f); /* always 0? */
println("Push Property: %04x", readUInt16(f));
break;
case 2: /* null */
println("Push NULL");
break;
case 3: /* ??? */
println("Push type 3- ??");
break;
case 4:
println("Push register %i", readUInt8(f));
break;
case 5:
if(readUInt8(f))
println("Push true");
else
println("Push false");
break;
case 6: /* double */
println("Push %f", readDouble(f));
break;
case 7: /* int */
println("Push %i", readSInt32(f));
break;
case 8: /* dictionary */
println("Push \"%s\"", dictionary[readUInt8(f)]);
break;
case 9: /* dictionary */
println("Push \"%s\"", dictionary[readSInt16(f)]);
default:
println("unknown push type: %i", type);
}
}
break;
}
case SWFACTION_GOTOFRAME:
println("Goto Frame %i", readUInt16(f));
break;
case SWFACTION_GETURL:
{
char *url = readString(f);
println("Get URL \"%s\" target \"%s\"", url, readString(f));
break;
}
case SWFACTION_WAITFORFRAMEEXPRESSION:
println("Wait For Frame Expression, skip %i\n", readUInt8(f));
break;
case SWFACTION_BRANCHALWAYS:
println("Branch Always %i", readSInt16(f));
break;
case SWFACTION_GETURL2:
{
int flags = readUInt8(f);
const char *op = (flags & 0x80) ? "Get URL2 (loadvariables)" : "Get URL2";
const char *tgt = (flags & 0x40) ? " into target" : "";
switch(flags & 0x03)
{
case 0: println("%s%s (Don't send)", op, tgt); break;
case 1: println("%s%s (GET)", op, tgt); break;
case 2: println("%s%s (POST)", op, tgt); break;
}
}
break;
case SWFACTION_BRANCHIFTRUE:
println("Branch If True %i", readSInt16(f));
break;
case SWFACTION_CALLFRAME:
println("Call Frame");
dumpBytes(f, length);
break;
case SWFACTION_GOTOEXPRESSION:
print("Goto Expression");
if(readUInt8(f) == 1)
printf(" and Play\n");
else
printf(" and Stop\n");
break;
case SWFACTION_WAITFORFRAME:
{
int frame = readUInt16(f);
println("Wait for frame %i else skip %i", frame, readUInt8(f));
break;
}
case SWFACTION_SETTARGET:
println("Set Target %s", readString(f));
break;
case SWFACTION_GOTOLABEL:
println("Goto Label %s", readString(f));
break;
case SWFACTION_END:
return 0;
break;
/* f5 ops */
case SWFACTION_DELETE:
println("Delete");
break;
case SWFACTION_VAR:
println("Var");
break;
case SWFACTION_VAREQUALS:
println("Var assign");
break;
case SWFACTION_INITARRAY:
println("Init array");
break;
case SWFACTION_INITOBJECT:
println("Init object");
break;
case SWFACTION_CALLFUNCTION:
println("call function");
break;
case SWFACTION_RETURN:
println("return");
break;
case SWFACTION_MODULO:
println("modulo");
break;
case SWFACTION_NEW:
println("new");
break;
case SWFACTION_TYPEOF:
println("typeof");
break;
case SWFACTION_NEWADD:
println("new add");
break;
case SWFACTION_NEWLESSTHAN:
println("new less than");
break;
case SWFACTION_NEWEQUALS:
println("new equals");
break;
case SWFACTION_DUP:
println("dup");
break;
case SWFACTION_SWAP:
println("swap");
break;
case SWFACTION_GETMEMBER:
println("get member");
break;
case SWFACTION_SETMEMBER:
println("set member");
break;
case SWFACTION_INCREMENT:
println("increment");
break;
case SWFACTION_CALLMETHOD:
println("call method");
break;
case SWFACTION_BITWISEAND:
println("bitwise and");
break;
case SWFACTION_BITWISEOR:
println("bitwise or");
break;
case SWFACTION_BITWISEXOR:
println("bitwise xor");
break;
case SWFACTION_SHIFTLEFT:
println("shift left");
break;
case SWFACTION_SHIFTRIGHT:
println("shift right");
break;
case SWFACTION_SHIFTRIGHT2:
println("shift right 2");
break;
case SWFACTION_CONSTANTPOOL:
{
int i, n = readUInt16(f);
print("declare dictionary:");
for(i=0; i<n; ++i)
printf(" %s%c", dictionary[i]=readString(f), (i<n-1)?',':'\n');
break;
}
case SWFACTION_WITH:
{
println("with");
++gIndent;
printDoAction(f, readUInt16(f));
--gIndent;
break;
}
case SWFACTION_DEFINEFUNCTION:
{
char *name = readString(f);
int n = readUInt16(f);
print("function ");
print(name);
putchar('(');
if(n > 0)
{
printf("%s", readString(f));
--n;
}
for(; n>0; --n)
printf(", %s", readString(f));
putchar(')');
putchar('\n');
++gIndent;
printDoAction(f, readUInt16(f));
--gIndent;
break;
}
case SWFACTION_ENUMERATE:
println("enumerate");
break;
case SWFACTION_SETREGISTER:
println("set register %i", readUInt8(f));
break;
/* f6 actions */
case SWFACTION_INSTANCEOF:
println("instanceof");
break;
case SWFACTION_STRICTEQ:
println("strict_equals");
break;
case SWFACTION_ENUM2:
println("enum2");
break;
default:
println("Unknown Action: %02X", type);
dumpBytes(f, length);
}
return 1;
}
void printDoAction(Buffer f, int length)
{
int end;
if(!f)
return;
end = fileOffset + length;
while(fileOffset < end && printActionRecord(f))
;
}