Skip to content

Commit 3f5fdae

Browse files
committed
Add specs for Rex::Encoder::NDR
1 parent 7d4c4c3 commit 3f5fdae

File tree

3 files changed

+226
-0
lines changed

3 files changed

+226
-0
lines changed

spec/lib/rex/encoder/ndr_spec.rb

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# -*- coding:binary -*-
2+
require 'spec_helper'
3+
4+
require 'rex/encoder/ndr'
5+
6+
describe Rex::Encoder::NDR do
7+
8+
describe ".align" do
9+
subject { described_class.align(string) }
10+
11+
context "when empty string argument" do
12+
let(:string) { "" }
13+
it { is_expected.to eq("") }
14+
end
15+
16+
context "when 32bit aligned length argument" do
17+
let(:string) { "A" * 4 }
18+
it { is_expected.to eq("") }
19+
end
20+
21+
context "when 32bit unaligned length argument" do
22+
let(:string) { "A" * 5 }
23+
it "returns the padding, as null bytes, necessary to 32bit align the argument" do
24+
is_expected.to eq("\x00\x00\x00")
25+
end
26+
end
27+
end
28+
29+
describe ".long" do
30+
subject { described_class.long(string) }
31+
let(:string) { 0x41424344 }
32+
33+
it "encodes the arguments as 32-bit little-endian unsigned integer" do
34+
is_expected.to eq("\x44\x43\x42\x41")
35+
end
36+
37+
context "when argument bigger than 32-bit unsigned integer" do
38+
let(:string) { 0x4142434445 }
39+
it "truncates the argument" do
40+
is_expected.to eq("\x45\x44\x43\x42")
41+
end
42+
end
43+
end
44+
45+
describe ".short" do
46+
subject { described_class.short(string) }
47+
let(:string) { 0x4142 }
48+
49+
it "encodes the arguments as 16-bit little-endian unsigned integer" do
50+
is_expected.to eq("\x42\x41")
51+
end
52+
53+
context "when argument bigger than 16-bit unsigned integer" do
54+
let(:string) { 0x41424344 }
55+
it "truncates the argument" do
56+
is_expected.to eq("\x44\x43")
57+
end
58+
end
59+
60+
end
61+
62+
describe ".byte" do
63+
subject { described_class.byte(string) }
64+
let(:string) { 0x41 }
65+
66+
it "encodes the arguments as 8-bit unsigned integer" do
67+
is_expected.to eq("\x41")
68+
end
69+
70+
context "when argument bigger than 8-bit unsigned integer" do
71+
let(:string) { 0x4142 }
72+
it "truncates the argument" do
73+
is_expected.to eq("\x42")
74+
end
75+
end
76+
77+
end
78+
79+
describe ".UniConformantArray" do
80+
subject { described_class.UniConformantArray(string) }
81+
let(:string) { "ABCDE" }
82+
83+
it "returns the encoded string" do
84+
is_expected.to be_kind_of(String)
85+
end
86+
87+
it "starts encoding the string length as 32-bit little-endian unsigned integer" do
88+
expect(subject.unpack("V").first).to eq(string.length)
89+
end
90+
91+
it "adds the string argument" do
92+
is_expected.to include(string)
93+
end
94+
95+
it "ends with padding to make result length 32-bits aligned" do
96+
is_expected.to end_with("\x00" * 3)
97+
end
98+
end
99+
100+
describe ".string" do
101+
subject { described_class.string(string) }
102+
let(:string) { "ABCD" }
103+
104+
it "returns the encoded string" do
105+
is_expected.to be_kind_of(String)
106+
expect(subject.length).to eq(20)
107+
end
108+
109+
it "starts encoding string metadata" do
110+
expect(subject.unpack("VVV")[0]).to eq(string.length)
111+
expect(subject.unpack("VVV")[1]).to eq(0)
112+
expect(subject.unpack("VVV")[2]).to eq(string.length)
113+
end
114+
115+
it "adds the string argument null-byte terminated" do
116+
is_expected.to include("ABCD\x00")
117+
end
118+
119+
it "ends with padding to make result length 32-bits aligned" do
120+
is_expected.to end_with("\x00" * 3)
121+
end
122+
end
123+
124+
describe ".wstring" do
125+
subject { described_class.wstring(string) }
126+
127+
it_behaves_like "Rex::Encoder::NDR.wstring"
128+
end
129+
130+
describe ".UnicodeConformantVaryingString" do
131+
subject { described_class.UnicodeConformantVaryingString(string) }
132+
133+
it_behaves_like "Rex::Encoder::NDR.wstring"
134+
end
135+
136+
describe ".uwstring" do
137+
subject { described_class.uwstring(string) }
138+
139+
let(:string) { "ABCD" }
140+
141+
it "encodes the argument as null-terminated unicode string" do
142+
is_expected.to include("A\x00B\x00C\x00D\x00\x00\x00")
143+
end
144+
145+
it "starts encoding string metadata" do
146+
expect(subject.unpack("VVVV")[1]).to eq(string.length + 1)
147+
expect(subject.unpack("VVVV")[2]).to eq(0)
148+
expect(subject.unpack("VVVV")[3]).to eq(string.length + 1)
149+
end
150+
151+
it "ends with padding to make result length 32-bits aligned" do
152+
is_expected.to end_with("\x00" * 2)
153+
expect(subject.length).to eq(28)
154+
end
155+
end
156+
157+
describe ".wstring_prebuilt" do
158+
subject { described_class.wstring_prebuilt(string) }
159+
160+
it_behaves_like "Rex::Encoder::NDR.wstring_prebuild"
161+
end
162+
163+
describe ".UnicodeConformantVaryingStringPreBuilt" do
164+
subject { described_class.UnicodeConformantVaryingStringPreBuilt(string) }
165+
166+
it_behaves_like "Rex::Encoder::NDR.wstring_prebuild"
167+
end
168+
169+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
shared_examples_for "Rex::Encoder::NDR.wstring" do
2+
let(:string) { "ABCD" }
3+
4+
it "encodes the argument as null-terminated unicode string" do
5+
is_expected.to include("A\x00B\x00C\x00D\x00\x00\x00")
6+
end
7+
8+
it "starts encoding string metadata" do
9+
expect(subject.unpack("VVV")[0]).to eq(string.length + 1)
10+
expect(subject.unpack("VVV")[1]).to eq(0)
11+
expect(subject.unpack("VVV")[2]).to eq(string.length + 1)
12+
end
13+
14+
it "ends with padding to make result length 32-bits aligned" do
15+
is_expected.to end_with("\x00" * 2)
16+
expect(subject.length).to eq(24)
17+
end
18+
end
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
shared_examples_for "Rex::Encoder::NDR.wstring_prebuild" do
2+
context "when 2-byte aligned string length" do
3+
let(:string) { "A\x00B\x00C\x00" }
4+
5+
it "encodes the argument as null-terminated unicode string" do
6+
is_expected.to include("A\x00B\x00C\x00")
7+
end
8+
9+
it "starts encoding string metadata" do
10+
expect(subject.unpack("VVV")[0]).to eq(string.length / 2)
11+
expect(subject.unpack("VVV")[1]).to eq(0)
12+
expect(subject.unpack("VVV")[2]).to eq(string.length / 2)
13+
end
14+
15+
it "ends with padding to make result length 32-bits aligned" do
16+
is_expected.to end_with("\x00" * 2)
17+
expect(subject.length).to eq(20)
18+
end
19+
end
20+
21+
context "when 2-byte unaligned string length" do
22+
let(:string) { "A\x00B\x00C" }
23+
24+
it "encodes the argument as null-terminated unicode string" do
25+
is_expected.to include("A\x00B\x00C\x00")
26+
end
27+
28+
it "starts encoding string metadata" do
29+
expect(subject.unpack("VVV")[0]).to eq((string.length + 1) / 2)
30+
expect(subject.unpack("VVV")[1]).to eq(0)
31+
expect(subject.unpack("VVV")[2]).to eq((string.length + 1) / 2)
32+
end
33+
34+
it "ends with padding to make result length 32-bits aligned" do
35+
is_expected.to end_with("\x00" * 2)
36+
expect(subject.length).to eq(20)
37+
end
38+
end
39+
end

0 commit comments

Comments
 (0)