Land #4008, OLE specs
commit
8e58efbf4f
|
@ -0,0 +1,56 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/ole'
|
||||
|
||||
describe Rex::OLE::CLSID do
|
||||
|
||||
let(:sample_clsid) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" }
|
||||
|
||||
subject(:clsid) do
|
||||
described_class.new(sample_clsid)
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
subject(:clsid_class) do
|
||||
described_class.allocate
|
||||
end
|
||||
|
||||
it "returns the buf value" do
|
||||
expect(clsid_class.send(:initialize, sample_clsid)).to eq(sample_clsid)
|
||||
end
|
||||
|
||||
context "when buf is nil" do
|
||||
it "returns padding" do
|
||||
expect(clsid_class.send(:initialize)).to eq("\x00" * 16)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pack" do
|
||||
it "returns the buf field" do
|
||||
expect(clsid.pack).to eq(sample_clsid)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_s" do
|
||||
it "returns printable clsid" do
|
||||
Rex::OLE::Util.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
expect(clsid.to_s).to eq('33221100-5544-7766-8899-aabbccddeeff')
|
||||
end
|
||||
|
||||
context "when buf is nil" do
|
||||
it "raises NoMethodError" do
|
||||
clsid.instance_variable_set(:@buf, nil)
|
||||
expect { clsid.to_s }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf is shorter than 16 bytes" do
|
||||
it "raises TypeError" do
|
||||
clsid.instance_variable_set(:@buf, '')
|
||||
expect { clsid.to_s }.to raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,406 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/ole'
|
||||
|
||||
describe Rex::OLE::Util do
|
||||
|
||||
describe ".Hexify32array" do
|
||||
subject(:hex_array) { described_class.Hexify32array(arr) }
|
||||
|
||||
context "when arr is empty" do
|
||||
let(:arr) { [] }
|
||||
it "returns empty string" do
|
||||
is_expected.to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "when arr is filled" do
|
||||
let(:arr) { [0, 1, 0x20, 0x40, 0x100, 0x200, 0x12345678] }
|
||||
|
||||
it "returns an string with the hexify array" do
|
||||
is_expected.to eq('0x00000000 0x00000001 0x00000020 0x00000040 0x00000100 0x00000200 0x12345678')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".Printable" do
|
||||
subject(:printable_buf) { described_class.Printable(buf) }
|
||||
|
||||
context "when buf is empty" do
|
||||
let(:buf) { '' }
|
||||
it "returns empty string" do
|
||||
is_expected.to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf only contains printable chars" do
|
||||
let(:buf) { 'abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()' }
|
||||
|
||||
it "returns the same string" do
|
||||
is_expected.to eq(buf)
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf contains no printable chars" do
|
||||
let(:buf) { "abcde\x88" }
|
||||
|
||||
it "returns hex representation for non printable chars" do
|
||||
is_expected.to eq('abcde\\x88')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".set_endian" do
|
||||
subject(:set_endian) { described_class.set_endian(endian) }
|
||||
let(:endian) { Rex::OLE::LITTLE_ENDIAN }
|
||||
|
||||
it "sets the endian field" do
|
||||
set_endian
|
||||
expect(described_class.instance_variable_get(:@endian)).to eq(0xfffe)
|
||||
end
|
||||
|
||||
it "returns the set endianness" do
|
||||
is_expected.to eq(0xfffe)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get64" do
|
||||
subject(:quad_word) { described_class.get64(buf, offset) }
|
||||
|
||||
context "when buf is empty" do
|
||||
let(:buf) { '' }
|
||||
let(:offset) { 0 }
|
||||
|
||||
it "raises a null dereference exception" do
|
||||
expect { quad_word }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf is shorter than offset" do
|
||||
let(:buf) { "\x12\x34\x56\x78\x12\x34\x56\x78" }
|
||||
let(:offset) { 8 }
|
||||
|
||||
it "raises a null dereference exceptioon" do
|
||||
expect { quad_word }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is little endian" do
|
||||
let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the little endian quad word at offset" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq(0x8877665544332211)
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the big endian quad word at offset" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq(0x1122334455667788)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".pack64" do
|
||||
subject(:packed_quad_word) { described_class.pack64(value) }
|
||||
let(:value) { 0x1122334455667788 }
|
||||
|
||||
context "when @endian is little endian" do
|
||||
it "returns the packed little endian quad word" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq("\x88\x77\x66\x55\x44\x33\x22\x11")
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
it "returns the packed big endian quad word" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq("\x11\x22\x33\x44\x55\x66\x77\x88")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get32" do
|
||||
subject(:word) { described_class.get32(buf, offset) }
|
||||
|
||||
context "when buf is empty" do
|
||||
let(:buf) { '' }
|
||||
let(:offset) { 0 }
|
||||
|
||||
it "returns nil" do
|
||||
is_expected.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf is shorter than offset" do
|
||||
let(:buf) { "\x12\x34\x56" }
|
||||
let(:offset) { 4 }
|
||||
|
||||
it "raises a null dereference exceptioon" do
|
||||
expect { word }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is little endian" do
|
||||
let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the little endian word at offset" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq(0x44332211)
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the big endian word at offset" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq(0x11223344)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".pack32" do
|
||||
subject(:packed_word) { described_class.pack32(value) }
|
||||
let(:value) { 0x11223344 }
|
||||
|
||||
context "when @endian is little endian" do
|
||||
it "returns the packed little endian word" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq("\x44\x33\x22\x11")
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
it "returns the packed big endian word at offset" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq("\x11\x22\x33\x44")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get32array" do
|
||||
subject(:word_array) { described_class.get32array(buf) }
|
||||
|
||||
context "when buf is empty" do
|
||||
let(:buf) { '' }
|
||||
|
||||
it "returns an empty array" do
|
||||
is_expected.to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf isn't empty" do
|
||||
let(:buf) { "\x11\x22\x33\x44\x55\x66\x77\x88" }
|
||||
|
||||
context "when @endian is little endian" do
|
||||
it "unpacks an array of little endian words" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq([0x44332211, 0x88776655])
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
it "unpacks an array of big endian words" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq([0x11223344, 0x55667788])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".pack32array" do
|
||||
subject(:packed_word) { described_class.pack32array(arr) }
|
||||
|
||||
context "when arr is empty" do
|
||||
let(:arr) { [] }
|
||||
it "returns an empty string" do
|
||||
is_expected.to eq('')
|
||||
end
|
||||
end
|
||||
|
||||
context "when arr isn't empty" do
|
||||
let(:arr) { [0x11223344, 0x55667788] }
|
||||
|
||||
context "when @endian is little endian" do
|
||||
it "returns the little endian words array packed" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq("\x44\x33\x22\x11\x88\x77\x66\x55")
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
it "returns the big endian words array packed" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq("\x11\x22\x33\x44\x55\x66\x77\x88")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe ".get16" do
|
||||
subject(:half_word) { described_class.get16(buf, offset) }
|
||||
|
||||
context "when buf is empty" do
|
||||
let(:buf) { '' }
|
||||
let(:offset) { 0 }
|
||||
|
||||
it "returns nil" do
|
||||
is_expected.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf is shorter than offset" do
|
||||
let(:buf) { "\x12\x34" }
|
||||
let(:offset) { 4 }
|
||||
|
||||
it "raises a null dereference exceptioon" do
|
||||
expect { half_word }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is little endian" do
|
||||
let(:buf) { "\x00\x11\x22\x33\x44" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the little endian half word at offset" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq(0x2211)
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
let(:buf) { "\x00\x11\x22\x33\x44" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the big endian word at offset" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq(0x1122)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".pack16" do
|
||||
subject(:packed_word) { described_class.pack16(value) }
|
||||
let(:value) { 0x1122 }
|
||||
|
||||
context "when @endian is little endian" do
|
||||
it "returns the packed little endian word" do
|
||||
described_class.set_endian(Rex::OLE::LITTLE_ENDIAN)
|
||||
is_expected.to eq("\x22\x11")
|
||||
end
|
||||
end
|
||||
|
||||
context "when @endian is big endian" do
|
||||
it "returns the packed big endian word at offset" do
|
||||
described_class.set_endian(Rex::OLE::BIG_ENDIAN)
|
||||
is_expected.to eq("\x11\x22")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get8" do
|
||||
subject(:byte) { described_class.get8(buf, offset) }
|
||||
|
||||
context "when buf is empty" do
|
||||
let(:buf) { '' }
|
||||
let(:offset) { 0 }
|
||||
|
||||
it "returns nil" do
|
||||
is_expected.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when buf is shorter than offset" do
|
||||
let(:buf) { "\x12\x34" }
|
||||
let(:offset) { 4 }
|
||||
|
||||
it "raises a null dereference exceptioon" do
|
||||
expect { byte }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
let(:buf) { "\x00\x11\x22" }
|
||||
let(:offset) { 1 }
|
||||
|
||||
it "returns the byte at offset" do
|
||||
is_expected.to eq(0x11)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".pack8" do
|
||||
subject(:packed_byte) { described_class.pack8(value) }
|
||||
let(:value) { 0x11 }
|
||||
|
||||
it "returns the packed byte" do
|
||||
is_expected.to eq("\x11")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".getUnicodeString" do
|
||||
subject(:unicode_string) { described_class.getUnicodeString(buf) }
|
||||
let(:buf) { "T\x00h\x00i\x00s\x00 \x00i\x00s\x00 \x00a\x00n\x00 \x00u\x00n\x00i\x00c\x00o\x00d\x00e\x00 \x00s\x00t\x00r\x00i\x00n\x00g\x00" }
|
||||
|
||||
it "unpacks unicode string" do
|
||||
is_expected.to eq('This is an unicode string')
|
||||
end
|
||||
|
||||
context "when buf contains unicode nulls" do
|
||||
let(:buf) { "T\x00h\x00\x00i\x00s\x00" }
|
||||
|
||||
it "unpacks unicode string until null" do
|
||||
is_expected.to eq('Th')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".putUnicodeString" do
|
||||
subject(:packed_byte) { described_class.putUnicodeString(buf) }
|
||||
let(:buf) { 'A' * 32 }
|
||||
|
||||
it "returns the unicode version of the string" do
|
||||
is_expected.to eq("A\x00" * 32)
|
||||
end
|
||||
|
||||
context "when buf is shorter than 32" do
|
||||
let(:buf) { 'A' * 30 }
|
||||
it "adds null byte padding" do
|
||||
is_expected.to eq(("A\x00" * 30) + "\x00\x00\x00\x00")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".name_is_valid" do
|
||||
subject(:valid_name) { described_class.name_is_valid(name) }
|
||||
|
||||
context "when name length is greater than 31" do
|
||||
let(:name) { 'A' * 32 }
|
||||
it "returns nil" do
|
||||
is_expected.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when name contains [0x00..0x1f] chars" do
|
||||
let(:name) { "ABCDE\x1f" }
|
||||
it "returns nil" do
|
||||
is_expected.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when name doesn't contain [0x00..0x1f] chars" do
|
||||
let(:name) { "ABCDE\x88" }
|
||||
it "returns true" do
|
||||
is_expected.to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue