gpl-compliance-tools/find-firmware.pl

357 lines
9.3 KiB
Perl
Raw Normal View History

#!/usr/bin/perl
#
# Copyright (C) 2003, Michael Holzt <michael@holzt.de> (as splitgzip.pl)
# DL3KJU, kju@fqdn.org, kju@debian.org, kju@IRCNet
#
# Copyright (C) 2003, 2004, David 'novalis' Turner <novalis@novalis.org>
# Copyright (C) 2005, 2006, 2007, Free Software Foundation, Inc. <licensing@fsf.org>
# Copyright (C) 2005, 2007, 2010 Bradley M. Kuhn <bkuhn@ebb.org>
# This software's license gives you freedom; you can copy, convey,
# propogate, redistribute and/or modify this program under the terms of
# the GNU General Public License (GPL) as published by the Free
# Software Foundation (FSF), either version 3 of the License, or (at your
# option) any later version of the GPL published by the FSF.
#
# 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 in a file in the toplevel directory called
# "GPLv3". If not, see <http://www.gnu.org/licenses/>.
use strict;
my ($fn, $onefile, $ofarg) = @ARGV;
if ($onefile ne '-o') {
$onefile = -1;
} elsif ($ofarg) {
$onefile = $ofarg;
}
die "Usage: splitgzip.pl <imagefile>\n" if ( $fn eq '' );
print "Reading $fn...\n";
open(IN,"<$fn") or die "Can't open: $fn\n";
my $image;
my $imglen = read(IN,$image, -s $fn);
die("did not get all the bytes, got $imglen expected " . -s $fn)
if $imglen != -s $fn;
close(IN);
print "Analysing $fn...\n";
my $offset = 0;
my $output = 0;
my $jffs = 0;
my $filenum = 0;
for ( $offset=0; $offset<$imglen; $offset++ )
{
if (ord(substr($image,$offset,1)) == 0x45 &&
ord(substr($image,$offset+1,1)) == 0x3d &&
ord(substr($image,$offset+2,1)) == 0xcd &&
ord(substr($image,$offset+3,1)) == 0x28 )
{
print "Found cramfs-Header at $offset... ";
close(OUT) if ( $output );
$fn = "morx$filenum"; #fixme, get name from file if possible
#hm, magic says this should work, but it didn't on the one i tried
#$fn = '';
#$i = 48;
#while (substr ($image, $offset+$i, 1) ne "\0") {
# $fn .= substr ($image, $offset+$i, 1);
# $i ++;
#}
$filenum++;
print "Filename $fn.cramfs... writing...\n";
$fn .= $filenum if -e "$fn.cramfs";
open(OUT,">$fn.cramfs") or die "Can't open: $fn\n";
$output = 1;
if ($onefile >= 0) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
}
if (substr($image,$offset,4) eq "ISc(") {
close(OUT) if ( $output );
$fn = "data$filenum";
$filenum++;
print "Filename $fn.cab... writing... (don't forget the data1.hdr thing)\n";
$fn .= $filenum if -e "$fn.cramfs";
open(OUT,">$fn.cab") or die "Can't open: $fn\n";
$output = 1;
if ($onefile >= 0) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
}
if (ord(substr($image,$offset,1)) == 0x5D &&
ord(substr($image,$offset+1,1)) == 0x00 &&
ord(substr($image,$offset+2,1)) == 0x00 &&
ord(substr($image,$offset+3,1)) == 0x80 &&
ord(substr($image,$offset+4,1)) == 0x00)
{
print "Found LZMA-Header at $offset\n";
close(OUT) if ( $output );
$fn = '';
my $x = 10;
while ( ord(substr($image,$offset+$x,1)) != 0 )
{
$fn .= substr($image,$offset+$x,1);
$x++;
}
$fn = substr ($fn, 0, 10);
if ($fn !~ /^[\w-.]+$/) {
$fn = "morx$filenum";
}
$filenum ++;
$fn .= $filenum if -e "$fn.lzma";
print "Filename $fn.lzma... writing...\n";
open(OUT,">$fn.lzma") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
if (ord(substr($image,$offset,1)) == 0x1F &&
ord(substr($image,$offset+1,1)) == 0x8B &&
ord(substr($image,$offset+2,1)) == 0x08 )
{
#fixme
#if ($onefile && $output) {
# next;
#}
print "Found GZIP-Header at $offset\n";
close(OUT) if ( $output );
$fn = '';
my $x = 10;
while ( ord(substr($image,$offset+$x,1)) != 0 )
{
$fn .= substr($image,$offset+$x,1);
$x++;
}
$fn = substr ($fn, 0, 10);
if ($fn !~ /^[\w-.]+$/) {
$fn = "morx$filenum";
}
$filenum ++;
$fn .= $filenum if -e "$fn.gz";
print "Filename $fn.gz... writing...\n";
open(OUT,">$fn.gz") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
if (substr($image,$offset,3) eq "BZh") {
#fixme
#if ($onefile && $output) {
# next;
#}
print "Found Bzip-Header at $offset\n";
close(OUT) if ( $output );
$fn = '';
my $x = 0;
while ( ord(substr($image,$offset+$x,1)) != 0 )
{
$fn .= substr($image,$offset+$x,1);
$x++;
}
$fn = substr ($fn, 0, 10);
if ($fn !~ /^[\w-.]+$/) {
$fn = "morx$filenum";
}
$filenum ++;
$fn .= $filenum if -e "$fn.bz2";
print "Filename $fn.bz2... writing...\n";
open(OUT,">$fn.bz2") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
if (substr($image,$offset,4) eq "sqsh" or
substr($image,$offset,4) eq "hsqs") {
#fixme
#if ($onefile && $output) {
# next;
#}
my $endianIs = (substr($image,$offset,4) eq "sqsh") ? "big" : "little";
print "Found squashfs filesystem, $endianIs endian at $offset\n";
close(OUT) if ( $output );
$fn = "morx$filenum";
$filenum ++;
$fn .= $filenum if -e "$fn.squash";
print "Filename $fn.squash... writing...\n";
open(OUT,">$fn.squash") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
if (substr($image,$offset,3) eq "Rar") {
#fixme
#if ($onefile && $output) {
# next;
#}
print "Found Rar at $offset (this hasn't been tested yet, might be saving wrong stuff)\n";
close(OUT) if ( $output );
$fn = '';
my $x = 0;
while ( ord(substr($image,$offset+$x,1)) != 0 )
{
$fn .= substr($image,$offset+$x,1);
$x++;
}
$fn = substr ($fn, 0, 10);
if ($fn !~ /^[\w-.]+$/) {
$fn = "morx$filenum";
}
$filenum ++;
$fn .= $filenum if -e "$fn.rar";
print "Filename $fn.rar... writing...\n";
open(OUT,">$fn.rar") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
if (ord(substr($image,$offset+1,1)) == 0x39 &&
ord(substr($image,$offset,1)) == 0x31 &&
ord(substr($image,$offset+3,1)) == 0x34 &&
ord(substr($image,$offset+2,1)) == 0x38)
{
$jffs = 1;
print "Found JFFS Magic Bitmask at $offset\n";
close(OUT) if ( $output );
$fn = "morx$filenum";
$filenum ++;
$fn .= $filenum if -e "$fn.jffs";
print "Filename $fn.jffs... writing...\n";
open(OUT,">$fn.jffs") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
# This Ext2 code doesn't work. I googled around looking or a way to read it
# but could not find one.
# if (ord(substr($image,$offset,1)) == 0x53 &&
# ord(substr($image,$offset+1,1)) == 0xef &&
# ord(substr($image,$offset+2,1)) == 0x01 &&
# ord(substr($image,$offset+3,1)) == 0x00)
# {
# print "Found EXT2/3 Magic Bitmask at $offset\n";
# close(OUT) if ( $output );
# $fn = "morx$filenum";
# $filenum ++;
# $fn .= $filenum if -e "$fn.ext";
# print "Filename $fn.ext... writing...\n";
# open(OUT,">$fn.ext") or die "Can't open: $fn\n";
# if ($onefile) {
# print OUT substr($image, $offset, 1+$imglen - $offset);
# close(OUT);
# $onefile --;
# }
# if (!$onefile) {
# exit (0);
# }
# $output = 1;
# }
if (ord(substr($image,$offset,1)) == 0x85 &&
ord(substr($image,$offset+1,1)) == 0x19 &&
ord(substr($image,$offset+2,1)) == 0x03 &&
ord(substr($image,$offset+3,1)) == 0x20)
{
$jffs = 1;
print "Found JFFS2 Magic Bitmask at $offset\n";
close(OUT) if ( $output );
$fn = "morx$filenum";
$filenum ++;
$fn .= $filenum if -e "$fn.jffs2";
print "Filename $fn.jffs2... writing...\n";
open(OUT,">$fn.jffs2") or die "Can't open: $fn\n";
if ($onefile) {
print OUT substr($image, $offset, 1+$imglen - $offset);
close(OUT);
$onefile --;
}
if (!$onefile) {
exit (0);
}
$output = 1;
}
print OUT substr($image,$offset,1) if ( $output );
}
close(OUT) if ( $output );