Skip to content

Commit d1808fa

Browse files
committed
Merge branch 'master' of ../metasploit-framework-creating-ole-gem
2 parents 87d99c1 + 25bed41 commit d1808fa

File tree

6 files changed

+1615
-0
lines changed

6 files changed

+1615
-0
lines changed

spec/rex/ole/clsid_spec.rb

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# -*- coding:binary -*-
2+
require 'spec_helper'
3+
4+
require 'rex/ole'
5+
6+
RSpec.describe Rex::OLE::CLSID do
7+
before(:example) do
8+
Rex::OLE::Util.set_endian(Rex::OLE::LITTLE_ENDIAN)
9+
end
10+
11+
let(:sample_clsid) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" }
12+
13+
subject(:clsid) do
14+
described_class.new(sample_clsid)
15+
end
16+
17+
describe "#initialize" do
18+
subject(:clsid_class) do
19+
described_class.allocate
20+
end
21+
22+
it "returns the buf value" do
23+
expect(clsid_class.send(:initialize, sample_clsid)).to eq(sample_clsid)
24+
end
25+
26+
context "when buf is nil" do
27+
it "returns padding" do
28+
expect(clsid_class.send(:initialize)).to eq("\x00" * 16)
29+
end
30+
end
31+
end
32+
33+
describe "#pack" do
34+
it "returns the buf field" do
35+
expect(clsid.pack).to eq(sample_clsid)
36+
end
37+
end
38+
39+
describe "#to_s" do
40+
it "returns printable clsid" do
41+
expect(clsid.to_s).to eq('33221100-5544-7766-8899-aabbccddeeff')
42+
end
43+
44+
context "when buf is nil" do
45+
it "raises NoMethodError" do
46+
clsid.instance_variable_set(:@buf, nil)
47+
expect { clsid.to_s }.to raise_error(NoMethodError)
48+
end
49+
end
50+
51+
context "when buf is shorter than 16 bytes" do
52+
it "raises TypeError" do
53+
clsid.instance_variable_set(:@buf, '')
54+
expect { clsid.to_s }.to raise_error(TypeError)
55+
end
56+
end
57+
end
58+
end

spec/rex/ole/difat_spec.rb

