iZsh-wwmd 0.2.19
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +24 -0
- data/README.rdoc +87 -0
- data/Rakefile +34 -0
- data/examples/config_example.yaml +24 -0
- data/examples/wwmd_example.rb +73 -0
- data/lib/wwmd.rb +78 -0
- data/lib/wwmd/class_extensions.rb +2 -0
- data/lib/wwmd/class_extensions/extensions_base.rb +235 -0
- data/lib/wwmd/class_extensions/extensions_encoding.rb +79 -0
- data/lib/wwmd/class_extensions/extensions_external.rb +18 -0
- data/lib/wwmd/class_extensions/extensions_nilclass.rb +11 -0
- data/lib/wwmd/class_extensions/extensions_rbkb.rb +188 -0
- data/lib/wwmd/class_extensions/mixins_string_encoding.rb +40 -0
- data/lib/wwmd/guid.rb +155 -0
- data/lib/wwmd/page.rb +3 -0
- data/lib/wwmd/page/auth.rb +17 -0
- data/lib/wwmd/page/constants.rb +64 -0
- data/lib/wwmd/page/form.rb +99 -0
- data/lib/wwmd/page/form_array.rb +296 -0
- data/lib/wwmd/page/headers.rb +111 -0
- data/lib/wwmd/page/helpers.rb +30 -0
- data/lib/wwmd/page/html2text_hpricot.rb +76 -0
- data/lib/wwmd/page/html2text_nokogiri.rb +42 -0
- data/lib/wwmd/page/inputs.rb +47 -0
- data/lib/wwmd/page/irb_helpers.rb +114 -0
- data/lib/wwmd/page/page.rb +241 -0
- data/lib/wwmd/page/parsing_convenience.rb +94 -0
- data/lib/wwmd/page/reporting_helpers.rb +87 -0
- data/lib/wwmd/page/scrape.rb +198 -0
- data/lib/wwmd/page/spider.rb +127 -0
- data/lib/wwmd/urlparse.rb +104 -0
- data/lib/wwmd/viewstate.rb +17 -0
- data/lib/wwmd/viewstate/viewstate.rb +101 -0
- data/lib/wwmd/viewstate/viewstate_deserializer_methods.rb +217 -0
- data/lib/wwmd/viewstate/viewstate_from_xml.rb +128 -0
- data/lib/wwmd/viewstate/viewstate_types.rb +51 -0
- data/lib/wwmd/viewstate/viewstate_utils.rb +162 -0
- data/lib/wwmd/viewstate/viewstate_yaml.rb +25 -0
- data/lib/wwmd/viewstate/vs_stubs.rb +22 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_array.rb +38 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_binary_serialized.rb +30 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_hashtable.rb +42 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_hybrid_dict.rb +42 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_indexed_string.rb +6 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_indexed_string_ref.rb +24 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_int_enum.rb +27 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_list.rb +34 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_pair.rb +29 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_read_types.rb +11 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_read_value.rb +35 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_sparse_array.rb +58 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_string.rb +33 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_string_array.rb +39 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_string_formatted.rb +32 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_stub_helpers.rb +37 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_triplet.rb +31 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_type.rb +23 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_unit.rb +30 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_value.rb +35 -0
- data/lib/wwmd/wwmd_config.rb +52 -0
- data/lib/wwmd/wwmd_puts.rb +9 -0
- data/lib/wwmd/wwmd_utils.rb +28 -0
- data/spec/README +3 -0
- data/spec/form_array.spec +49 -0
- data/spec/spider_csrf_test.spec +28 -0
- data/spec/urlparse_test.spec +101 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- metadata +174 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'htmlentities'
|
2
|
+
require 'wwmd/class_extensions'
|
3
|
+
module WWMD
|
4
|
+
|
5
|
+
# yay for experiments in re-inventing the wheel
|
6
|
+
class URLParse
|
7
|
+
HANDLERS = [:https,:http,:ftp,:file]
|
8
|
+
attr_reader :proto,:location,:path,:script,:rpath,:params,:base_url,:fqpath
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
# nothing to see here, move along
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse(*args)
|
15
|
+
if args.size == 1
|
16
|
+
base = ""
|
17
|
+
actual = args.shift
|
18
|
+
else
|
19
|
+
base = args.shift
|
20
|
+
actual = args.shift
|
21
|
+
end
|
22
|
+
@proto = @location = @path = @script = @rpath = nil
|
23
|
+
@base = base.to_s
|
24
|
+
@actual = actual
|
25
|
+
if self.has_proto?
|
26
|
+
@base = @actual
|
27
|
+
@actual = ""
|
28
|
+
end
|
29
|
+
# does this work for http://location/? probably not
|
30
|
+
@base += "/" if (!@base.has_ext? || @base.split("/").size == 3)
|
31
|
+
@rpath = make_me_path.join("/")
|
32
|
+
@rpath += "?#{@params}" if @params
|
33
|
+
@path = "/" + @rpath
|
34
|
+
if @rpath.has_ext?
|
35
|
+
@path = "/" + @rpath.dirname
|
36
|
+
@script = @rpath.basename.clip
|
37
|
+
end
|
38
|
+
@script = "" if @script.nil?
|
39
|
+
begin
|
40
|
+
@base_url = @proto + "://" + @location
|
41
|
+
rescue => e
|
42
|
+
dgb = WWMD.debug
|
43
|
+
WWMD.debug = true
|
44
|
+
putd "ERROR in urlparse TRACE:"
|
45
|
+
pp *args
|
46
|
+
putd @proto
|
47
|
+
putd @base
|
48
|
+
putd @actual
|
49
|
+
putd @location
|
50
|
+
WWMD.debug = dbg
|
51
|
+
raise e
|
52
|
+
end
|
53
|
+
@fqpath = @path + @script
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def make_me_path
|
58
|
+
@proto,tpath = @base.split(":",2)
|
59
|
+
tpath ||= ""
|
60
|
+
@params = tpath.clop
|
61
|
+
tpath = tpath.clip
|
62
|
+
if @actual.empty?
|
63
|
+
a_path = tpath.split("/").reject { |x| x.empty? }
|
64
|
+
else
|
65
|
+
a_path = tpath.dirname.split("/").reject { |x| x.empty? }
|
66
|
+
end
|
67
|
+
@location = a_path.shift
|
68
|
+
if @actual.clop
|
69
|
+
@params = @actual.clop
|
70
|
+
@actual = @actual.clip
|
71
|
+
end
|
72
|
+
a_path = [] if (@actual =~ (/^\//))
|
73
|
+
b_path = @actual.split("/").reject { |x| x.empty? }
|
74
|
+
a_path.pop if (a_path[-1] =~ /^\?/).kind_of?(Fixnum) && !b_path.empty?
|
75
|
+
c_path = (a_path + @actual.split("/").reject { |x| x.empty? }).flatten
|
76
|
+
d_path = []
|
77
|
+
c_path.each do |x|
|
78
|
+
(d_path.pop;next) if x == ".."
|
79
|
+
next if (x == "." || x =~ /^\?/)
|
80
|
+
d_path << x
|
81
|
+
end
|
82
|
+
return d_path
|
83
|
+
end
|
84
|
+
|
85
|
+
def has_proto?
|
86
|
+
begin
|
87
|
+
return true if HANDLERS.include?(@actual.split(":").first.downcase.to_sym)
|
88
|
+
rescue
|
89
|
+
return false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_s
|
94
|
+
return "#{@proto}://#{@location}/#{rpath}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class String
|
100
|
+
def has_ext? #:nodoc:
|
101
|
+
return false if self.basename.split(".",2)[1].empty?
|
102
|
+
return true
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'htmlentities'
|
5
|
+
require 'wwmd/viewstate/viewstate_utils'
|
6
|
+
module WWMD
|
7
|
+
class ViewState
|
8
|
+
include ViewStateUtils
|
9
|
+
end
|
10
|
+
end
|
11
|
+
require 'wwmd/class_extensions'
|
12
|
+
require 'wwmd/viewstate/viewstate'
|
13
|
+
require 'wwmd/viewstate/viewstate_types'
|
14
|
+
require 'wwmd/viewstate/viewstate_yaml'
|
15
|
+
require 'wwmd/viewstate/viewstate_deserializer_methods'
|
16
|
+
require 'wwmd/viewstate/viewstate_from_xml'
|
17
|
+
require 'wwmd/viewstate/vs_stubs'
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module WWMD
|
2
|
+
class ViewState
|
3
|
+
attr_accessor :b64
|
4
|
+
attr_accessor :obj_queue
|
5
|
+
attr_accessor :mac
|
6
|
+
attr_accessor :debug
|
7
|
+
attr_reader :raw
|
8
|
+
attr_reader :stack
|
9
|
+
attr_reader :bufarr
|
10
|
+
attr_reader :magic
|
11
|
+
attr_reader :size
|
12
|
+
attr_reader :indexed_strings
|
13
|
+
attr_reader :last_offset
|
14
|
+
attr_reader :xml
|
15
|
+
attr_reader :ndoc
|
16
|
+
attr_reader :obj_counts
|
17
|
+
|
18
|
+
def initialize(b64=nil)
|
19
|
+
@b64 = b64
|
20
|
+
@raw = ""
|
21
|
+
@stack = ""
|
22
|
+
@obj_queue = []
|
23
|
+
@bufarr = []
|
24
|
+
@size = 0
|
25
|
+
@indexed_strings = []
|
26
|
+
@mac = nil
|
27
|
+
@debug = false
|
28
|
+
@obj_counts = {}
|
29
|
+
self.deserialize if b64
|
30
|
+
end
|
31
|
+
|
32
|
+
# mac_enabled?
|
33
|
+
def mac_enabled?
|
34
|
+
return !@mac.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
# deserialize
|
38
|
+
def deserialize(b64=nil)
|
39
|
+
@obj_queue = []
|
40
|
+
@b64 = b64 if b64
|
41
|
+
@raw = @b64.b64d
|
42
|
+
@bufarr = @raw.scan(/./m)
|
43
|
+
@size = @bufarr.size
|
44
|
+
raise "Invalid ViewState" if not self.magic?
|
45
|
+
@obj_queue << self.deserialize_value
|
46
|
+
if @bufarr.size == 20 then
|
47
|
+
@mac = @bufarr.slice!(0..19).join("")
|
48
|
+
dlog(0x00,"MAC = #{@mac.hexify}")
|
49
|
+
end
|
50
|
+
raise "Error Parsing Viewstate (left: #{@bufarr.size})" if not @bufarr.size == 0
|
51
|
+
return !self.raw.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def serialize(objs=nil,version=2)
|
55
|
+
@obj_queue = objs if objs
|
56
|
+
@stack << "\xFF\x01"
|
57
|
+
@stack << @obj_queue.first.serialize
|
58
|
+
@stack << @mac if @mac
|
59
|
+
return !self.stack.nil?
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_xml
|
63
|
+
@xml = REXML::Document.new()
|
64
|
+
header = REXML::Element.new("ViewState")
|
65
|
+
header.add_attribute("version", @magic.b64e)
|
66
|
+
header.add_attribute("version_string", @magic.hexify)
|
67
|
+
header.add_element(@obj_queue.first.to_xml)
|
68
|
+
if self.mac_enabled?
|
69
|
+
max = REXML::Element.new("Mac")
|
70
|
+
max.add_attribute("encoding","hexify")
|
71
|
+
max.add_text(@mac.hexify)
|
72
|
+
header.add_element(max)
|
73
|
+
end
|
74
|
+
@xml.add_element(header)
|
75
|
+
@ndoc = Nokogiri::XML.parse(@xml.to_s)
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
# xpath search the nokogiri doc if we have one
|
80
|
+
def search(*args)
|
81
|
+
return "No XML" if !@ndoc
|
82
|
+
@ndoc.search(*args)
|
83
|
+
end
|
84
|
+
|
85
|
+
# move pp due to to_xml returning self
|
86
|
+
# this is all for the sake of getting #search to work
|
87
|
+
def pp(*args)
|
88
|
+
return "Undefined" if !@xml
|
89
|
+
@xml.pp(*args)
|
90
|
+
end
|
91
|
+
|
92
|
+
def from_yaml(yaml)
|
93
|
+
@obj_queue = YAML.load(yaml)
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_yaml
|
97
|
+
@obj_queue.to_yaml
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module WWMD
|
2
|
+
class ViewState
|
3
|
+
# complex types
|
4
|
+
def pair(t=nil)
|
5
|
+
dlog t,"next = #{next_type}"
|
6
|
+
VSStubs::VSPair.new(self.deserialize_value,self.deserialize_value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def triplet(t=nil)
|
10
|
+
dlog t,"next = #{next_type}"
|
11
|
+
VSStubs::VSTriplet.new(self.deserialize_value,self.deserialize_value,self.deserialize_value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def type(t=nil)
|
15
|
+
typeref,typeval = self.deserialize_type
|
16
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval}")
|
17
|
+
VSStubs::VSType.new(typeref,typeval)
|
18
|
+
end
|
19
|
+
|
20
|
+
def string_formatted(t=nil)
|
21
|
+
typeref,typeval = self.deserialize_type
|
22
|
+
str = self.read_string
|
23
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} string = #{str}")
|
24
|
+
VSStubs::VSStringFormatted.new(typeref,typeval,str)
|
25
|
+
end
|
26
|
+
|
27
|
+
def int_enum(t=nil)
|
28
|
+
typeref,typeval = self.deserialize_type
|
29
|
+
index = self.read_7bit_encoded_int
|
30
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} index = #{index}")
|
31
|
+
VSStubs::VSIntEnum.new(typeref,typeval,index)
|
32
|
+
end
|
33
|
+
|
34
|
+
def binary_serialized(t=nil)
|
35
|
+
count = self.read_7bit_encoded_int
|
36
|
+
dlog(t,count)
|
37
|
+
bin = self.read(count)
|
38
|
+
me = VSStubs::VSBinarySerialized.new()
|
39
|
+
me.set(bin)
|
40
|
+
return me
|
41
|
+
end
|
42
|
+
|
43
|
+
def sparse_array(t=nil)
|
44
|
+
typeref,typeval = self.deserialize_type
|
45
|
+
size = read_7bit_encoded_int
|
46
|
+
elems = read_7bit_encoded_int
|
47
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} size = #{size} elems = #{elems}")
|
48
|
+
me = VSStubs::VSSparseArray.new(typeref,typeval,size,elems)
|
49
|
+
if elems > size
|
50
|
+
raise "Invalid sparse_array"
|
51
|
+
end
|
52
|
+
(1..elems).each do |i|
|
53
|
+
idx = read_7bit_encoded_int
|
54
|
+
me.add(idx,self.deserialize_value)
|
55
|
+
end
|
56
|
+
return me
|
57
|
+
end
|
58
|
+
|
59
|
+
def hashtable(t=nil)
|
60
|
+
len = read_7bit_encoded_int
|
61
|
+
dlog(t,"len = #{len}")
|
62
|
+
me = VSStubs::VSHashtable.new()
|
63
|
+
(1..len).each do |i|
|
64
|
+
me.add(self.deserialize_value,self.deserialize_value)
|
65
|
+
end
|
66
|
+
return me
|
67
|
+
end
|
68
|
+
|
69
|
+
def hybrid_dict(t=nil)
|
70
|
+
len = read_7bit_encoded_int
|
71
|
+
dlog(t,"len = #{len}")
|
72
|
+
me = VSStubs::VSHybridDict.new()
|
73
|
+
(1..len).each do |i|
|
74
|
+
me.add(self.deserialize_value,self.deserialize_value)
|
75
|
+
end
|
76
|
+
return me
|
77
|
+
end
|
78
|
+
|
79
|
+
def array(t=nil)
|
80
|
+
typeref,typeval = self.deserialize_type
|
81
|
+
len = read_7bit_encoded_int
|
82
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} len = #{len}")
|
83
|
+
me = VSStubs::VSArray.new(typeref,typeval)
|
84
|
+
(1..len).each do |i|
|
85
|
+
me.add(self.deserialize_value)
|
86
|
+
end
|
87
|
+
return me
|
88
|
+
end
|
89
|
+
|
90
|
+
def string_array(t=nil)
|
91
|
+
len = read_7bit_encoded_int
|
92
|
+
dlog(t,"len = #{len}")
|
93
|
+
me = VSStubs::VSStringArray.new()
|
94
|
+
(1..len).each do |i|
|
95
|
+
str = self.read_string
|
96
|
+
me.add(str)
|
97
|
+
dlog(t,"string_array_elem: #{str}")
|
98
|
+
end
|
99
|
+
return me
|
100
|
+
end
|
101
|
+
|
102
|
+
def list(t=nil)
|
103
|
+
len = read_7bit_encoded_int
|
104
|
+
dlog(t,"len = #{len}")
|
105
|
+
me = VSStubs::VSList.new()
|
106
|
+
(1..len).each do |i|
|
107
|
+
me.add(self.deserialize_value)
|
108
|
+
end
|
109
|
+
return me
|
110
|
+
end
|
111
|
+
|
112
|
+
def unit(t=nil)
|
113
|
+
s1 = read_double
|
114
|
+
s2 = read_int32
|
115
|
+
dlog(t,"#{s1.to_s(16).rjust(16,"0")},#{s2.to_s(16).rjust(8,"0")}")
|
116
|
+
VSStubs::VSUnit.new(s1,s2)
|
117
|
+
end
|
118
|
+
|
119
|
+
def indexed_string(t=nil)
|
120
|
+
str = self.read_string
|
121
|
+
@indexed_strings << str
|
122
|
+
dlog(t,"idx = #{@indexed_strings.size - 1} val = #{str}")
|
123
|
+
VSStubs::VSIndexedString.new(str)
|
124
|
+
end
|
125
|
+
|
126
|
+
def indexed_string_ref(t=nil)
|
127
|
+
ref = self.read_int
|
128
|
+
dlog(t,"ref = #{ref} val = #{@indexed_strings[ref]}")
|
129
|
+
VSStubs::VSIndexedStringRef.new(ref)
|
130
|
+
end
|
131
|
+
|
132
|
+
def string(t=nil)
|
133
|
+
str = self.read_string
|
134
|
+
dlog(t,str)
|
135
|
+
VSStubs::VSString.new(str)
|
136
|
+
end
|
137
|
+
|
138
|
+
# VSStubs::VSReadValue types
|
139
|
+
def color(t=nil)
|
140
|
+
val = self.read_int32
|
141
|
+
dlog(t,val.to_s(16))
|
142
|
+
VSStubs::VSColor.new(val)
|
143
|
+
end
|
144
|
+
|
145
|
+
def known_color(t=nil)
|
146
|
+
index = self.read_7bit_encoded_int
|
147
|
+
dlog(t,"index = #{index.to_s(16)}")
|
148
|
+
VSStubs::VSKnownColor.new(index)
|
149
|
+
end
|
150
|
+
|
151
|
+
def int16(t=nil)
|
152
|
+
val = read_short
|
153
|
+
dlog(t,val)
|
154
|
+
VSStubs::VSInt16.new(val)
|
155
|
+
end
|
156
|
+
|
157
|
+
def int32(t=nil)
|
158
|
+
val = self.read_7bit_encoded_int
|
159
|
+
dlog(t,val)
|
160
|
+
VSStubs::VSInt32.new(val)
|
161
|
+
end
|
162
|
+
|
163
|
+
def byte(t=nil)
|
164
|
+
val = self.read_byte
|
165
|
+
dlog(t,val)
|
166
|
+
VSStubs::VSByte.new(val)
|
167
|
+
end
|
168
|
+
|
169
|
+
def char(t=nil)
|
170
|
+
val = self.read_byte
|
171
|
+
dlog(t,val)
|
172
|
+
VSStubs::VSChar.new(val)
|
173
|
+
end
|
174
|
+
|
175
|
+
def date_time(t=nil)
|
176
|
+
val = self.read_double
|
177
|
+
dlog(t,val)
|
178
|
+
VSStubs::VSDateTime.new(val)
|
179
|
+
end
|
180
|
+
|
181
|
+
def double(t=nil)
|
182
|
+
val = self.read_double
|
183
|
+
dlog(t,val)
|
184
|
+
VSStubs::VSDouble.new(val)
|
185
|
+
end
|
186
|
+
|
187
|
+
def single(t=nil)
|
188
|
+
val = self.read_single
|
189
|
+
dlog(t,val)
|
190
|
+
VSStubs::VSSingle.new(val)
|
191
|
+
end
|
192
|
+
|
193
|
+
# VSStubs::VSValue types
|
194
|
+
def null(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
195
|
+
def empty_byte(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
196
|
+
def zeroint32(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
197
|
+
def bool_true(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
198
|
+
def bool_false(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
199
|
+
def empty_color(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
200
|
+
def empty_unit(t=nil); dlog(t,nil); return VSStubs::VSValue.new(t); end
|
201
|
+
|
202
|
+
# deserialize_value
|
203
|
+
def deserialize_value
|
204
|
+
@last_offset = self.offset
|
205
|
+
token = self.read_byte # self.read_raw_byte
|
206
|
+
if not (tsym = VIEWSTATE_TYPES[token])
|
207
|
+
STDERR.puts "TOKEN: [0x#{token.to_s(16)}] at #{last_offset}"
|
208
|
+
STDERR.puts @bufarr.slice(0..31).join("").hexdump
|
209
|
+
raise "Invalid Type [0x#{token.to_s(16)}] at #{last_offset}" if not (tsym = VIEWSTATE_TYPES[token])
|
210
|
+
end
|
211
|
+
nobj = self.send(tsym,token)
|
212
|
+
raise "Invalid Class Returned #{nobj.class}" if not VIEWSTATE_TYPES.include?(nobj.opcode)
|
213
|
+
return nobj
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module WWMD
|
2
|
+
class ViewState
|
3
|
+
# directly serialize into stack from received xml (the easy way)
|
4
|
+
# this is pretty silly but it didn't take me very long so...
|
5
|
+
|
6
|
+
attr_reader :xmlstack
|
7
|
+
|
8
|
+
def get_sym(str)
|
9
|
+
str.split(":").last.gsub(/[A-Z]+/,'\1_\0').downcase[1..-1].gsub(/\Avs/,"").to_sym
|
10
|
+
end
|
11
|
+
|
12
|
+
def opcode(name,val)
|
13
|
+
sym = get_sym(name)
|
14
|
+
if sym == :value
|
15
|
+
ret = VIEWSTATE_TYPES.index(val.to_sym)
|
16
|
+
else
|
17
|
+
ret = VIEWSTATE_TYPES.index(sym)
|
18
|
+
end
|
19
|
+
ret
|
20
|
+
end
|
21
|
+
|
22
|
+
def serialize_hashtable(node)
|
23
|
+
tstack = ""
|
24
|
+
tstack << self.write_7bit_encoded_int(node['size'].to_i)
|
25
|
+
node.children.each do |c|
|
26
|
+
next if c.text?
|
27
|
+
raise "Invalid Hashtable: got #{c.name}" if not c.name == "Pair"
|
28
|
+
end
|
29
|
+
tstack
|
30
|
+
end
|
31
|
+
|
32
|
+
def decode_text(node)
|
33
|
+
case node['encoding']
|
34
|
+
when "urlencoded"
|
35
|
+
node.inner_text.unescape
|
36
|
+
when "quoted-printable"
|
37
|
+
node.inner_text.from_qp
|
38
|
+
when "base64"
|
39
|
+
node.inner_text.b64d
|
40
|
+
when "hexify"
|
41
|
+
node.inner_text.dehexify
|
42
|
+
else
|
43
|
+
node.inner_text
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def write_node(node)
|
48
|
+
return false if node.text?
|
49
|
+
tstack = ""
|
50
|
+
# this is a hack to get sparse_array to work
|
51
|
+
return false if ["Pair","Key","Value"].include?(node.name) # skip and fall through
|
52
|
+
if ["Index","Size","Elements"].include?(node.name)
|
53
|
+
@xmlstack << self.write_7bit_encoded_int(node.inner_text.to_i)
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
if node.name == "Mac"
|
57
|
+
@xmlstack << decode_text(node)
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
# end hack
|
61
|
+
flag = true # begin; sillyness; rescue => me; end
|
62
|
+
case get_sym(node.name)
|
63
|
+
when :pair, :triplet, :value, :sparse_array, :type, :string_formatted
|
64
|
+
when :int_enum, :known_color, :int32
|
65
|
+
tstack << self.write_7bit_encoded_int(node.inner_text.to_i)
|
66
|
+
when :int16
|
67
|
+
tstack << self.write_short(node.inner_text.to_i)
|
68
|
+
when :byte, :char, :indexed_string_ref
|
69
|
+
tstack << self.write_byte(node.inner_text.to_i)
|
70
|
+
when :color, :single
|
71
|
+
tstack << self.write_int32(node.inner_text.to_i)
|
72
|
+
when :double, :date_time
|
73
|
+
tstack << self.write_double(node.inner_text.to_i)
|
74
|
+
when :unit
|
75
|
+
tstack << self.write_double(node['dword'].to_i)
|
76
|
+
tstack << self.write_single(node['word'].to_i)
|
77
|
+
when :list, :string_array, :array
|
78
|
+
tstack << self.write_7bit_encoded_int(node['size'].to_i)
|
79
|
+
when :string, :indexed_string, :binary_serialized
|
80
|
+
flag = false if ([:string_array,:string_formatted].include?(get_sym(node.parent.name)))
|
81
|
+
# get encoding
|
82
|
+
str = decode_text(node)
|
83
|
+
tstack << self.write_7bit_encoded_int(str.size)
|
84
|
+
tstack << str
|
85
|
+
when :hashtable, :hybrid_dict
|
86
|
+
tstack << serialize_hashtable(node)
|
87
|
+
else
|
88
|
+
raise "Invalid Node:\n#{node.name}"
|
89
|
+
end
|
90
|
+
|
91
|
+
# [flag] is a hack to get around string_array and string_formatted emitting opcodes
|
92
|
+
@xmlstack << self.write_byte(opcode(node.name,node.inner_text)) if flag
|
93
|
+
if node.has_attribute?("typeref")
|
94
|
+
if node['typeref'].to_i == 0x2b
|
95
|
+
@xmlstack << self.serialize_type(node['typeref'].to_i,node['typeval'].to_i)
|
96
|
+
else
|
97
|
+
@xmlstack << self.serialize_type(node['typeref'].to_i,node['typeval'])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
@xmlstack << tstack
|
101
|
+
end
|
102
|
+
|
103
|
+
def serialize_xml(node)
|
104
|
+
begin
|
105
|
+
write_node(node)
|
106
|
+
rescue => e
|
107
|
+
STDERR.puts "ERROR parsing node:\n#{node.to_s}"
|
108
|
+
raise e
|
109
|
+
end
|
110
|
+
node.children.each do |c|
|
111
|
+
serialize_xml(c)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def from_xml(xml)
|
116
|
+
@xmlstack = ""
|
117
|
+
doc = Nokogiri::XML.parse(xml)
|
118
|
+
root = doc.root
|
119
|
+
raise "Invalid ViewState Version" if not root.has_attribute?("version")
|
120
|
+
@xmlstack << root['version'].b64d
|
121
|
+
root.children.each do |c|
|
122
|
+
serialize_xml(c)
|
123
|
+
end
|
124
|
+
self.deserialize(@xmlstack.b64e)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|