/usr/lib/magicrescue/tools/oleextract.pl is in magicrescue 1.1.8-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #!/usr/bin/env perl
use strict;
#
# This script loosely follows the LAOLA file system described at
# http://user.cs.tu-berlin.de/~schwartz/pmh/guide.html. It only looks at the
# "big block depots", as they seem to be sufficient for finding the length of
# the file.
use Fcntl qw(:seek);
my $buf;
# We use sysread/sysseek here to work around problems on cygwin
sysread STDIN, $buf, 512;
if (substr($buf, 0, 8) ne "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1") {
die "Not an MS OLE file\n";
}
my $num_of_bbd_blocks = unpack("V", substr($buf, 0x2c));
if ($num_of_bbd_blocks == 0 or $num_of_bbd_blocks > 320) {
# Max 320 bbd means the file can only be 128*512*320 = 20MB
die "Corrupted file, too many big block depots\n";
}
my $max_block = 128*$num_of_bbd_blocks;
my @bbds = unpack("V$num_of_bbd_blocks", substr($buf, 0x4c));
my $block_count = 0;
my $prevblock = -1;
my $block_index = 0;
foreach my $block (@bbds) {
if ($block > $max_block or $block == $prevblock) {
die "Corrupted file, bbd block number out of bounds\n";
}
sysseek STDIN, 512*($block - $prevblock - 1), SEEK_CUR
or die "sysseek failed: $!\n";
512 == sysread STDIN, $buf, 512
or die "read failed: $!\n";
my @blockmap = unpack("V128", $buf);
for (my $i = 0; $i < 128; $i++) {
if ($blockmap[$i] != 0xFFffFFff) {
$block_count = $block_index * 128 + $i + 2;
}
if ($blockmap[$i] < 0xFFffFFfd and $blockmap[$i] > $max_block) {
die "Corrupted file, block number too high\n";
}
}
$prevblock = $block;
$block_index++;
}
if ($block_count > 0) {
sysseek STDIN, -512*($bbds[@bbds - 1] + 2), SEEK_CUR # seek to first block
or die "seek failed: $!\n";
for (1 .. $block_count) {
512 == sysread STDIN, $buf, 512
or die "read failed: $!\n";
print $buf
or die "write failed: $!\n";
}
}
|