furnace-avm2 0.0.9 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -3
- data/LICENSE +20 -0
- data/bin/furnace-avm2 +36 -6
- data/bin/furnace-avm2-decompiler +141 -0
- data/furnace-avm2.gemspec +2 -2
- data/lib/furnace-avm2.rb +1 -0
- data/lib/furnace-avm2/abc.rb +24 -7
- data/lib/furnace-avm2/abc/metadata/{option_detail.rb → default_value.rb} +5 -1
- data/lib/furnace-avm2/abc/metadata/initializer_body.rb +8 -0
- data/lib/furnace-avm2/abc/metadata/instance_info.rb +19 -4
- data/lib/furnace-avm2/abc/metadata/klass_info.rb +1 -4
- data/lib/furnace-avm2/abc/metadata/method_body_info.rb +27 -10
- data/lib/furnace-avm2/abc/metadata/method_info.rb +20 -13
- data/lib/furnace-avm2/abc/metadata/multiname_info.rb +6 -0
- data/lib/furnace-avm2/abc/metadata/multiname_kind_genericname.rb +8 -5
- data/lib/furnace-avm2/abc/metadata/multiname_kind_multiname.rb +4 -0
- data/lib/furnace-avm2/abc/metadata/multiname_kind_qname.rb +5 -1
- data/lib/furnace-avm2/abc/metadata/record_with_value.rb +90 -0
- data/lib/furnace-avm2/abc/metadata/script_info.rb +25 -1
- data/lib/furnace-avm2/abc/metadata/trait_class.rb +7 -3
- data/lib/furnace-avm2/abc/metadata/trait_info.rb +8 -4
- data/lib/furnace-avm2/abc/metadata/trait_method.rb +4 -0
- data/lib/furnace-avm2/abc/metadata/trait_slot.rb +5 -51
- data/lib/furnace-avm2/abc/opcodes/bitwise/as3_lshift.rb +1 -1
- data/lib/furnace-avm2/abc/opcodes/bitwise/as3_rshift.rb +1 -1
- data/lib/furnace-avm2/abc/opcodes/bitwise/as3_urshift.rb +1 -1
- data/lib/furnace-avm2/abc/opcodes/debug/as3_debug.rb +15 -0
- data/lib/furnace-avm2/abc/opcodes/debug/as3_debugfile.rb +12 -0
- data/lib/furnace-avm2/abc/opcodes/debug/as3_debugline.rb +12 -0
- data/lib/furnace-avm2/abc/opcodes/function_invocation/as3_callproplex.rb +21 -0
- data/lib/furnace-avm2/abc/opcodes/push_literal/as3_pushbyte.rb +1 -1
- data/lib/furnace-avm2/abc/opcodes/push_literal/as3_pushshort.rb +1 -1
- data/lib/furnace-avm2/binary/record.rb +21 -1
- data/lib/furnace-avm2/source/declaration_tokens/argument_declaration_token.rb +4 -0
- data/lib/furnace-avm2/source/declaration_tokens/arguments_token.rb +15 -0
- data/lib/furnace-avm2/source/declaration_tokens/callee_token.rb +72 -0
- data/lib/furnace-avm2/source/declaration_tokens/class_implementations_token.rb +21 -0
- data/lib/furnace-avm2/source/declaration_tokens/class_inheritance_token.rb +17 -0
- data/lib/furnace-avm2/source/declaration_tokens/class_name_token.rb +21 -0
- data/lib/furnace-avm2/source/declaration_tokens/class_specifiers_token.rb +12 -0
- data/lib/furnace-avm2/source/declaration_tokens/class_token.rb +21 -0
- data/lib/furnace-avm2/source/declaration_tokens/comment_token.rb +22 -0
- data/lib/furnace-avm2/source/declaration_tokens/constructor_specifiers_token.rb +12 -0
- data/lib/furnace-avm2/source/declaration_tokens/constructor_token.rb +15 -0
- data/lib/furnace-avm2/source/declaration_tokens/function_name_token.rb +14 -0
- data/lib/furnace-avm2/source/declaration_tokens/import_token.rb +17 -0
- data/lib/furnace-avm2/source/declaration_tokens/initialization_token.rb +7 -0
- data/lib/furnace-avm2/source/declaration_tokens/method_specifiers_token.rb +13 -0
- data/lib/furnace-avm2/source/declaration_tokens/method_token.rb +15 -0
- data/lib/furnace-avm2/source/declaration_tokens/multiname_token.rb +41 -0
- data/lib/furnace-avm2/source/declaration_tokens/namespace_name_token.rb +16 -0
- data/lib/furnace-avm2/source/declaration_tokens/package_name_token.rb +17 -0
- data/lib/furnace-avm2/source/declaration_tokens/package_token.rb +29 -0
- data/lib/furnace-avm2/source/declaration_tokens/rest_argument_token.rb +12 -0
- data/lib/furnace-avm2/source/declaration_tokens/scope_token.rb +23 -0
- data/lib/furnace-avm2/source/declaration_tokens/script_token.rb +14 -0
- data/lib/furnace-avm2/source/declaration_tokens/slot_name_token.rb +17 -0
- data/lib/furnace-avm2/source/declaration_tokens/slot_token.rb +23 -0
- data/lib/furnace-avm2/source/declaration_tokens/specifiers_token.rb +32 -0
- data/lib/furnace-avm2/source/declaration_tokens/token_with_traits.rb +51 -0
- data/lib/furnace-avm2/source/declaration_tokens/type_token.rb +7 -0
- data/lib/furnace-avm2/source/decompiler.rb +669 -0
- data/lib/furnace-avm2/source/implementation_tokens/access_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/array_token.rb +17 -0
- data/lib/furnace-avm2/source/implementation_tokens/as_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/assignment_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/binary_operator_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/break_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/call_token.rb +5 -0
- data/lib/furnace-avm2/source/implementation_tokens/continue_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/control_flow_token.rb +26 -0
- data/lib/furnace-avm2/source/implementation_tokens/control_transfer_token.rb +20 -0
- data/lib/furnace-avm2/source/implementation_tokens/delete_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/do_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/else_if_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/else_token.rb +22 -0
- data/lib/furnace-avm2/source/implementation_tokens/for_each_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/for_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/generic_specializers_token.rb +17 -0
- data/lib/furnace-avm2/source/implementation_tokens/generic_type_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/if_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/immediate_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/immediate_typename_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/in_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/index_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/is_complex.rb +7 -0
- data/lib/furnace-avm2/source/implementation_tokens/is_simple.rb +7 -0
- data/lib/furnace-avm2/source/implementation_tokens/is_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/label_declaration_token.rb +12 -0
- data/lib/furnace-avm2/source/implementation_tokens/label_token.rb +12 -0
- data/lib/furnace-avm2/source/implementation_tokens/local_variable_token.rb +7 -0
- data/lib/furnace-avm2/source/implementation_tokens/new_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/object_pair_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/object_token.rb +17 -0
- data/lib/furnace-avm2/source/implementation_tokens/parentheses_token.rb +11 -0
- data/lib/furnace-avm2/source/implementation_tokens/property_name_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/return_token.rb +16 -0
- data/lib/furnace-avm2/source/implementation_tokens/rtname_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/statement_token.rb +8 -0
- data/lib/furnace-avm2/source/implementation_tokens/super_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/switch_token.rb +9 -0
- data/lib/furnace-avm2/source/implementation_tokens/ternary_operator_token.rb +13 -0
- data/lib/furnace-avm2/source/implementation_tokens/throw_token.rb +12 -0
- data/lib/furnace-avm2/source/implementation_tokens/typeof_token.rb +13 -0
- data/lib/furnace-avm2/source/implementation_tokens/unary_operator_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/unary_post_operator_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/variable_name_token.rb +14 -0
- data/lib/furnace-avm2/source/implementation_tokens/while_token.rb +9 -0
- data/lib/furnace-avm2/transform.rb +5 -1
- data/lib/furnace-avm2/transform/ast_build.rb +22 -7
- data/lib/furnace-avm2/transform/ast_normalize.rb +61 -20
- data/lib/furnace-avm2/transform/cfg_build.rb +86 -0
- data/lib/furnace-avm2/transform/cfg_reduce.rb +249 -0
- data/lib/furnace-avm2/transform/nf_normalize.rb +130 -0
- data/lib/furnace-avm2/version.rb +4 -2
- data/test/basic.as +239 -0
- metadata +110 -38
- data/lib/furnace-avm2/abc/metadata/option_info.rb +0 -5
- data/test/exception.as +0 -29
- data/test/literal.as +0 -5
- data/test/logic.as +0 -23
- data/test/loops.as +0 -30
- data/test/number.as +0 -14
- data/test/switch.as +0 -38
- data/test/ternary.as +0 -22
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
furnace-avm2 (0.0
|
5
|
-
furnace (>= 0.0
|
4
|
+
furnace-avm2 (0.9.0)
|
5
|
+
furnace (>= 0.1.0)
|
6
6
|
trollop
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: http://rubygems.org/
|
10
10
|
specs:
|
11
|
-
furnace (0.0
|
11
|
+
furnace (0.1.0)
|
12
12
|
trollop (1.16.2)
|
13
13
|
|
14
14
|
PLATFORMS
|
15
|
+
java
|
15
16
|
ruby
|
16
17
|
|
17
18
|
DEPENDENCIES
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Peter Zotov <whitequark@whitequark.org>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
4
|
+
copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included
|
12
|
+
in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/furnace-avm2
CHANGED
@@ -13,7 +13,7 @@ require "benchmark"
|
|
13
13
|
include Furnace
|
14
14
|
|
15
15
|
opts = Trollop::options do
|
16
|
-
version "furnace-
|
16
|
+
version "furnace-avm2 #{AVM2::VERSION}"
|
17
17
|
banner <<-EOS
|
18
18
|
furnace-avm2 is a processing tool which operates on ActionScript3 bytecode.
|
19
19
|
|
@@ -39,6 +39,8 @@ EOS
|
|
39
39
|
|
40
40
|
opt :dce, "Eliminate dead code", :default => false
|
41
41
|
opt :ast, "Build AST", :default => false
|
42
|
+
opt :nf, "Build NF-AST", :default => false
|
43
|
+
opt :decompile, "Decompile methods", :default => false
|
42
44
|
end
|
43
45
|
|
44
46
|
Trollop::die "Stray arguments: #{ARGV}" unless ARGV.empty?
|
@@ -50,7 +52,6 @@ File.open(opts[:input]) do |file|
|
|
50
52
|
end
|
51
53
|
|
52
54
|
disasm = lambda do |body, after|
|
53
|
-
puts
|
54
55
|
puts "Method #{body.method_idx}," <<
|
55
56
|
" max stack #{body.max_stack}, local count #{body.local_count}"
|
56
57
|
if after
|
@@ -68,6 +69,8 @@ disasm = lambda do |body, after|
|
|
68
69
|
"catch(#{exception.exc_type} #{exception.var_name}) #{exception.target_offset}"
|
69
70
|
end
|
70
71
|
end
|
72
|
+
|
73
|
+
puts
|
71
74
|
end
|
72
75
|
|
73
76
|
failed = []
|
@@ -130,21 +133,48 @@ opts[:threads].times do
|
|
130
133
|
dced << body.method_idx if body.code.eliminate_dead!
|
131
134
|
end
|
132
135
|
|
136
|
+
disasm[body, true] if opts[:disasm_after]
|
137
|
+
|
133
138
|
if opts[:ast]
|
134
|
-
ast
|
135
|
-
puts "Method #{body.method_idx}"
|
139
|
+
ast = body.code_to_ast
|
140
|
+
puts "Method #{body.method_idx}; AST"
|
136
141
|
puts ast.to_sexp
|
137
142
|
puts
|
138
143
|
end
|
139
144
|
|
140
145
|
if opts[:cfg]
|
141
|
-
cfg = body.
|
146
|
+
cfg = body.code_to_cfg
|
142
147
|
File.open("method-#{body.method_idx}.dot", "w") do |dot|
|
143
148
|
dot.write cfg.to_graphviz
|
144
149
|
end
|
150
|
+
|
151
|
+
puts "Method #{body.method_idx}; dominators"
|
152
|
+
cfg.dominators.each do |node, dominating|
|
153
|
+
puts "#{node.label.inspect} => " +
|
154
|
+
"#{dominating.map(&:label).map(&:inspect).join(", ")}"
|
155
|
+
end
|
156
|
+
puts
|
157
|
+
|
158
|
+
puts "Method #{body.method_idx}; loops"
|
159
|
+
cfg.identify_loops.each do |header, body|
|
160
|
+
puts "#{header.label.inspect} => " +
|
161
|
+
"#{body.map(&:label).map(&:inspect).join(", ")}"
|
162
|
+
end
|
163
|
+
puts
|
145
164
|
end
|
146
165
|
|
147
|
-
|
166
|
+
if opts[:nf]
|
167
|
+
ast = body.code_to_nf
|
168
|
+
puts "Method #{body.method_idx}; NF-AST"
|
169
|
+
puts ast.to_sexp
|
170
|
+
puts
|
171
|
+
end
|
172
|
+
|
173
|
+
if opts[:decompile]
|
174
|
+
puts "Method #{body.method_idx}"
|
175
|
+
puts body.decompile(ns: []).to_text.lstrip
|
176
|
+
puts
|
177
|
+
end
|
148
178
|
rescue Exception => e
|
149
179
|
if opts[:collect]
|
150
180
|
puts "Failure at method body idx=#{body.method_idx}: #{e.class} (#{e.message}) at #{e.backtrace.first}."
|
@@ -0,0 +1,141 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler/setup"
|
5
|
+
|
6
|
+
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
7
|
+
|
8
|
+
require "trollop"
|
9
|
+
require "furnace-avm2"
|
10
|
+
require "thread"
|
11
|
+
|
12
|
+
include Furnace
|
13
|
+
|
14
|
+
DEBUG_INFO = %w(names funids)
|
15
|
+
|
16
|
+
opts = Trollop::options do
|
17
|
+
version "furnace-avm2 #{AVM2::VERSION} decompiler"
|
18
|
+
banner <<-EOS
|
19
|
+
furnace-avm2-decompiler is a decompiler for ActionScript3 bytecode.
|
20
|
+
|
21
|
+
Debugging information classes: #{DEBUG_INFO.join(", ")}.
|
22
|
+
|
23
|
+
Usage: #{__FILE__} [options]
|
24
|
+
EOS
|
25
|
+
|
26
|
+
opt :input, "Input file", :type => :string, :required => true
|
27
|
+
opt :verbose, "Be verbose", :default => false
|
28
|
+
opt :debug, "Show debugging information for <s+>.", :type => :strings, :short => '-D'
|
29
|
+
|
30
|
+
opt :threads, "Use <i> threads for processing", :default => 1
|
31
|
+
|
32
|
+
opt :only, "Only operate on classes <s+>", :type => :strings, :short => '-O'
|
33
|
+
opt :except, "Operate on all classes except <s+>", :type => :strings, :short => '-E'
|
34
|
+
opt :grep, "Search <s> (regexp) in class names", :type => :string, :short => '-G'
|
35
|
+
|
36
|
+
opt :decompile, "Write ActionScript 3 code", :type => :boolean, :short => '-d'
|
37
|
+
opt :destructurize, "Write internal token structure", :type => :boolean, :short => '-s'
|
38
|
+
end
|
39
|
+
|
40
|
+
Trollop::die "Stray arguments: #{ARGV}" unless ARGV.empty?
|
41
|
+
|
42
|
+
decompile_options = {}
|
43
|
+
|
44
|
+
(opts[:debug] || []).each do |opt|
|
45
|
+
Trollop::die "Unknown debug option #{opt}." unless DEBUG_INFO.include? opt
|
46
|
+
|
47
|
+
decompile_options[:"debug_#{opt}"] = true
|
48
|
+
end
|
49
|
+
|
50
|
+
shound_skip = ->(obj) {
|
51
|
+
(opts[:except] && opts[:except].include?(obj.to_s)) ||
|
52
|
+
(opts[:only] && !opts[:only].include?(obj.to_s))
|
53
|
+
}
|
54
|
+
|
55
|
+
$stderr.puts "Reading input data..."
|
56
|
+
|
57
|
+
abc = nil
|
58
|
+
File.open(opts[:input]) do |file|
|
59
|
+
abc = AVM2::ABC::File.new
|
60
|
+
abc.read(file)
|
61
|
+
end
|
62
|
+
|
63
|
+
if opts[:grep]
|
64
|
+
regexp = Regexp.new(opts[:grep], Regexp::IGNORECASE)
|
65
|
+
|
66
|
+
abc.instances.each do |inst|
|
67
|
+
if inst.name.to_s =~ regexp
|
68
|
+
if inst.interface?
|
69
|
+
print "Iface "
|
70
|
+
else
|
71
|
+
print "Class "
|
72
|
+
end
|
73
|
+
|
74
|
+
print inst.name.to_s.ljust(30)
|
75
|
+
|
76
|
+
if inst.super_name
|
77
|
+
print " extends #{inst.super_name.to_s}"
|
78
|
+
end
|
79
|
+
|
80
|
+
puts
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
|
87
|
+
mutex = Mutex.new
|
88
|
+
|
89
|
+
roots = {}
|
90
|
+
workqueue = abc.instances.dup + abc.scripts.select(&:any_code?)
|
91
|
+
total_size = workqueue.size
|
92
|
+
|
93
|
+
last_percentage = 0
|
94
|
+
|
95
|
+
$stderr.puts "Decompiling #{total_size} classes and packages..."
|
96
|
+
|
97
|
+
opts[:threads].times.map do
|
98
|
+
Thread.new do
|
99
|
+
loop do
|
100
|
+
what = nil
|
101
|
+
mutex.synchronize do
|
102
|
+
what = workqueue.pop
|
103
|
+
|
104
|
+
percentage = (total_size - workqueue.size) * 100 / total_size
|
105
|
+
if percentage >= last_percentage
|
106
|
+
$stderr.print " #{percentage}% (#{total_size - workqueue.size}) "
|
107
|
+
last_percentage += 10
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
break if what.nil?
|
112
|
+
|
113
|
+
if what.is_a? AVM2::ABC::InstanceInfo
|
114
|
+
name = what.name
|
115
|
+
ns = name.ns
|
116
|
+
else # ScriptInfo
|
117
|
+
name = what.traits[0].name.ns
|
118
|
+
ns = name.to_s.sub(/(^|\.)[^.]+$/, '')
|
119
|
+
end
|
120
|
+
next if shound_skip.(name)
|
121
|
+
|
122
|
+
source = what.decompile(decompile_options)
|
123
|
+
next unless source
|
124
|
+
|
125
|
+
text = source.to_text
|
126
|
+
|
127
|
+
mutex.synchronize do
|
128
|
+
$stderr.print "."
|
129
|
+
roots[ns.to_s] ||= []
|
130
|
+
roots[ns.to_s] << text
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end.each(&:join)
|
135
|
+
|
136
|
+
$stderr.puts
|
137
|
+
|
138
|
+
roots.values.flatten.each do |code|
|
139
|
+
puts code
|
140
|
+
puts
|
141
|
+
end
|
data/furnace-avm2.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "furnace-avm2"
|
3
|
+
require "furnace-avm2/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "furnace-avm2"
|
@@ -17,6 +17,6 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
s.add_runtime_dependency "furnace", '>= 0.0
|
20
|
+
s.add_runtime_dependency "furnace", '>= 0.1.0'
|
21
21
|
s.add_runtime_dependency "trollop"
|
22
22
|
end
|
data/lib/furnace-avm2.rb
CHANGED
data/lib/furnace-avm2/abc.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Furnace::AVM2::ABC
|
2
|
-
AST
|
3
|
-
CFG
|
2
|
+
AST = Furnace::AST
|
3
|
+
CFG = Furnace::CFG
|
4
4
|
end
|
5
5
|
|
6
6
|
require_relative "binary/choice_definition"
|
@@ -41,11 +41,8 @@ require_relative "abc/metadata/multiname_kind_genericname"
|
|
41
41
|
require_relative "abc/metadata/multiname_info"
|
42
42
|
require_relative "abc/metadata/const_pool_info"
|
43
43
|
|
44
|
-
require_relative "abc/metadata/
|
45
|
-
require_relative "abc/metadata/
|
46
|
-
require_relative "abc/metadata/method_info"
|
47
|
-
|
48
|
-
require_relative "abc/metadata/metadata_info"
|
44
|
+
require_relative "abc/metadata/record_with_value"
|
45
|
+
require_relative "abc/metadata/initializer_body"
|
49
46
|
|
50
47
|
require_relative "abc/metadata/trait_slot"
|
51
48
|
require_relative "abc/metadata/trait_method"
|
@@ -53,6 +50,11 @@ require_relative "abc/metadata/trait_class"
|
|
53
50
|
require_relative "abc/metadata/trait_function"
|
54
51
|
require_relative "abc/metadata/trait_info"
|
55
52
|
|
53
|
+
require_relative "abc/metadata/default_value"
|
54
|
+
require_relative "abc/metadata/method_info"
|
55
|
+
|
56
|
+
require_relative "abc/metadata/metadata_info"
|
57
|
+
|
56
58
|
require_relative "abc/metadata/record_with_traits"
|
57
59
|
|
58
60
|
require_relative "abc/metadata/instance_info"
|
@@ -66,3 +68,18 @@ require_relative "abc/metadata/method_body_info"
|
|
66
68
|
require_relative "abc/metadata/file"
|
67
69
|
|
68
70
|
Furnace::AVM2::Binary::Record.codegen_each
|
71
|
+
|
72
|
+
require_relative "source/declaration_tokens/token_with_traits"
|
73
|
+
|
74
|
+
Dir[File.join(File.dirname(__FILE__), "source", "declaration_tokens", "*.rb")].each do |file|
|
75
|
+
require file
|
76
|
+
end
|
77
|
+
|
78
|
+
require_relative 'source/implementation_tokens/is_simple'
|
79
|
+
require_relative 'source/implementation_tokens/is_complex'
|
80
|
+
|
81
|
+
Dir[File.join(File.dirname(__FILE__), "source", "implementation_tokens", "*.rb")].each do |file|
|
82
|
+
require file
|
83
|
+
end
|
84
|
+
|
85
|
+
require_relative 'source/decompiler'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Furnace::AVM2::ABC
|
2
2
|
class InstanceInfo < Record
|
3
3
|
include RecordWithTraits
|
4
|
+
include InitializerBody
|
4
5
|
|
5
6
|
CLASS_SEALED = 0x01
|
6
7
|
CLASS_FINAL = 0x02
|
@@ -28,10 +29,6 @@ module Furnace::AVM2::ABC
|
|
28
29
|
root.klasses[root.instances.index(self)]
|
29
30
|
end
|
30
31
|
|
31
|
-
def initializer_body
|
32
|
-
root.method_bodies.find { |body| body.method_idx == initializer_idx }
|
33
|
-
end
|
34
|
-
|
35
32
|
def to_astlet
|
36
33
|
if interface?
|
37
34
|
root = AST::Node.new(:interface)
|
@@ -64,5 +61,23 @@ module Furnace::AVM2::ABC
|
|
64
61
|
|
65
62
|
root.normalize_hierarchy!
|
66
63
|
end
|
64
|
+
|
65
|
+
def collect_ns
|
66
|
+
ns = []
|
67
|
+
ns << super_name.ns if super_name
|
68
|
+
ns += initializer.collect_ns if initializer
|
69
|
+
interfaces.each { |iface| ns << iface.ns_set.ns[0] } # stupid avm2
|
70
|
+
traits.each { |trait| ns += trait.collect_ns }
|
71
|
+
klass.traits.each { |trait| ns += trait.collect_ns }
|
72
|
+
ns
|
73
|
+
end
|
74
|
+
|
75
|
+
def decompile(options={})
|
76
|
+
Furnace::AVM2::Tokens::PackageToken.new(self,
|
77
|
+
options.merge(
|
78
|
+
ns: collect_ns,
|
79
|
+
package_type: (interface? ? :interface : :class),
|
80
|
+
package_name: name))
|
81
|
+
end
|
67
82
|
end
|
68
83
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Furnace::AVM2::ABC
|
2
2
|
class KlassInfo < Record
|
3
3
|
include RecordWithTraits
|
4
|
+
include InitializerBody
|
4
5
|
|
5
6
|
root_ref :initializer, :method
|
6
7
|
|
@@ -10,10 +11,6 @@ module Furnace::AVM2::ABC
|
|
10
11
|
root.instances[root.klasses.index(self)]
|
11
12
|
end
|
12
13
|
|
13
|
-
def initializer_body
|
14
|
-
root.method_bodies.find { |body| body.method_idx == initializer_idx }
|
15
|
-
end
|
16
|
-
|
17
14
|
def to_astlet
|
18
15
|
root = AST::Node.new(:klass)
|
19
16
|
|
@@ -19,17 +19,34 @@ module Furnace::AVM2::ABC
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def code_to_ast
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
def code_to_ast(options={})
|
23
|
+
pipeline = Furnace::Transform::Pipeline.new([
|
24
|
+
Furnace::AVM2::Transform::ASTBuild.new(options),
|
25
|
+
Furnace::AVM2::Transform::ASTNormalize.new
|
26
|
+
])
|
27
|
+
|
28
|
+
pipeline.run(code, self)
|
29
|
+
end
|
30
|
+
|
31
|
+
def code_to_cfg
|
32
|
+
pipeline = Furnace::Transform::Pipeline.new([
|
33
|
+
Furnace::AVM2::Transform::CFGBuild.new
|
34
|
+
])
|
35
|
+
|
36
|
+
pipeline.run(*code_to_ast)
|
37
|
+
end
|
38
|
+
|
39
|
+
def code_to_nf
|
40
|
+
pipeline = Furnace::Transform::Pipeline.new([
|
41
|
+
Furnace::AVM2::Transform::CFGReduce.new,
|
42
|
+
Furnace::AVM2::Transform::NFNormalize.new,
|
43
|
+
])
|
44
|
+
|
45
|
+
pipeline.run(*code_to_cfg)
|
46
|
+
end
|
31
47
|
|
32
|
-
|
48
|
+
def decompile(options={})
|
49
|
+
Furnace::AVM2::Decompiler.new(self, options).decompile
|
33
50
|
end
|
34
51
|
end
|
35
52
|
end
|