summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2018-11-21 11:15:00 +0100
committerMiklos Vajna <vmiklos@collabora.com>2018-11-21 11:15:00 +0100
commite73d6479e0431539cd5722d85bab457f2e684907 (patch)
tree52f00c07aca45a45f57ded9592db17635915b813
parent0c1a03000e29219ce754df8bb99781d1564bf41a (diff)
Add OLE1 and OLE2 preview dumper
All this is documented in [MS-OLEDS].
-rw-r--r--Makefile10
-rw-r--r--msodumper/ole1previewrecord.py89
-rw-r--r--msodumper/ole2previewrecord.py73
-rwxr-xr-xole1preview-dump.py33
-rwxr-xr-xole2preview-dump.py33
5 files changed, 234 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index badc2f5..fb90903 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,10 @@
check:
cd test/doc && ./test.py
cd test/emf && ./test.py
- pep8 --ignore=E501 msodumper/{binarystream,msometa}.py
- pep8 --ignore=E501 doc-dump.py msodumper/doc{record,sprm,stream}.py test/doc/test.py
- pep8 --ignore=E501 emf-dump.py msodumper/{emf,wmf}record.py
- pep8 --ignore=E501 vsd-dump.py msodumper/vsdstream.py test/vsd-test.py
+ pycodestyle --ignore=E501 msodumper/{binarystream,msometa}.py
+ pycodestyle --ignore=E501 doc-dump.py msodumper/doc{record,sprm,stream}.py test/doc/test.py
+ pycodestyle --ignore=E501 emf-dump.py msodumper/{emf,wmf}record.py
+ pycodestyle --ignore=E501 vsd-dump.py msodumper/vsdstream.py test/vsd-test.py
pycodestyle --ignore=E501 swlaycache-dump.py msodumper/swlaycacherecord.py
+ pycodestyle --ignore=E501 ole1preview-dump.py msodumper/ole1previewrecord.py
+ pycodestyle --ignore=E501 ole2preview-dump.py msodumper/ole2previewrecord.py
diff --git a/msodumper/ole1previewrecord.py b/msodumper/ole1previewrecord.py
new file mode 100644
index 0000000..115ec69
--- /dev/null
+++ b/msodumper/ole1previewrecord.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from . import globals
+from .binarystream import BinaryStream
+
+
+class Ole1PreviewStream(BinaryStream):
+ def __init__(self, bytes):
+ BinaryStream.__init__(self, bytes)
+
+ def dump(self):
+ print('<stream type="Ole1Preview" size="%d">' % self.size)
+ header = StandardPresentationObject(self, "Header")
+ header.dump()
+ self.printAndSet("PresentationDataSize", self.readuInt32(), hexdump=False, offset=True)
+ self.printAndSet("Reserved1", self.readuInt16())
+ self.printAndSet("Reserved2", self.readuInt16())
+ self.printAndSet("Reserved3", self.readuInt16())
+ self.printAndSet("Reserved4", self.readuInt16())
+ print('<PresentationData offset="%s" size="%s"/>' % (self.pos, int(self.PresentationDataSize) - 8))
+ print('</stream>')
+
+
+class Record(BinaryStream):
+ def __init__(self, parent):
+ BinaryStream.__init__(self, parent.bytes)
+ self.parent = parent
+ self.pos = parent.pos
+
+
+class LengthPrefixedAnsiString(Record):
+ """Specified by [MS-OLEDS] 2.1.4, specifies a length-prefixed and
+ null-terminated ANSI string."""
+ def __init__(self, parent, name):
+ Record.__init__(self, parent)
+ self.parent = parent
+ self.pos = parent.pos
+ self.name = name
+
+ def dump(self):
+ print('<%s type="LengthPrefixedAnsiString">' % self.name)
+ self.printAndSet("Length", self.readuInt32(), offset=True)
+ bytes = []
+ for dummy in range(self.Length):
+ c = self.readuInt8()
+ bytes.append(c)
+
+ self.printAndSet("String", globals.encodeName("".join(map(lambda c: chr(c), bytes[:-1])), lowOnly=True).encode('utf-8'), hexdump=False, offset=True)
+
+ print('</%s>' % self.name)
+ self.parent.pos = self.pos
+
+
+class StandardPresentationObject(Record):
+ def __init__(self, parent, name):
+ Record.__init__(self, parent)
+ self.name = name
+
+ def dump(self):
+ print('<%s type="StandardPresentationObject">' % self.name)
+ header = PresentationObjectHeader(self, "Header")
+ header.dump()
+ self.printAndSet("Width", self.readuInt32())
+ self.printAndSet("Height", self.readInt32() * -1)
+
+ print('</%s>' % self.name)
+ self.parent.pos = self.pos
+
+
+class PresentationObjectHeader(Record):
+ def __init__(self, parent, name):
+ Record.__init__(self, parent)
+ self.name = name
+
+ def dump(self):
+ print('<%s type="PresentationObjectHeader">' % self.name)
+ self.printAndSet("OLEVersion", self.readuInt32())
+ self.printAndSet("FormatID", self.readuInt32())
+ LengthPrefixedAnsiString(self, "ClassName").dump()
+
+ print('</%s>' % self.name)
+ self.parent.pos = self.pos
+
+# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
diff --git a/msodumper/ole2previewrecord.py b/msodumper/ole2previewrecord.py
new file mode 100644
index 0000000..39016d9
--- /dev/null
+++ b/msodumper/ole2previewrecord.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from . import globals
+from .binarystream import BinaryStream
+
+
+class Ole2PreviewStream(BinaryStream):
+ def __init__(self, bytes):
+ BinaryStream.__init__(self, bytes)
+
+ def dump(self):
+ print('<stream type="Ole2Preview" size="%d">' % self.size)
+
+ ansiClipboardFormat = ClipboardFormatOrAnsiString(self, "AnsiClipboardFormat")
+ ansiClipboardFormat.dump()
+ self.printAndSet("TargetDeviceSize", self.readuInt32())
+ if self.TargetDeviceSize == 0x00000004:
+ # TargetDevice is not present
+ pass
+ else:
+ print('<todo what="TargetDeviceSize != 0x00000004"/>')
+ self.printAndSet("Aspect", self.readuInt32())
+ self.printAndSet("Lindex", self.readuInt32())
+ self.printAndSet("Advf", self.readuInt32())
+ self.printAndSet("Reserved1", self.readuInt32())
+ self.printAndSet("Width", self.readuInt32(), hexdump=False)
+ self.printAndSet("Height", self.readuInt32(), hexdump=False)
+ self.printAndSet("Size", self.readuInt32(), hexdump=False)
+ print('<Data offset="%s" size="%s"/>' % (self.pos, self.Size))
+
+ print('</stream>')
+
+
+class Record(BinaryStream):
+ def __init__(self, parent):
+ BinaryStream.__init__(self, parent.bytes)
+ self.parent = parent
+ self.pos = parent.pos
+
+
+class ClipboardFormatOrAnsiString(Record):
+ def __init__(self, parent, name):
+ Record.__init__(self, parent)
+ self.parent = parent
+ self.pos = parent.pos
+ self.name = name
+
+ def dump(self):
+ print('<%s type="ClipboardFormatOrAnsiString">' % self.name)
+
+ self.printAndSet("MarkerOrLength", self.readuInt32())
+ if self.MarkerOrLength == 0xffffffff:
+ self.printAndSet("FormatOrAnsiLength", self.readuInt32(), dict=ClipboardFormats)
+ else:
+ print('<todo what="MarkerOrLength != 0xffffffff"/>')
+
+ print('</%s>' % self.name)
+ self.parent.pos = self.pos
+
+
+ClipboardFormats = {
+ 0x00000002: "CF_BITMAP",
+ 0x00000003: "CF_METAFILEPICT",
+ 0x00000008: "CF_DIB",
+ 0x0000000E: "CF_ENHMETAFILE",
+}
+
+# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
diff --git a/ole1preview-dump.py b/ole1preview-dump.py
new file mode 100755
index 0000000..045c1d0
--- /dev/null
+++ b/ole1preview-dump.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from msodumper import ole1previewrecord
+import sys
+
+
+# Dumps the OLE1 preview: see [MS-OLEDS] 2.2.5.
+class Ole1PreviewDumper:
+ def __init__(self, filepath):
+ self.filepath = filepath
+
+ def dump(self):
+ file = open(self.filepath, 'rb')
+ strm = ole1previewrecord.Ole1PreviewStream(file.read())
+ file.close()
+ print('<?xml version="1.0"?>')
+ strm.dump()
+
+
+def main(args):
+ dumper = Ole1PreviewDumper(args[1])
+ dumper.dump()
+
+
+if __name__ == '__main__':
+ main(sys.argv)
+
+# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
diff --git a/ole2preview-dump.py b/ole2preview-dump.py
new file mode 100755
index 0000000..729fd1d
--- /dev/null
+++ b/ole2preview-dump.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from msodumper import ole2previewrecord
+import sys
+
+
+# Dumps the OLE2 preview stream: see [MS-OLEDS] 2.3.4.
+class Ole2PreviewDumper:
+ def __init__(self, filepath):
+ self.filepath = filepath
+
+ def dump(self):
+ file = open(self.filepath, 'rb')
+ strm = ole2previewrecord.Ole2PreviewStream(file.read())
+ file.close()
+ print('<?xml version="1.0"?>')
+ strm.dump()
+
+
+def main(args):
+ dumper = Ole2PreviewDumper(args[1])
+ dumper.dump()
+
+
+if __name__ == '__main__':
+ main(sys.argv)
+
+# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab: