|
|
@ -71,6 +71,7 @@ class _AVMClass(object):
|
|
|
|
self.method_pyfunctions = {}
|
|
|
|
self.method_pyfunctions = {}
|
|
|
|
|
|
|
|
|
|
|
|
self.variables = _ScopeDict(self)
|
|
|
|
self.variables = _ScopeDict(self)
|
|
|
|
|
|
|
|
self.constants = {}
|
|
|
|
|
|
|
|
|
|
|
|
def make_object(self):
|
|
|
|
def make_object(self):
|
|
|
|
return _AVMClass_Object(self)
|
|
|
|
return _AVMClass_Object(self)
|
|
|
@ -189,11 +190,13 @@ class SWFInterpreter(object):
|
|
|
|
|
|
|
|
|
|
|
|
# Constant pool
|
|
|
|
# Constant pool
|
|
|
|
int_count = u30()
|
|
|
|
int_count = u30()
|
|
|
|
|
|
|
|
self.constant_ints = [0]
|
|
|
|
for _c in range(1, int_count):
|
|
|
|
for _c in range(1, int_count):
|
|
|
|
s32()
|
|
|
|
self.constant_ints.append(s32())
|
|
|
|
|
|
|
|
self.constant_uints = [0]
|
|
|
|
uint_count = u30()
|
|
|
|
uint_count = u30()
|
|
|
|
for _c in range(1, uint_count):
|
|
|
|
for _c in range(1, uint_count):
|
|
|
|
u32()
|
|
|
|
self.constant_uints.append(u32())
|
|
|
|
double_count = u30()
|
|
|
|
double_count = u30()
|
|
|
|
read_bytes(max(0, (double_count - 1)) * 8)
|
|
|
|
read_bytes(max(0, (double_count - 1)) * 8)
|
|
|
|
string_count = u30()
|
|
|
|
string_count = u30()
|
|
|
@ -281,13 +284,28 @@ class SWFInterpreter(object):
|
|
|
|
kind = kind_full & 0x0f
|
|
|
|
kind = kind_full & 0x0f
|
|
|
|
attrs = kind_full >> 4
|
|
|
|
attrs = kind_full >> 4
|
|
|
|
methods = {}
|
|
|
|
methods = {}
|
|
|
|
if kind in [0x00, 0x06]: # Slot or Const
|
|
|
|
constants = None
|
|
|
|
|
|
|
|
if kind == 0x00: # Slot
|
|
|
|
u30() # Slot id
|
|
|
|
u30() # Slot id
|
|
|
|
u30() # type_name_idx
|
|
|
|
u30() # type_name_idx
|
|
|
|
vindex = u30()
|
|
|
|
vindex = u30()
|
|
|
|
if vindex != 0:
|
|
|
|
if vindex != 0:
|
|
|
|
read_byte() # vkind
|
|
|
|
read_byte() # vkind
|
|
|
|
elif kind in [0x01, 0x02, 0x03]: # Method / Getter / Setter
|
|
|
|
elif kind == 0x06: # Const
|
|
|
|
|
|
|
|
u30() # Slot id
|
|
|
|
|
|
|
|
u30() # type_name_idx
|
|
|
|
|
|
|
|
vindex = u30()
|
|
|
|
|
|
|
|
vkind = 'any'
|
|
|
|
|
|
|
|
if vindex != 0:
|
|
|
|
|
|
|
|
vkind = read_byte()
|
|
|
|
|
|
|
|
if vkind == 0x03: # Constant_Int
|
|
|
|
|
|
|
|
value = self.constant_ints[vindex]
|
|
|
|
|
|
|
|
elif vkind == 0x04: # Constant_UInt
|
|
|
|
|
|
|
|
value = self.constant_uints[vindex]
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return {}, None # Ignore silently for now
|
|
|
|
|
|
|
|
constants = {self.multinames[trait_name_idx]: value}
|
|
|
|
|
|
|
|
elif kind in (0x01, 0x02, 0x03): # Method / Getter / Setter
|
|
|
|
u30() # disp_id
|
|
|
|
u30() # disp_id
|
|
|
|
method_idx = u30()
|
|
|
|
method_idx = u30()
|
|
|
|
methods[self.multinames[trait_name_idx]] = method_idx
|
|
|
|
methods[self.multinames[trait_name_idx]] = method_idx
|
|
|
@ -306,7 +324,7 @@ class SWFInterpreter(object):
|
|
|
|
for _c3 in range(metadata_count):
|
|
|
|
for _c3 in range(metadata_count):
|
|
|
|
u30() # metadata index
|
|
|
|
u30() # metadata index
|
|
|
|
|
|
|
|
|
|
|
|
return methods
|
|
|
|
return methods, constants
|
|
|
|
|
|
|
|
|
|
|
|
# Classes
|
|
|
|
# Classes
|
|
|
|
class_count = u30()
|
|
|
|
class_count = u30()
|
|
|
@ -328,8 +346,9 @@ class SWFInterpreter(object):
|
|
|
|
u30() # iinit
|
|
|
|
u30() # iinit
|
|
|
|
trait_count = u30()
|
|
|
|
trait_count = u30()
|
|
|
|
for _c2 in range(trait_count):
|
|
|
|
for _c2 in range(trait_count):
|
|
|
|
trait_methods = parse_traits_info()
|
|
|
|
trait_methods, constants = parse_traits_info()
|
|
|
|
avm_class.register_methods(trait_methods)
|
|
|
|
avm_class.register_methods(trait_methods)
|
|
|
|
|
|
|
|
assert constants is None
|
|
|
|
|
|
|
|
|
|
|
|
assert len(classes) == class_count
|
|
|
|
assert len(classes) == class_count
|
|
|
|
self._classes_by_name = dict((c.name, c) for c in classes)
|
|
|
|
self._classes_by_name = dict((c.name, c) for c in classes)
|
|
|
@ -338,8 +357,10 @@ class SWFInterpreter(object):
|
|
|
|
u30() # cinit
|
|
|
|
u30() # cinit
|
|
|
|
trait_count = u30()
|
|
|
|
trait_count = u30()
|
|
|
|
for _c2 in range(trait_count):
|
|
|
|
for _c2 in range(trait_count):
|
|
|
|
trait_methods = parse_traits_info()
|
|
|
|
trait_methods, trait_constants = parse_traits_info()
|
|
|
|
avm_class.register_methods(trait_methods)
|
|
|
|
avm_class.register_methods(trait_methods)
|
|
|
|
|
|
|
|
if trait_constants:
|
|
|
|
|
|
|
|
avm_class.constants.update(trait_constants)
|
|
|
|
|
|
|
|
|
|
|
|
# Scripts
|
|
|
|
# Scripts
|
|
|
|
script_count = u30()
|
|
|
|
script_count = u30()
|
|
|
@ -633,9 +654,11 @@ class SWFInterpreter(object):
|
|
|
|
break
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
scope = avm_class.variables
|
|
|
|
scope = avm_class.variables
|
|
|
|
# I cannot find where static variables are initialized
|
|
|
|
|
|
|
|
# so let's just return None
|
|
|
|
if mname in scope:
|
|
|
|
res = scope.get(mname)
|
|
|
|
res = scope[mname]
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
res = avm_class.constants[mname]
|
|
|
|
stack.append(res)
|
|
|
|
stack.append(res)
|
|
|
|
elif opcode == 97: # setproperty
|
|
|
|
elif opcode == 97: # setproperty
|
|
|
|
index = u30()
|
|
|
|
index = u30()
|
|
|
|