From: kramm Date: Sat, 5 Apr 2008 07:23:28 +0000 (+0000) Subject: added more implementation and opcodes X-Git-Tag: buttons-working~292 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=99f17fbc56f64e4960e9399d2f33b2bcf7b22b0c added more implementation and opcodes --- diff --git a/lib/modules/swfabc.c b/lib/modules/swfabc.c index 5f3f23e..c2d566f 100644 --- a/lib/modules/swfabc.c +++ b/lib/modules/swfabc.c @@ -373,6 +373,34 @@ int swf_GetU30(TAG*tag) return s; } +int swf_GetS30(TAG*tag) +{ + U32 shift = 0; + U32 s = 0; + while(1) { + U8 b = swf_GetU8(tag); + s|=(b&127)<pos+len; @@ -631,10 +766,21 @@ static int parse_code(TAG*tag, int len, abc_file_t*pool, char*prefix) } else if(*p == 'b') { int b = swf_GetU8(tag); printf("%02x", b); + } else if(*p == 'j') { + printf("%d", swf_GetU24(tag)); } else if(*p == 's') { const char*s = dict_getstr(pool->strings, swf_GetU30(tag)); printf("\"%s\"", s); - } + } else if(*p == 'S') { + swf_GetU24(tag); //default + int num = swf_GetU30(tag)+1; + int t; + for(t=0;tstrings, swf_GetU30(tag)); + int num = swf_GetU30(tag); + int s; + DEBUG printf(" %s\n", name); + for(s=0;sstrings, swf_GetU30(tag)); + const char*value = dict_getstr(pool->strings, swf_GetU30(tag)); + DEBUG printf(" %s=%s\n", key, value); + } + } +} + #define TRAIT_SLOT 0 #define TRAIT_METHOD 1 #define TRAIT_GETTER 2 @@ -690,6 +854,9 @@ static dict_t* parse_traits(char*prefix, TAG*tag, abc_file_t*pool, char print) int num_traits = swf_GetU30(tag); dict_t*traits = dict_new(); int t; + if(num_traits) { + DEBUG printf("%d traits\n", num_traits); + } for(t=0;tmultinames, name_index); U8 kind = swf_GetU8(tag); - DEBUG printf("trait %d) %s type=%02x\n", t, name, kind); + U8 attributes = kind&0xf0; + kind&=0x0f; + DEBUG printf(" trait %d) %s type=%02x\n", t, name, kind); if(kind == 1 || kind == 2 || kind == 3) { // method / getter / setter int disp_id = swf_GetU30(tag); int nr = swf_GetU30(tag); - DEBUG printf("%smethod %d %d %s\n", prefix, nr, disp_id, ((abc_method_t*)dict_getdata(pool->methods, nr))->paramstr); + DEBUG printf(" %smethod %d %d %s\n", prefix, nr, disp_id, ((abc_method_t*)dict_getdata(pool->methods, nr))->paramstr); if(print) dump_method(prefix, kind==1?"method":(kind==2?"getter":"setter"), name, nr, pool); } else if(kind == 5) { // function int slot_id = swf_GetU30(tag); @@ -710,19 +879,26 @@ static dict_t* parse_traits(char*prefix, TAG*tag, abc_file_t*pool, char print) } else if(kind == 4) { // class int slot_id = swf_GetU30(tag); int cls = swf_GetU30(tag); - if(print) printf("%sclass %s %d %d\n", prefix, name, slot_id, cls); - } else if(kind == 0) { // slot + if(print) printf(" %sclass %s %d %d\n", prefix, name, slot_id, cls); + } else if(kind == 0 || kind == 6) { // slot, const int slot_id = swf_GetU30(tag); const char*type_name = dict_getstr(pool->multinames, swf_GetU30(tag)); int vindex = swf_GetU30(tag); if(vindex) { U8 vkind = swf_GetU8(tag); } - if(print) printf("%sslot %s %d %s (vindex=%d)\n", prefix, name, slot_id, type_name, vindex); + if(print) printf(" %sslot %s %d %s (vindex=%d)\n", prefix, name, slot_id, type_name, vindex); } else { printf(" can't parse trait type %d\n", kind); return 0; } + if(attributes&0x40) { + int num = swf_GetU30(tag); + int s; + for(s=0;sints = dict_new(); - f->ints = dict_new(); + dict_append(f->ints, 0, (void*)0); f->uints = dict_new(); + dict_append(f->uints, 0, (void*)0); f->floats = dict_new(); + dict_append(f->floats, 0, 0); f->strings = dict_new(); dict_append(f->strings, "----", 0); f->namespaces = dict_new(); dict_append(f->namespaces, "----", 0); + f->namespace_sets = dict_new(); + dict_append(f->namespace_sets, "----", 0); f->sets = dict_new(); dict_append(f->sets, "----", 0); f->multinames = dict_new(); @@ -781,27 +961,39 @@ void swf_DissassembleABC(TAG*tag) swf_SetTagPos(tag, 0); U32 flags = swf_GetU32(tag); + int t; DEBUG printf("flags=%08x\n", flags); char*classname = swf_GetString(tag); U32 version = swf_GetU32(tag); + if(version!=0x002e0010) { + fprintf(stderr, "Warning: unknown AVM2 version %08x\n", version); + } - pool->ints->num = swf_GetU30(tag)-1; - if(pool->ints->num>0) { - printf("can't parse ints yet\n"); - return; + int num_ints = swf_GetU30(tag); + DEBUG printf("%d ints\n", num_ints); + for(t=1;tints, 0, (void*)v); } - pool->uints->num = swf_GetU30(tag)-1; - if(pool->uints->num>0) { - printf("can't parse uints yet\n"); - return; + + int num_uints = swf_GetU30(tag); + DEBUG printf("%d uints\n", num_uints); + for(t=1;tuints, 0, (void*)v); } - pool->floats->num = swf_GetU30(tag)-1; - if(pool->floats->num>0) { - printf("can't parse floats yet\n"); - return; + + int num_floats = swf_GetU30(tag); + DEBUG printf("%d floats\n", num_floats); + for(t=1;tfloats, 0, 0); } + int num_strings = swf_GetU30(tag); - int t; DEBUG printf("%d strings\n", num_strings); for(t=1;t0) { - printf("can't parse namespace sets yet\n"); - return; + DEBUG printf("%d namespace sets\n", num_namespaces); + for(t=1;tnamespaces, nsnr); + l += strlen(name[s])+1; + } + char*desc = malloc(l+16); + strcpy(desc, "{"); + for(s=0;snamespace_sets, desc, 0); + DEBUG printf("set %d) %s\n", t, desc); } + int num_multinames = swf_GetU30(tag); + DEBUG printf("%d multinames\n", num_multinames); for(t=1;tstrings, swf_GetU30(tag)); + const char*namespace = dict_getstr(pool->namespace_sets, swf_GetU30(tag)); + DEBUG printf("multiname %d) %s:%s\n", t, namespace, methodname); + mname = malloc(strlen(namespace)+strlen(methodname)+16); + strcpy(mname, namespace); + strcat(mname, ":"); + strcat(mname, methodname); + } else if(type==0x1b || type==0x1c) { + const char*nsset = dict_getstr(pool->namespace_sets, swf_GetU30(tag)); + mname = strdup(nsset); } else { printf("can't parse type %d multinames yet\n", type); return; @@ -871,6 +1090,7 @@ void swf_DissassembleABC(TAG*tag) } int num_methods = swf_GetU30(tag); + DEBUG printf("%d methods\n", num_methods); for(t=0;treturn_type_index = swf_GetU30(tag); m->index = t; int s; - char params[256]; + int params_len = 256; + char* params = malloc(params_len); params[0]='('; params[1]=0; for(s=0;sparam_count;s++) { - if(s) - strcat(params, ", "); int typenr = swf_GetU30(tag); if(s < sizeof(m->params)/sizeof(m->params[0])) m->params[s] = typenr; const char*type = dict_getstr(pool->multinames, typenr); + while(strlen(type)+strlen(params)>params_len-4) { + params_len+=256; + params = realloc(params, params_len); + } + if(s) + strcat(params, ", "); strcat(params, type); } strcat(params, ")"); @@ -896,38 +1121,53 @@ void swf_DissassembleABC(TAG*tag) if(namenr) m->name = dict_getstr(pool->strings, namenr); m->paramstr=strdup(params); - DEBUG printf("method %d) %s\n", t, m->paramstr); + free(params);params = 0; m->flags = swf_GetU8(tag); - if(m->flags&0x88) { - printf("can't parse optional or params names yet\n"); + + DEBUG printf("method %d) %s flags=%02x\n", t, m->paramstr, m->flags); + + if(m->flags&0x08) { + /* optional parameters */ + int num = swf_GetU30(tag); + int s; + for(s=0;sflags&0x80) { + printf("can't parse param names yet\n"); return; } dict_append(pool->methods, m->name, m); } - int num_metadata = swf_GetU30(tag); - for(t=0;tpos; DEBUG printf("%d classes\n", num_classes); for(t=0;tmultinames, swf_GetU30(tag)); + DEBUG printf(" class %d interface: %s\n", t, interface); + } + swf_GetU30(tag); //iinit if(!parse_traits("", tag, pool, 0)) return; } for(t=0;ttag, tag, code_length); int exception_count = swf_GetU30(tag); + int s; + for(s=0;straits = parse_traits("", tag, pool, 1); if(!c->traits) { return; @@ -996,11 +1244,12 @@ void swf_DissassembleABC(TAG*tag) } printf("class %s extends %s, %s, flags=%02x\n", classname, supername, ns, flags); printf("{\n"); - int num_interfaces = swf_GetU30(tag); - if(num_interfaces>0) { - printf("can't parse interfaces yet\n"); - return; - } + + int num_interfaces = swf_GetU30(tag); //interface count + int s; + for(s=0;siinit = swf_GetU30(tag); dump_method(" ","constructor", classname, cls->iinit, pool); cls->traits = parse_traits(" ",tag, pool, 1);