170 lines
4.4 KiB
Ruby
170 lines
4.4 KiB
Ruby
|
# -*- coding:binary -*-
|
||
|
require 'spec_helper'
|
||
|
|
||
|
require 'rex/encoder/ndr'
|
||
|
|
||
|
describe Rex::Encoder::NDR do
|
||
|
|
||
|
describe ".align" do
|
||
|
subject { described_class.align(string) }
|
||
|
|
||
|
context "when empty string argument" do
|
||
|
let(:string) { "" }
|
||
|
it { is_expected.to eq("") }
|
||
|
end
|
||
|
|
||
|
context "when 32bit aligned length argument" do
|
||
|
let(:string) { "A" * 4 }
|
||
|
it { is_expected.to eq("") }
|
||
|
end
|
||
|
|
||
|
context "when 32bit unaligned length argument" do
|
||
|
let(:string) { "A" * 5 }
|
||
|
it "returns the padding, as null bytes, necessary to 32bit align the argument" do
|
||
|
is_expected.to eq("\x00\x00\x00")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe ".long" do
|
||
|
subject { described_class.long(string) }
|
||
|
let(:string) { 0x41424344 }
|
||
|
|
||
|
it "encodes the arguments as 32-bit little-endian unsigned integer" do
|
||
|
is_expected.to eq("\x44\x43\x42\x41")
|
||
|
end
|
||
|
|
||
|
context "when argument bigger than 32-bit unsigned integer" do
|
||
|
let(:string) { 0x4142434445 }
|
||
|
it "truncates the argument" do
|
||
|
is_expected.to eq("\x45\x44\x43\x42")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe ".short" do
|
||
|
subject { described_class.short(string) }
|
||
|
let(:string) { 0x4142 }
|
||
|
|
||
|
it "encodes the arguments as 16-bit little-endian unsigned integer" do
|
||
|
is_expected.to eq("\x42\x41")
|
||
|
end
|
||
|
|
||
|
context "when argument bigger than 16-bit unsigned integer" do
|
||
|
let(:string) { 0x41424344 }
|
||
|
it "truncates the argument" do
|
||
|
is_expected.to eq("\x44\x43")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
describe ".byte" do
|
||
|
subject { described_class.byte(string) }
|
||
|
let(:string) { 0x41 }
|
||
|
|
||
|
it "encodes the arguments as 8-bit unsigned integer" do
|
||
|
is_expected.to eq("\x41")
|
||
|
end
|
||
|
|
||
|
context "when argument bigger than 8-bit unsigned integer" do
|
||
|
let(:string) { 0x4142 }
|
||
|
it "truncates the argument" do
|
||
|
is_expected.to eq("\x42")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
describe ".UniConformantArray" do
|
||
|
subject { described_class.UniConformantArray(string) }
|
||
|
let(:string) { "ABCDE" }
|
||
|
|
||
|
it "returns the encoded string" do
|
||
|
is_expected.to be_kind_of(String)
|
||
|
end
|
||
|
|
||
|
it "starts encoding the string length as 32-bit little-endian unsigned integer" do
|
||
|
expect(subject.unpack("V").first).to eq(string.length)
|
||
|
end
|
||
|
|
||
|
it "adds the string argument" do
|
||
|
is_expected.to include(string)
|
||
|
end
|
||
|
|
||
|
it "ends with padding to make result length 32-bits aligned" do
|
||
|
is_expected.to end_with("\x00" * 3)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe ".string" do
|
||
|
subject { described_class.string(string) }
|
||
|
let(:string) { "ABCD" }
|
||
|
|
||
|
it "returns the encoded string" do
|
||
|
is_expected.to be_kind_of(String)
|
||
|
expect(subject.length).to eq(20)
|
||
|
end
|
||
|
|
||
|
it "starts encoding string metadata" do
|
||
|
expect(subject.unpack("VVV")[0]).to eq(string.length)
|
||
|
expect(subject.unpack("VVV")[1]).to eq(0)
|
||
|
expect(subject.unpack("VVV")[2]).to eq(string.length)
|
||
|
end
|
||
|
|
||
|
it "adds the string argument null-byte terminated" do
|
||
|
is_expected.to include("ABCD\x00")
|
||
|
end
|
||
|
|
||
|
it "ends with padding to make result length 32-bits aligned" do
|
||
|
is_expected.to end_with("\x00" * 3)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe ".wstring" do
|
||
|
subject { described_class.wstring(string) }
|
||
|
|
||
|
it_behaves_like "Rex::Encoder::NDR.wstring"
|
||
|
end
|
||
|
|
||
|
describe ".UnicodeConformantVaryingString" do
|
||
|
subject { described_class.UnicodeConformantVaryingString(string) }
|
||
|
|
||
|
it_behaves_like "Rex::Encoder::NDR.wstring"
|
||
|
end
|
||
|
|
||
|
describe ".uwstring" do
|
||
|
subject { described_class.uwstring(string) }
|
||
|
|
||
|
let(:string) { "ABCD" }
|
||
|
|
||
|
it "encodes the argument as null-terminated unicode string" do
|
||
|
is_expected.to include("A\x00B\x00C\x00D\x00\x00\x00")
|
||
|
end
|
||
|
|
||
|
it "starts encoding string metadata" do
|
||
|
expect(subject.unpack("VVVV")[1]).to eq(string.length + 1)
|
||
|
expect(subject.unpack("VVVV")[2]).to eq(0)
|
||
|
expect(subject.unpack("VVVV")[3]).to eq(string.length + 1)
|
||
|
end
|
||
|
|
||
|
it "ends with padding to make result length 32-bits aligned" do
|
||
|
is_expected.to end_with("\x00" * 2)
|
||
|
expect(subject.length).to eq(28)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe ".wstring_prebuilt" do
|
||
|
subject { described_class.wstring_prebuilt(string) }
|
||
|
|
||
|
it_behaves_like "Rex::Encoder::NDR.wstring_prebuild"
|
||
|
end
|
||
|
|
||
|
describe ".UnicodeConformantVaryingStringPreBuilt" do
|
||
|
subject { described_class.UnicodeConformantVaryingStringPreBuilt(string) }
|
||
|
|
||
|
it_behaves_like "Rex::Encoder::NDR.wstring_prebuild"
|
||
|
end
|
||
|
|
||
|
end
|