136 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/perl
 | |
| #
 | |
| # dmg2iso - dmg to iso convert tool
 | |
| # Copyright (C) 2004 vu1tur <to@vu1tur.eu.org>
 | |
| 
 | |
| # 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.
 | |
| 
 | |
| # 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | |
| #
 | |
| # Changes:
 | |
| #
 | |
| # Tue Apr 26 15:49:53 EDT 2005 Jeff Mahoney <jeff.mahoney@gmail.com>
 | |
| # * read/writes now do so in 4k blocks rather than allocate
 | |
| #   huge chunks of memory
 | |
| 
 | |
| use MIME::Base64;
 | |
| use strict ;
 | |
| local ($^W) = 1; #use warnings ;
 | |
| use Compress::Zlib ;
 | |
| my $x = inflateInit()
 | |
|    or die "ERROR: Cannot create inflation stream. Is Compress::zlib installed?\n" ;
 | |
| my $zfblock="\x00"; for (0..8) { $zfblock.=$zfblock; }
 | |
| my $indxbeg=0;
 | |
| my $indxend=0;
 | |
| my $blocksz = 4096;
 | |
| my @plist;
 | |
| print "dmg2iso v0.2a by vu1tur (vu1tur.eu.org)\n\n";
 | |
| if (@ARGV."" != 2) { die "Syntax: dmg2iso.pl filename.dmg filename.iso\n"; }
 | |
| my $zeroblock = "\x00";
 | |
| for (0..8) { $zeroblock.=$zeroblock; }
 | |
| my $tmp;
 | |
| my ($output,$status);
 | |
| my $buffer;
 | |
| open(FINPUT,$ARGV[0]) or die "ERROR: Can't open input file\n";
 | |
| 
 | |
| binmode FINPUT;
 | |
| sysseek(FINPUT,-0x200000,2);
 | |
| print "reading property list...";
 | |
| my $fpos = sysseek(FINPUT,0,1);
 | |
| while(my $ar = sysread(FINPUT,$buffer,0x10000))
 | |
| {
 | |
| 	my $fpos = sysseek(FINPUT,0,1)-$ar;
 | |
| 	if ($buffer =~ /(.*)<plist version=\"1.0\">/s)
 | |
| 	{
 | |
| 		$indxbeg = $fpos+length($1);
 | |
| 	}
 | |
| 	if ($buffer =~ /(.*)<\/plist>/s)
 | |
| 	{
 | |
| 		$indxend = $fpos+length($1)+8;
 | |
| 	}
 | |
| }
 | |
| open(FOUTPUT,">".$ARGV[1]) or die "ERROR: Can't open output file\n";
 | |
| binmode FOUTPUT;
 | |
| my $indxcur = $indxbeg + 0x28;
 | |
| sysseek(FINPUT,$indxbeg,0);
 | |
| sysread(FINPUT,$tmp,$indxend-$indxbeg);
 | |
| 
 | |
| if ($tmp =~ s/.*<key>blkx<\/key>.*?\s*<array>(.*?)<\/array>.*/$1/s)
 | |
| {
 | |
| 	while ($tmp =~ s/.*?<data>(.*?)<\/data>//s)
 | |
| 	{
 | |
| 		my $t = $1;
 | |
| 		$t =~ s/\t//g;
 | |
| 		$t =~ s/^\n//g;
 | |
| 		push @plist,decode_base64($t);
 | |
| 	}
 | |
| } else {
 | |
| die "PropertyList is corrupted\n";
 | |
| }
 | |
| print "found ".@plist." partitions\n";
 | |
| print "decompressing:\n";
 | |
| 
 | |
| my $t=0;
 | |
| my $zoffs = 0;
 | |
| my $tempzoffs = 0;
 | |
| foreach (@plist)
 | |
| {
 | |
| 	print "partition ".$t++."\n";
 | |
| 	s/^.{204}//s;
 | |
| 	while (s/^(.{8})(.{8})(.{8})(.{8})(.{8})//s)
 | |
| 	{
 | |
| 		$x = inflateInit();
 | |
| 		my $block_type = unpack("H*",$1);
 | |
| 		my $out_offs = 0x200*hex(unpack("H*",$2));
 | |
| 		my $out_size = 0x200*hex(unpack("H*",$3));
 | |
| 		my $in_offs = hex(unpack("H*",$4));
 | |
| 		my $in_size = hex(unpack("H*",$5));
 | |
| 		# $1 - block type, $2 - output offs $3 - output size $4 input offset $5 - input size
 | |
| 		sysseek(FINPUT,$in_offs+$zoffs,0);
 | |
| 		
 | |
| 		if ($block_type =~ /^80000005/ or $block_type =~ /^00000001/)
 | |
| 		{
 | |
| 			do {
 | |
| 				my ($toread, $res);
 | |
| 				$toread = $blocksz;
 | |
| 				$toread = $in_size if ($in_size < $blocksz);
 | |
| 
 | |
| 				$res = sysread (FINPUT, $tmp, $toread);
 | |
| 				die "read failure" if ($res != $toread);
 | |
| 				$output = $tmp;
 | |
| 
 | |
| 				# If compressed, inflate it
 | |
| 				if ($block_type =~ /^80000005/) {
 | |
| 					($output,$status) = $x->inflate($tmp);
 | |
| 					die "\nConversion failed.File may be corrupted.\n"
 | |
| 					    if (!($status == Z_OK or $status == Z_STREAM_END));
 | |
| 				}
 | |
| 				print FOUTPUT $output;
 | |
| 				$in_size -= $toread;
 | |
| 			} while ($in_size > 0);
 | |
| 		}
 | |
| 		if ($block_type =~ /^00000002/)
 | |
| 		{
 | |
| 			for(1..$out_size/0x200) 
 | |
| 			{
 | |
| 				syswrite(FOUTPUT,$zeroblock,0x200);
 | |
| 			}
 | |
| 		}
 | |
| 		if ($block_type =~ /^FFFFFFFF/i)
 | |
| 		{
 | |
| 			$zoffs += $tempzoffs;
 | |
| 		}
 | |
| 		$tempzoffs = $in_offs+$in_size;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| print "\nconversion successful\n"; |