[swfinterp] Add support for multiple classes

This commit is contained in:
Philipp Hagemeister 2014-07-20 00:25:58 +02:00
parent e75c24e889
commit 70f767dc65
2 changed files with 57 additions and 6 deletions

View file

@ -0,0 +1,15 @@
// input: []
// output: 0
package {
public class ClassConstruction {
public static function main():int{
var f:Foo = new Foo();
return 0;
}
}
}
class Foo {
}

View file

@ -5,7 +5,10 @@ import io
import struct import struct
import zlib import zlib
from .utils import ExtractorError from .utils import (
compat_str,
ExtractorError,
)
def _extract_tags(file_contents): def _extract_tags(file_contents):
@ -65,7 +68,26 @@ class _AVMClass(object):
self.method_idxs = {} self.method_idxs = {}
self.methods = {} self.methods = {}
self.method_pyfunctions = {} self.method_pyfunctions = {}
self.variables = {}
class ScopeDict(dict):
def __init__(self, avm_class):
super(ScopeDict, self).__init__()
self.avm_class = avm_class
def __getitem__(self, k):
print('getting %r' % k)
return super(ScopeDict, self).__getitem__(k)
def __contains__(self, k):
print('contains %r' % k)
return super(ScopeDict, self).__contains__(k)
def __repr__(self):
return '%s__Scope(%s)' % (
self.avm_class.name,
super(ScopeDict, self).__repr__())
self.variables = ScopeDict(self)
def make_object(self): def make_object(self):
return _AVMClass_Object(self) return _AVMClass_Object(self)
@ -156,10 +178,10 @@ class SWFInterpreter(object):
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()
constant_strings = [''] self.constant_strings = ['']
for _c in range(1, string_count): for _c in range(1, string_count):
s = _read_string(code_reader) s = _read_string(code_reader)
constant_strings.append(s) self.constant_strings.append(s)
namespace_count = u30() namespace_count = u30()
for _c in range(1, namespace_count): for _c in range(1, namespace_count):
read_bytes(1) # kind read_bytes(1) # kind
@ -189,7 +211,7 @@ class SWFInterpreter(object):
if kind == 0x07: if kind == 0x07:
u30() # namespace_idx u30() # namespace_idx
name_idx = u30() name_idx = u30()
self.multinames.append(constant_strings[name_idx]) self.multinames.append(self.constant_strings[name_idx])
else: else:
self.multinames.append('[MULTINAME kind: %d]' % kind) self.multinames.append('[MULTINAME kind: %d]' % kind)
for _c2 in range(MULTINAME_SIZES[kind]): for _c2 in range(MULTINAME_SIZES[kind]):
@ -375,7 +397,7 @@ class SWFInterpreter(object):
stack.append(value) stack.append(value)
elif opcode == 44: # pushstring elif opcode == 44: # pushstring
idx = u30() idx = u30()
stack.append(constant_strings[idx]) stack.append(self.constant_strings[idx])
elif opcode == 48: # pushscope elif opcode == 48: # pushscope
new_scope = stack.pop() new_scope = stack.pop()
scopes.append(new_scope) scopes.append(new_scope)
@ -450,6 +472,16 @@ class SWFInterpreter(object):
arr.append(stack.pop()) arr.append(stack.pop())
arr = arr[::-1] arr = arr[::-1]
stack.append(arr) stack.append(arr)
elif opcode == 93: # findpropstrict
index = u30()
mname = self.multinames[index]
for s in reversed(scopes):
if mname in s:
res = s
break
else:
res = scopes[0]
stack.append(res)
elif opcode == 94: # findproperty elif opcode == 94: # findproperty
index = u30() index = u30()
mname = self.multinames[index] mname = self.multinames[index]
@ -535,6 +567,10 @@ class SWFInterpreter(object):
stack.append(registers[2]) stack.append(registers[2])
elif opcode == 211: # getlocal_3 elif opcode == 211: # getlocal_3
stack.append(registers[3]) stack.append(registers[3])
elif opcode == 212: # setlocal_0
registers[0] = stack.pop()
elif opcode == 213: # setlocal_1
registers[1] = stack.pop()
elif opcode == 214: # setlocal_2 elif opcode == 214: # setlocal_2
registers[2] = stack.pop() registers[2] = stack.pop()
elif opcode == 215: # setlocal_3 elif opcode == 215: # setlocal_3