#!/bin/bash
# -*- coding: utf-8 -*-
# msidump - dump raw MSI tables and stream content
#
# Copyright (c) 2013 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
set -e
tables=
streams=
signature=
destdir=.
version()
{
cat <<EOF
@PACKAGE_VERSION@
EOF
}
help()
{
cat <<EOF
msidump dumps MSI tables as idt text and streams
EOF
usage
echo ""
echo "Report bugs to <@PACKAGE_BUGREPORT@>."
}
usage()
{
cat <<EOF
Usage: msidump [OPTION]... MSI-FILE
Options:
-t, --tables Dump tables. This is the default.
-s, --streams Dump streams
-S, --signature Dump asn1parse of digital signature.
-d, --directory DIR Dump to given directory DIR
-h, --help Print help message and exit.
-v, --version Print version information and exit.
More than one of -t, -s or -S may be specified.
EOF
}
while true ; do
case $1 in
-t|--tables)
tables=true
;;
-s|--streams)
streams=true
;;
-S|--signature)
signature=true
;;
-d|--directory)
destdir=$2
shift
;;
-h|--help)
help
exit 0
;;
-v|--version)
version
exit 0
;;
*)
break
;;
esac
shift
done
if [[ $# -lt 1 ]] ; then
usage
exit 1
fi
for file in "$1" ; do
if [[ ! -f $file ]] ; then
[[ -e $file ]] && \
echo "Error: not a regular file: '$file'" >&2 ||
echo "Error: file does not exist: '$file'" >&2
exit 1
fi
done
if [[ ! -d $destdir ]] ; then
echo "Error: directory does not exist: '$destdir'" >&2
exit 1
fi
# Tables mode is the default.
if [[ -z $tables$streams$signature ]] ; then
tables=true
else
tables=${tables:-false}
fi
streams=${streams:-false}
signature=${signature:-false}
# Here we go
if $tables ; then
TABLES=$(msiinfo tables "$1")
for i in $TABLES; do
echo "Exporting table $i..."
msiinfo export "$1" "$i" > "$destdir/$i.idt"
done
fi
if $streams ; then
mkdir -p "$destdir/_Streams"
STREAMS=$(msiinfo streams "$1")
for i in $STREAMS; do
echo "Exporting stream $i..."
msiinfo extract "$1" "$i" > "$destdir/_Streams/$i"
done
fi
if $signature ; then
signature="$destdir/signature"
echo "Exporting asn1parsed $signature ..."
rm -f "$signature"
(msiinfo extract "$1" $'\005DigitalSignature' 2>/dev/null | openssl asn1parse -i -inform de > "$signature") || true
fi