+294
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# -*- coding:binary -*-
2+
require 'spec_helper'
3+
4+
require 'rex/ole'
5+
6+
RSpec.describe Rex::OLE::DIFAT do
7+
before(:example) do
8+
Rex::OLE::Util.set_endian(Rex::OLE::LITTLE_ENDIAN)
9+
end
10+
11+
let(:storage) do
12+
Rex::OLE::Storage.new
13+
end
14+
15+
subject(:difat) do
16+
described_class.new(storage)
17+
end
18+
19+
describe ".new" do
20+
it "returns a Rex::OLE::DIFAT instance" do
21+
expect(described_class.new(storage)).to be_a(Rex::OLE::DIFAT)
22+
end
23+
24+
it "initializes @stg" do
25+
expect(difat.instance_variable_get(:@stg)).to eq(storage)
26+
end
27+
28+
it "initializes @entries" do
29+
expect(difat.instance_variable_get(:@entries)).to be_an(Array)
30+
end
31+
32+
it "initializes @entries as empty array" do
33+
expect(difat.instance_variable_get(:@entries)).to be_empty
34+
end
35+
end
36+
37+
describe "#[]=" do
38+
context "when the entry doesn't exist" do
39+
it "sets an element in the @entries array" do
40+
difat[0] = 1
41+
expect(difat.instance_variable_get(:@entries)[0]).to eq(1)
42+
end
43+
end
44+
45+
context "when the entry exists" do
46+
it "replaces the element in the @entries array" do
47+
difat[0] = 1
48+
difat[0] = 2
49+
expect(difat.instance_variable_get(:@entries)[0]).to eq(2)
50+
end
51+
end
52+
end
53+
54+
describe "#[]" do
55+
context "when the entry doesn't exist" do
56+
it "returns nil" do
57+
expect(difat[3]).to eq(nil)
58+
end
59+
end
60+
61+
context "when the entry exists" do
62+
it "returns the entry value" do
63+
difat[3] = 31
64+
expect(difat[3]).to eq(31)
65+
end
66+
end
67+
end
68+
69+
70+
describe "#+" do
71+
context "when @entries is empty" do
72+
it "sets the @entries values" do
73+
difat + [1, 2]
74+
expect(difat.instance_variable_get(:@entries)).to eq([1, 2])
75+
end
76+
end
77+
78+
context "when @entries isn't empty" do
79+
it "concatenates the array to @entries" do
80+
difat[2] = 0
81+
difat + [1, 2]
82+
expect(difat.instance_variable_get(:@entries)).to eq([nil, nil, 0, 1, 2])
83+
end
84+
end
85+
end
86+
87+
describe "#<<" do
88+
it "concatenates the element to the @entries array" do
89+
difat[0] = 1
90+
difat << 3
91+
expect(difat.instance_variable_get(:@entries)).to eq([1, 3])
92+
end
93+
end
94+
95+
describe "#length" do
96+
subject(:difat_length) do
97+
difat.length
98+
end
99+
100+
context "when @entries is empty" do
101+
it "returns 0" do
102+
is_expected.to eq(0)
103+
end
104+
end
105+
106+
context "when @entries isn't empty" do
107+
it "returns the @entries length" do
108+
difat[0] = 1
109+
difat[1] = 2
110+
is_expected.to eq(2)
111+
end
112+
end
113+
end
114+
115+
describe "#slice!" do
116+
context "when @entries is empty" do
117+
it "returns empty array" do
118+
expect(difat.slice!(0, 1)).to eq([])
119+
end
120+
end
121+
122+
context "when start is out of range" do
123+
it "returns nil" do
124+
difat[0] = 1
125+
expect(difat.slice!(10, 1)).to eq(nil)
126+
end
127+
end
128+
129+
context "when stop is 0" do
130+
it "returns empty array" do
131+
difat[0] = 1
132+
expect(difat.slice!(0, 0)).to eq([])
133+
end
134+
135+
it "doesn't delete nothing" do
136+
difat[0] = 1
137+
difat.slice!(0, 0)
138+
expect(difat[0]).to eq(1)
139+
end
140+
end
141+
142+
context "when @entries is long enough" do
143+
it "returns the deleted elements" do
144+
difat + [1, 2]
145+
expect(difat.slice!(0, 1)).to eq([1])
146+
end
147+
148+
it "deletes the elements in the range" do
149+
difat + [1, 2]
150+
difat.slice!(0, 1)
151+
expect(difat.instance_variable_get(:@entries)).to eq([2])
152+
end
153+
end
154+
end
155+
156+
describe "#reset" do
157+
it "resets the @entries array" do
158+
difat[0] = 1
159+
difat.reset
160+
expect(difat.length).to eq(0)
161+
end
162+
end
163+
164+
describe "#each" do
165+
it "calls the block for every @entries element" do
166+
difat + [1, 2, 3]
167+
res = 0
168+
difat.each { |elem| res += elem}
169+
expect(res).to eq(1 + 2 + 3)
170+
end
171+
end
172+
173+
describe "#to_s" do
174+
subject(:difat_string) do
175+
difat.to_s
176+
end
177+
178+
it "returns an String" do
179+
is_expected.to be_an(String)
180+
end
181+
182+
it "starts with {" do
183+
is_expected.to start_with('{')
184+
end
185+
186+
it "ends with }" do
187+
is_expected.to end_with('}')
188+
end
189+
190+
it "contains @entries values" do
191+
difat + [Rex::OLE::SECT_FAT, 1, 2, 3, Rex::OLE::SECT_DIF, Rex::OLE::SECT_FREE, Rex::OLE::SECT_END]
192+
is_expected.to match(/FAT, 0x1, 0x2, 0x3, DIF, FREE, END/)
193+
end
194+
end
195+
196+
describe "#read" do
197+
context "when difat is empty" do
198+
it "returns nil" do
199+
expect(difat.read).to be_nil
200+
end
201+
end
202+
end
203+
204+
describe "#write" do
205+
context "when entries is empty" do
206+
it "returns 0" do
207+
expect(difat.write).to eq(0)
208+
end
209+
210+
it "fills the first 109 FAT sectors in the storage header" do
211+
difat.write
212+
storage = difat.instance_variable_get(:@stg)
213+
expect(storage.header._sectFat.length).to eq(109)
214+
end
215+
216+
it "fills the first 109 FAT sectors in the storage header with SECT_FREE" do
217+
difat.write
218+
storage = difat.instance_variable_get(:@stg)
219+
storage.header._sectFat.each { |s|
220+
expect(s).to eq(Rex::OLE::SECT_FREE)
221+
}
222+
end
223+
end
224+
225+
context "when entries length is less than 109" do
226+
let(:entries) { [1] * 20 }
227+
228+
it "returns the number of entries" do
229+
difat + entries
230+
expect(difat.write).to eq(20)
231+
end
232+
233+
it "fills the first 109 FAT sectors in the storage header" do
234+
difat + entries
235+
difat.write
236+
storage = difat.instance_variable_get(:@stg)
237+
expect(storage.header._sectFat.length).to eq(109)
238+
end
239+
240+
it "fills the first FAT sectors with the entries" do
241+
difat + entries
242+
difat.write
243+
storage = difat.instance_variable_get(:@stg)
244+
(0..entries.length - 1).each { |i|
245+
expect(storage.header._sectFat[i]).to eq(1)
246+
}
247+
end
248+
249+
it "fills the remaining FAT sectors with FREE sectors" do
250+
difat + entries
251+
difat.write
252+
storage = difat.instance_variable_get(:@stg)
253+
(entries.length..109 - 1).each { |i|
254+
expect(storage.header._sectFat[i]).to eq(Rex::OLE::SECT_FREE)
255+
}
256+
end
257+
end
258+
259+
context "when entries length is 109" do
260+
let(:entries) { [1] * 109 }
261+
262+
it "returns the number of entries" do
263+
difat + entries
264+
expect(difat.write).to eq(109)
265+
end
266+
267+
it "fills the first 109 FAT sectors in the storage header" do
268+
difat + entries
269+
difat.write
270+
storage = difat.instance_variable_get(:@stg)
271+
expect(storage.header._sectFat.length).to eq(109)
272+
end
273+
274+
it "fills the first 109 FAT sectors with the entries" do
275+
difat + entries
276+
difat.write
277+
storage = difat.instance_variable_get(:@stg)
278+
(0..storage.header._sectFat.length - 1).each { |i|
279+
expect(storage.header._sectFat[i]).to eq(1)
280+
}
281+
end
282+
end
283+
284+
context "when entries length is greater than 109" do
285+
let(:entries) { [1] * 110 }
286+
287+
it "raises a RuntimeError" do
288+
difat + entries
289+
expect { difat.write }.to raise_error(RuntimeError)
290+
end
291+
end
292+
293+
end
294+
end

0 commit comments

Comments
 (0)